Compare commits

..

142 Commits

Author SHA1 Message Date
78ba39bfe2 docs: add changelog for 5.1.0-beta.0 2017-11-08 11:32:48 -08:00
119034c642 docs: add changelog for 5.0.1 2017-11-08 10:30:17 -08:00
6e8e3bd248 refactor(core): misc changes and integrate review feedback on #19996
closes #20224
2017-11-06 14:13:02 -08:00
a460066972 feat(compiler): introduce TestBed.overrideTemplateUsingTestingModule
This allows to overwrite templates for JIT and AOT components alike.

In contrast to `TestBed.overrideTemplate`, the template is compiled
in the context of the testing module, allowing to use other testing
directives.

Closes #19815
2017-11-06 14:12:30 -08:00
05d96dc507 feat(core): allow to pass in aot summaries also to TestBed.configureTestingModule
Also adds caching for summaries.

Closes #19817.
2017-11-06 14:12:30 -08:00
b489259a34 docs(common): fix mis-ordered lines (#20221) 2017-11-06 11:28:39 -08:00
6b748835be build(aio): upgrade to @anglar/core@5.0.0 and cli@1.5.0
-rw-r--r--  1 iminar  eng   14880 Nov  4 11:54
dist/0.b19e913fbdd6507d346b.chunk.js
-rw-r--r--  1 iminar  eng    1533 Nov  4 11:54
dist/inline.9183bfe0d60f43b6a772.bundle.js
-rw-r--r--  1 iminar  eng  486476 Nov  4 11:54
dist/main.f5445f99490330207c9c.bundle.js
-rw-r--r--  1 iminar  eng   37070 Nov  4 11:54
dist/polyfills.0dfca732c5a075c110d0.bundle.js

Closes #20184
2017-11-06 10:04:43 -08:00
d30ea61f0d build(aio): remove the build-optimizer flag
it's on by default now.
2017-11-06 10:04:02 -08:00
0c47ea704e build(aio): use aot compiler for development
since it was not turned on by default in the cli we
have to opt in.
2017-11-06 10:04:02 -08:00
049c89645b docs(aio): update ToH for CLI (#19811) 2017-11-06 10:02:17 -08:00
bf22f2df88 fix(compiler): report a reasonable error with invalid metadata (#20062)
The compiler would throw an internal exception if an import using
the `ngModule` syntax and the module as not a resolvable symbol.

Fixes: #20049
2017-11-06 10:01:27 -08:00
880201681f fix(aio): style correctly on Safari (#20157) 2017-11-06 10:00:37 -08:00
63d26a1777 ci(aio): move e2e tests to optional job (#20178) 2017-11-06 09:59:59 -08:00
8b50ed083c docs(aio): fixed case-typo for code (#20196) 2017-11-06 09:59:17 -08:00
3997d97806 revert: feat(elements): implement @angular/elements #19469 (#20152)
This PR was merged without API docs and general rollout plan.

We can't release this as is in 5.1 without a plan for documentation, cli integration, etc.
2017-11-03 15:54:54 -07:00
200d92d030 fix(core): should support event.stopImmediatePropagation (#19222) 2017-11-03 15:22:05 -07:00
dbec3ca716 docs(aio): update pipes for CLI (#19553) 2017-11-03 15:21:14 -07:00
f7c9b941cb ci(aio): Add payload size percentage changes check to payload size task (#19908) 2017-11-03 15:20:09 -07:00
f0764016f9 revert: feat(core): add source to StaticInjectorError message (#19482) (#20171)
This reverts commit faa621218e.
2017-11-03 14:51:06 -07:00
a99eb16320 test(aio): make e2e tests less flakey
closes #20117
2017-11-03 11:22:57 -07:00
e36bac9e90 build(aio): upgrade protractor to v5.2.0 2017-11-03 11:22:41 -07:00
196ce6d475 build(aio): use correct types for e2e tests 2017-11-03 11:22:41 -07:00
faa621218e feat(core): add source to StaticInjectorError message (#19482) 2017-11-03 11:14:05 -07:00
169cedd43b docs: Bootstrapping guide prose for CLI (#19777) 2017-11-03 11:13:24 -07:00
567cc26b8e docs: Component Styles guide for CLI (#19791) 2017-11-03 11:12:34 -07:00
1d19d61970 fix(platform-browser): support Symbols in custom jasmineToString() method (#19794)
It's illegal to coerce a Symbol to a string, and results in a TypeError:

TypeError: Cannot convert a Symbol value to a string

Previously, the custom jasmineToString() method monkey-patched onto Maps
in platform-browser/testing/src/matchers.ts would coerce keys and values
to strings. A change in a newer version of Jasmine calls this method more
often, resulting in calls against Maps which contain Symbols in some
applications, which causes crashes.

The fix is to explicitly convert keys and values to strings, which does
work on Symbols.
2017-11-03 11:11:47 -07:00
03f080b7da docs: Deployment guide for CLI (#19839) 2017-11-03 11:10:53 -07:00
26f82995f6 fix(compiler): don't overwrite missingTranslation's value in JIT (#19952) 2017-11-03 11:08:39 -07:00
f1da1419fa docs(aio): Fix typo in Architecture Overview. (#20073) 2017-11-03 11:00:22 -07:00
5079d2d37c docs(aio): Add v4 doc link to navigation (#20089)
Fixes #20090
2017-11-03 10:59:27 -07:00
c7fd172ba7 build(aio): make plunker works with rxjs operators (#20124) 2017-11-03 10:47:23 -07:00
dcf8840831 feat(elements): implement registerAsCustomElements()
closes #19469
2017-11-02 16:09:30 -07:00
60c0b178af feat(elements): implement NgElements 2017-11-02 16:09:09 -07:00
0899f4f8fc feat(elements): implement NgElementConstructor 2017-11-02 16:09:09 -07:00
aed4a11d01 feat(elements): implement NgElement 2017-11-02 16:09:09 -07:00
75cf70ae04 feat(elements): implement NgElementApplicationContext 2017-11-02 16:09:09 -07:00
6b30fbf94e feat(elements): implement extractProjectableNodes() 2017-11-02 16:09:09 -07:00
24f17f913a feat(elements): implement utils 2017-11-02 16:09:09 -07:00
ebfa204af0 feat(elements): set up the elements package 2017-11-02 16:09:09 -07:00
a28d616e10 fix(core): __symbol__ should return __zone_symbol__ without zone.js loaded (#19541) 2017-11-02 16:06:06 -07:00
613a9e3672 build: update Windows symlink scripts (#16761)
Fixes packages\upgrade\static\src symlink.

Closes #16760
2017-11-02 16:05:13 -07:00
65d57a07e0 build(aio): avoid building before running the local PWA tests
When this command is run on CI, `yarn build` has already been run, so
this was unnecessarily building angular.io again (adding ~4mins to the
`aio` job).
When this command is run locally, it is most often about testing a new
`lighthouse` version/config, so you don't need to build angular.io over
and over (and if necessary, one can always run `yarn build` manually).

Closes #19633
2017-11-02 16:02:52 -07:00
22946cfd40 build(aio): upgrade lighthouse to v2.5.0 2017-11-02 16:02:25 -07:00
9975486954 build: remove local yarn (#19981)
We use the globally installed yarn now. The local yarn was used in
`check-environment.js` only, which results in the `--integrity` check
always failing (if dependencies were installed with the global yarn).
2017-11-02 15:11:34 -07:00
068348e9b1 build(aio): do not fail the initial doc-gen when running docs-watch
Checks that cause the doc-gen to fail were already disabled in `docs-watch`
for the doc-gen that runs when a file is changed.
Now these checks are also disabled for the initial doc-gen run.
closes #20038
2017-11-02 15:03:59 -07:00
1beab0da6a build(aio): do not fail on bad examples when running docs-watch 2017-11-02 15:00:22 -07:00
3a03ff6b2d build(aio): allow render-examples to complete even if examples are broken
By setting `renderExamples.ignoreBrokenExamples = true` the doc-gen will
not fail if there is something wrong with an example. Instead it will
just log a warning.
2017-11-02 15:00:22 -07:00
feae55b264 docs(aio): fix badly formatted code-examples
closes #19970
2017-11-02 14:59:05 -07:00
0355142737 build(aio): fail doc-gen if a code-example is badly formatted.
This will catch the problem that was missed in
https://github.com/angular/angular/pull/19845#issuecomment-338626662
2017-11-02 14:58:38 -07:00
5b16ce9302 fix(compiler-cli): don't report emit diagnostics when --noEmitOnError is off (#20063) 2017-11-02 14:49:38 -07:00
17ed14faea docs: fix changelog for v5 (#20097) 2017-11-02 14:37:39 -07:00
d156e72ad7 docs: Add 0 in padding of 'dd' (#20107) 2017-11-02 14:36:22 -07:00
7186c9c839 docs: AOT guide for CLI #19510 (#19818) 2017-11-02 14:34:21 -07:00
a41558eb30 docs: BrowserSupport guide for CLI (#19843) 2017-11-02 14:29:59 -07:00
a91252a90c docs: Npm Packages guide for CLI (#19850) 2017-11-02 14:27:53 -07:00
132c0719dc docs(aio): updated i18n guide and example (#19975) 2017-11-02 14:22:09 -07:00
3db7112b89 docs(aio): fix linting for universal (#20086)
PR Close #20086
2017-11-02 00:51:29 +01:00
2ea76cce31 build: change the version in package.json to 5.1.0-beta
this is needed to reflect that the current branch will be yielding 5.1.0 releases

some of our scripts (e.g. aio deployment) relies on this identifier.
2017-11-02 00:17:55 +01:00
b8bb2dd0f5 build(aio): update lockfile for examples
Installing dependencies for the docs examples fails, because the
lockfile is out-of-sync with the corresponding `package.json`.
This commit brings the lockfile in sync with `package.json`.

(For reference, this was accidentally broken in #20039.)
2017-11-02 00:15:59 +01:00
27ae0f9475 build(aio): upgrade to @angular/material@2.0.0-beta.12 (#19702)
-rw-r--r--  1 iminar  eng   14880 Nov  1 12:25 dist/0.b19e913fbdd6507d346b.chunk.js
-rw-r--r--  1 iminar  eng    1533 Nov  1 12:25 dist/inline.2826385ad3e299c6d1c1.bundle.js
-rw-r--r--  1 iminar  eng  486476 Nov  1 12:25 dist/main.f0610805f4aad19da4be.bundle.js
-rw-r--r--  1 iminar  eng   37070 Nov  1 12:25 dist/polyfills.0dfca732c5a075c110d0.bundle.js

PR Close #19702
2017-11-01 15:24:48 -07:00
171dceb010 build(aio): upgrade to @angular/core@5.0.0-rc.9 (#19702)
build fails - material upgrade required

PR Close #19702
2017-11-01 15:24:48 -07:00
1ebc0d1e33 revert: build(aio): remove cli patches (#19702)
This reverts commit f0d530b4de38f71c759e42afc8f3d7531eb1b1fb.

cli rc.8 reintroduces the node polyfill which causes size regression,
so I'm putting the patch back in.

-rw-r--r--  1 iminar  eng   14880 Nov  1 12:11 dist/0.b19e913fbdd6507d346b.chunk.js
-rw-r--r--  1 iminar  eng    1533 Nov  1 12:11 dist/inline.25600c3b48de18b97581.bundle.js
-rw-r--r--  1 iminar  eng  486476 Nov  1 12:11 dist/main.d1292a34401056535884.bundle.js
-rw-r--r--  1 iminar  eng   37070 Nov  1 12:11 dist/polyfills.0dfca732c5a075c110d0.bundle.js

PR Close #19702
2017-11-01 15:24:47 -07:00
1d8e0758fa build(aio): upgrade to @angular/cli@1.5.0-rc.8 (#19702)
-rw-r--r--  1 iminar  eng   14880 Nov  1 11:57 dist/0.b19e913fbdd6507d346b.chunk.js
-rw-r--r--  1 iminar  eng    1533 Nov  1 11:57 dist/inline.3574d1d784c09c507dbd.bundle.js
-rw-r--r--  1 iminar  eng  497812 Nov  1 11:57 dist/main.76bbb69df79eaefef54c.bundle.js
-rw-r--r--  1 iminar  eng   37259 Nov  1 11:57 dist/polyfills.fdb71956ccd13330fb47.bundle.js

PR Close #19702
2017-11-01 15:24:47 -07:00
cd55643f85 build(aio): upgrade to @angular/cli@1.5.0-rc.6 (#19702)
-rw-r--r--  1 iminar  eng   14880 Oct 30 11:29 dist/0.b19e913fbdd6507d346b.chunk.js
-rw-r--r--  1 iminar  eng    1533 Oct 30 11:29 dist/inline.25600c3b48de18b97581.bundle.js
-rw-r--r--  1 iminar  eng  486476 Oct 30 11:29 dist/main.d1292a34401056535884.bundle.js
-rw-r--r--  1 iminar  eng   37070 Oct 30 11:29 dist/polyfills.0dfca732c5a075c110d0.bundle.js

PR Close #19702
2017-11-01 15:24:47 -07:00
486b8e6f69 ci(aio): decrease payload size limit for main file (#19702)
PR Close #19702
2017-11-01 15:24:47 -07:00
215d373ebd refactor(aio): rename CustomMdIconRegistry to CustomIconRegistry (#19702)
The change of Angular Material version means that the `md` prefix is
no longer appropriate.

PR Close #19702
2017-11-01 15:24:47 -07:00
4038b42396 build(aio): lock zone.js to 0.8.16 (#19702)
Later versions (before 0.8.19) had a size increase.

PR Close #19702
2017-11-01 15:24:46 -07:00
9ab1f4a9c9 style(aio): fix docs linting issues (#19702)
These issues appeared after upgrade of eslint jasmine plugin

PR Close #19702
2017-11-01 15:24:46 -07:00
e9afc59a81 ci(aio): increase payload size limit for polyfills.ts (#19702)
The latest builds have added ~2kB to the size of this file (500 bytes zipped).

PR Close #19702
2017-11-01 15:24:46 -07:00
83c826c3f9 build(aio): remove hack to modify CLI version (#19702)
PR Close #19702
2017-11-01 15:24:46 -07:00
abfc41d661 build(aio): upgrade to Angular@rc.5 and CLI@rc.3 (#19702)
PR Close #19702
2017-11-01 15:24:45 -07:00
11fd7eaf63 build(aio): revert temporary increase in size limit (#19702)
PR Close #19702
2017-11-01 15:24:45 -07:00
54eba606cb build(aio): fix tests to work with @angular/{material,cdk}@2.0.0-beta.12 (#19702)
PR Close #19702
2017-11-01 15:24:45 -07:00
3337865913 build(aio): remove cli patches (#19702)
PR Close #19702
2017-11-01 15:24:45 -07:00
f24397c5d0 build(aio): revert to clean CLI test.ts file (#19702)
The use of `System.import()` in test.ts was causing the webpack build to fail
with a mysterious "Module build failed: Error: TypeScript compilation failed" error,
when running `yarn test`.

PR Close #19702
2017-11-01 15:24:44 -07:00
9d52bf27de build(aio): temporarily increaze the size limit until the regressions are fixed (#19702)
related issues:
https://github.com/angular/angular/issues/19857
https://github.com/angular/devkit/pull/231

PR Close #19702
2017-11-01 15:24:44 -07:00
19fbfbc371 build(aio): disable 'global' support in webpack (#19702)
This will be fixed in CLI once https://github.com/angular/angular-cli/pull/8130 lands.

-rw-r--r--  1 iminar  eng   14942 Oct 20 22:23 dist/0.b19e913fbdd6507d346b.chunk.js
-rw-r--r--  1 iminar  eng    1535 Oct 20 22:23 dist/inline.5d66b81ec9e01af9d28d.bundle.js
-rw-r--r--  1 iminar  eng  528395 Oct 20 22:23 dist/main.e36bb99245ca52ae546f.bundle.js
-rw-r--r--  1 iminar  eng   37205 Oct 20 22:23 dist/polyfills.0dfca732c5a075c110d0.bundle.js

PR Close #19702
2017-11-01 15:24:44 -07:00
6578b30b77 build(aio): upgrade to build-optimizer@0.0.29 (#19702)
-rw-r--r--  1 iminar  eng   14942 Oct 20 22:16 dist/0.b19e913fbdd6507d346b.chunk.js
-rw-r--r--  1 iminar  eng    1535 Oct 20 22:16 dist/inline.68ebcf831dc9c905804f.bundle.js
-rw-r--r--  1 iminar  eng  541291 Oct 20 22:16 dist/main.5ec6fb5f95fc0433d822.bundle.js
-rw-r--r--  1 iminar  eng   37402 Oct 20 22:16 dist/polyfills.f8409a9eb69060ac1aa6.bundle.js

PR Close #19702
2017-11-01 15:24:44 -07:00
10c1c2ba5a build(aio): upgrade to @angular/cli@1.5.0-rc.2 (#19702)
-rw-r--r--  1 iminar  eng   84219 Oct 19 21:37 dist/0.0f327734d18211139822.chunk.js
-rw-r--r--  1 iminar  eng   14942 Oct 19 21:37 dist/4.c719ac5645940382cdce.chunk.js
-rw-r--r--  1 iminar  eng    1560 Oct 19 21:37 dist/inline.887757679ff553e20b54.bundle.js
-rw-r--r--  1 iminar  eng  492354 Oct 19 21:37 dist/main.5e5dc9ed980c9f5dc2bd.bundle.js
-rw-r--r--  1 iminar  eng   37402 Oct 19 21:37 dist/polyfills.f8409a9eb69060ac1aa6.bundle.js

PR Close #19702
2017-11-01 15:24:44 -07:00
e18bfd1f3d build(aio): upgrade to @angular/cli@1.5.0-rc.1 (#19702)
-rw-r--r--  1 iminar  eng   84219 Oct 18 21:05 dist/0.0f327734d18211139822.chunk.js
-rw-r--r--  1 iminar  eng   14942 Oct 18 21:05 dist/4.c719ac5645940382cdce.chunk.js
-rw-r--r--  1 iminar  eng    1560 Oct 18 21:05 dist/inline.887757679ff553e20b54.bundle.js
-rw-r--r--  1 iminar  eng  492354 Oct 18 21:05 dist/main.5e5dc9ed980c9f5dc2bd.bundle.js
-rw-r--r--  1 iminar  eng   37402 Oct 18 21:05 dist/polyfills.f8409a9eb69060ac1aa6.bundle.js

PR Close #19702
2017-11-01 15:24:43 -07:00
3c2ddbe9ab build(aio): upgrade to rxjs@5.5.0 (#19702)
-rw-r--r--  1 iminar  eng   84219 Oct 18 09:13 dist/0.8ef208c27531d5c6af63.chunk.js
-rw-r--r--  1 iminar  eng   14942 Oct 18 09:13 dist/4.c719ac5645940382cdce.chunk.js
-rw-r--r--  1 iminar  eng    1560 Oct 18 09:13 dist/inline.adc367eb50c706f3fd04.bundle.js
-rw-r--r--  1 iminar  eng  492354 Oct 18 09:13 dist/main.b9d9549455c74aff1480.bundle.js
-rw-r--r--  1 iminar  eng   37402 Oct 18 09:13 dist/polyfills.f8409a9eb69060ac1aa6.bundle.js

PR Close #19702
2017-11-01 15:24:43 -07:00
a149605c9f build(aio): turn off preserveWhitespaces in compiler options (#19702)
-rw-r--r--  1 iminar  eng   14942 Oct 13 16:12 dist/0.b19e913fbdd6507d346b.chunk.js
-rw-r--r--  1 iminar  eng    1535 Oct 13 16:12 dist/inline.eede8140efeab4c45b22.bundle.js
-rw-r--r--  1 iminar  eng  559389 Oct 13 16:12 dist/main.20858f9aa7cf8741b6aa.bundle.js
-rw-r--r--  1 iminar  eng   37402 Oct 13 16:12 dist/polyfills.f8409a9eb69060ac1aa6.bundle.js

PR Close #19702
2017-11-01 15:24:43 -07:00
b396029d39 build(aio): patch @angular/cli to use esm builds of rxjs (#19702)
-rw-r--r--  1 iminar  eng   14942 Oct 13 14:52 dist/0.b19e913fbdd6507d346b.chunk.js
-rw-r--r--  1 iminar  eng    1535 Oct 13 14:52 dist/inline.6ca24f1c3b848103b041.bundle.js
-rw-r--r--  1 iminar  eng  567802 Oct 13 14:52 dist/main.c8183a2c0116782ca366.bundle.js
-rw-r--r--  1 iminar  eng   37402 Oct 13 14:52 dist/polyfills.f8409a9eb69060ac1aa6.bundle.js

PR Close #19702
2017-11-01 15:24:43 -07:00
040b376052 build(aio): upgrade to rxjs@5.5.0-beta.7 (#19702)
-rw-r--r--  1 iminar  eng   14942 Oct 13 14:30 dist/0.b19e913fbdd6507d346b.chunk.js
-rw-r--r--  1 iminar  eng    1535 Oct 13 14:30 dist/inline.702d6ff5146ddc373f05.bundle.js
-rw-r--r--  1 iminar  eng  588943 Oct 13 14:30 dist/main.64c96d55a10c56cfd6cd.bundle.js
-rw-r--r--  1 iminar  eng   37402 Oct 13 14:30 dist/polyfills.f8409a9eb69060ac1aa6.bundle.js

PR Close #19702
2017-11-01 15:24:42 -07:00
175c872514 build(aio): upgrade to @angular/{material,cdk}@2.0.0-beta.12 (#19702)
-rw-r--r--  1 iminar  eng   14942 Oct 13 13:35 dist/0.b19e913fbdd6507d346b.chunk.js
-rw-r--r--  1 iminar  eng    1535 Oct 13 13:35 dist/inline.f005f1bd6803b72f5961.bundle.js
-rw-r--r--  1 iminar  eng  582527 Oct 13 13:35 dist/main.b9ef1abb785be8de15b8.bundle.js
-rw-r--r--  1 iminar  eng   37402 Oct 13 13:35 dist/polyfills.f8409a9eb69060ac1aa6.bundle.js

PR Close #19702
2017-11-01 15:24:42 -07:00
71291aa2c0 fix(aio): hand fix the renaming md->mat issues (#19702)
These are changes that the mat-switcher missed and I had to make them by hand.

PR Close #19702
2017-11-01 15:24:42 -07:00
415e75716a build(aio): upgrade to @angular/{material,cdk}@2.0.0-beta.11 + md->mat migration (#19702)
all the non-npm changes were made by the angular-material-prefix-updater tool.

the tool missed a few things, which I'll fix in a separate commit to preserve the diff.

-rw-r--r--  1 iminar  eng   14942 Oct 13 13:09 dist/0.b19e913fbdd6507d346b.chunk.js
-rw-r--r--  1 iminar  eng    1535 Oct 13 13:09 dist/inline.0592c25ceb544d6aca3d.bundle.js
-rw-r--r--  1 iminar  eng  578250 Oct 13 13:09 dist/main.45d4edca3facc6d621e7.bundle.js
-rw-r--r--  1 iminar  eng   37402 Oct 13 13:09 dist/polyfills.f8409a9eb69060ac1aa6.bundle.js

PR Close #19702
2017-11-01 15:24:42 -07:00
3216abee2e build(aio): upgrade to @angular/cli@1.5.0-rc.0 and typescript@2.5.3 (#19702)
the size regression has gotten worse:

-rw-r--r--  1 iminar  eng   14942 Oct 13 12:24 dist/0.b19e913fbdd6507d346b.chunk.js
-rw-r--r--  1 iminar  eng    1535 Oct 13 12:24 dist/inline.41e701c562960ede8ef5.bundle.js
-rw-r--r--  1 iminar  eng  865780 Oct 13 12:24 dist/main.6c4c605d461870b9c2d7.bundle.js
-rw-r--r--  1 iminar  eng   37402 Oct 13 12:24 dist/polyfills.f8409a9eb69060ac1aa6.bundle.js

PR Close #19702
2017-11-01 15:24:41 -07:00
327ad02a28 build(aio): upgrade to @angular/cli@1.4.7 (#19702)
this causes the size regression to get only worse:

-rw-r--r--  1 iminar  eng   14942 Oct 13 10:37 dist/0.b19e913fbdd6507d346b.chunk.js
-rw-r--r--  1 iminar  eng    1535 Oct 13 10:37 dist/inline.3cc964095cb25e329dc0.bundle.js
-rw-r--r--  1 iminar  eng  846141 Oct 13 10:37 dist/main.5eb64df77b2877327a16.bundle.js
-rw-r--r--  1 iminar  eng   37402 Oct 13 10:37 dist/polyfills.965a9a5ad3e11b17f85e.bundle.js

PR Close #19702
2017-11-01 15:24:41 -07:00
1df0c9e1b0 build(aio): update to @angular/core@5.0.0-rc.2 (#19702)
there is a size regression right now because the CLI is out of date:

-rw-r--r--  1 iminar  eng   14942 Oct 13 10:23 dist/0.b19e913fbdd6507d346b.chunk.js
-rw-r--r--  1 iminar  eng    1535 Oct 13 10:23 dist/inline.812a4af83ecce165c71c.bundle.js
-rw-r--r--  1 iminar  eng  643481 Oct 13 10:23 dist/main.74550bb35f9f5a57e78a.bundle.js
-rw-r--r--  1 iminar  eng   37402 Oct 13 10:23 dist/polyfills.965a9a5ad3e11b17f85e.bundle.js

PR Close #19702
2017-11-01 15:24:41 -07:00
280dadaaad docs(aio): fix typo in attribute-directives
Closes #20071
2017-11-01 15:21:09 -07:00
c30eff898a docs(aio): update universal for CLI
PR Close #20039
2017-11-01 15:18:43 -07:00
ca129ba549 docs(aio): upgrade to v5 and cli 1.5
PR Close #20077
2017-11-01 14:14:08 -07:00
171ae154c2 docs(packaging): fix typo
PR Close #18915
2017-11-01 15:45:58 -04:00
4426c0f14e fix(docs): Fix 404 on amcdnl image
PR Close #19120
2017-11-01 15:45:28 -04:00
901436e46f docs: fix link texts
Fixes #19701

PR Close #19709
2017-11-01 15:44:59 -04:00
6fbc2b3be0 docs(aio): update AngularJS Quick Reference guide
PR Close #19939
2017-11-01 15:44:35 -04:00
93d23ddcc8 docs(aio): fix typo
PR Close #20029
2017-11-01 15:42:25 -04:00
548a809a05 docs(aio): fix typo
PR Close #20042
2017-11-01 15:41:57 -04:00
a161b4ab6d docs(aio): fix typo
PR Close #20069
2017-11-01 15:41:27 -04:00
60b91656cd docs: add changelog for 5.0.0 2017-11-01 11:00:39 -07:00
1858d99559 release: cut the 5.0.0 release 2017-11-01 09:47:02 -07:00
3a8665409d build(aio): add i18n boilerplate type (#20004)
PR Close #20004
2017-10-31 01:06:25 -04:00
005a78bd83 refactor: allow compilation with TypeScript 2.5 (#19966)
A small number of types need to be adjusted. The changes seem to be
backwards compatible with TS 2.4.

PR Close #19966
2017-10-31 00:26:43 -04:00
7553ce9dfe docs: add changelog for 5.0.0-rc.9 2017-10-30 21:24:59 -07:00
42bfe4477f release: cut the 5.0.0-rc.9 release 2017-10-30 21:24:54 -07:00
3bdbb18c8b build: update rollup lint rule from bad merge (#20047)
PR Close #20047
2017-10-30 23:43:49 -04:00
13f8648a00 fix: add missing globals from each rollup configuration (#20028)
PR Close #20028
2017-10-30 23:09:17 -04:00
b6abcb2500 refactor: make all rollup config ES5 compatible (#20028)
So they can be required by other Node scripts.

PR Close #20028
2017-10-30 23:09:17 -04:00
f1a9e1e361 build: add lint rule for global flags in rollup config (#20028)
We now verify that every imports is part of the globals defined in the files rollup.config.js.

PR Close #20028
2017-10-30 23:09:16 -04:00
54480f7dfc fix(compiler): report errors properly in G3 in certain conditions (#20041)
Condition: static analysis error, given:
- noResolve:true
- generateCodeForLibraries: false
- CompilerHost.getSourceFile throws on non existent files

All of these are true in G3.
PR Close #20041
2017-10-30 21:24:30 -04:00
951bd33b09 build: add release as a valid commit message subject (#19955)
PR Close #19955
2017-10-30 21:23:18 -04:00
bf57df3e04 build: temporarily increase the commit msg limit to 120
Right now HEAD and 5.0.x have a branch deviation and therefore
all the commits between both branches are being compared. There
exists a problematic commit which has a commit message that is
longer than 100 commits. This patch will temporarily increase
the limit to 120 so that CI passes. Once master is resumed to
being the primary development branch (once 5.0.0 is out) then
the the msg limit will be set back to 100.
2017-10-30 21:20:43 -04:00
420852e2f5 fix(compiler): reexport less symbols in .ngfactory.ts files (#19884)
* don't reexport symbols that the user already reexported
* never reexport symbols that are part of arguments of non simple function calls

Fixes #19883

PR Close #19884
2017-10-30 20:11:29 -04:00
04eb80cc2b fix(compiler): always use relative paths to refer to generated code
Previously we generated imports like `@angular/material/index.ngfactory`,
which doesn’t make sense as we don’t ship generated code on npm

Closes #20031
2017-10-30 18:28:25 -04:00
308fc8e328 docs: add changelog for 5.0.0-rc.8 2017-10-27 23:46:02 -07:00
9bb2939d68 release: cut the 5.0.0-rc.8 release 2017-10-27 23:45:52 -07:00
2f63899be2 docs: ensure examples get rxjs ^5.5.0 (#19985)
This change coincidentally updates other packages that were in `package.json`
because it regenerates `yarn.lock`. This too should be fine.

PR Close #19985
2017-10-27 22:27:27 -07:00
22c66f0e02 fix(compiler-cli): avoid producing source mappings for host views (#19965)
The host view doesn't map back to user code so the template compiler
produces a blank `url` for them.

PR Close #19965
2017-10-27 22:26:57 -07:00
00bc80bb37 fix(platform-server): add missing packages to the UMD global rollup config
This adds the proper bindings for calling angular packages from platform-server in the UMD.
This was not a problem for universal apps that dont use UMD.

Fixes 19899
2017-10-27 22:26:25 -07:00
394d951883 docs: add changelog for 5.0.0-rc.7 2017-10-26 19:47:31 -07:00
98b26381f6 release: cut the 5.0.0-rc.7 release 2017-10-26 19:47:24 -07:00
31797d3b50 fix(compiler): make watch mode work on windows (#19953)
Fixes #19951
PR Close #19953
2017-10-26 18:43:00 -04:00
957be960d2 fix(compiler): recover from structural errors in watch mode (#19953)
This also changes the compiler so that we throw less often
on structural changes and produce a meaningful state
in the `ng.Program` in case of errors.

Related to #19951

PR Close #19953
2017-10-26 18:43:00 -04:00
18e9d86a3b fix(compiler): translate emit diagnostics with noEmitOnError: true. (#19953)
This prevents errors reported against `.ngfactory.ts` files show up
as the result of running `ngc`.

Closes #19935
PR Close #19953
2017-10-26 18:42:59 -04:00
a869aeecd2 fix(compiler): don’t store invalid state when using listLazyRoutes (#19953)
Previously, `listLazyRoute` would store invalid information in a compiler
internal cache, which lead to incorrect paths that were used during emit.
This commit fixes this.

PR Close #19953
2017-10-26 18:42:59 -04:00
eca822b756 fix(service-worker): fix improper call of Observable.merge (#19962)
Observable.merge was called using .call() as if it were an operator
and not an Observable factory. This removes the .call() and uses
the factory properly.

PR Close #19962
2017-10-26 18:09:53 -04:00
17142a778a fix(service-worker): don't block initialization on registration (#19936)
Importing ServiceWorkerModule.register() will schedule registration of
the Service Worker inside an APP_INITIALIZER. Previously, the Promise
returned by navigator.serviceWorker.register() was returned from the
initializer function. This has the unwanted side effect of blocking
initialization until the SW is registered. Even worse, if the SW script
fails to load, this can cause the app initialization to fail.

The solution is to not return the registration promise from the
initializer function, essentially decoupling registration from the rest
of the initialization flow.

This change is not unit testable as there are no mocks/adapters yet for
navigator.serviceWorker. A future integration test should cover this case
with better fidelity.

PR Close #19936
2017-10-26 16:05:07 -04:00
5adb7c9669 fix(service-worker): listen for messages on the right event source (#19954)
Currently, the SwUpdate service doesn't receive messages from the SW.
This is because it attempts to subscribe to the 'message' event on
ServiceWorkerRegistration, when really messages are emitted by the
ServiceWorkerContainer.

This change moves to listening on ServiceWorkerContainer and changes
the mocks to reflect the way the browser actually works.

PR Close #19954
2017-10-26 16:04:59 -04:00
703fcda590 docs: add changelog for 5.0.0-rc.6 2017-10-25 14:49:27 -07:00
f16a7cd7e3 release: cut the 5.0.0-rc.6 release 2017-10-25 14:48:41 -07:00
fde5f2fa14 build: update to rxjs@5.5.2 (#19931)
PR Close #19931
2017-10-25 14:27:05 -04:00
d56724659f fix(compiler): automatically set emitDecoratorMetadata when "annotationsAs": "static fields” (#19927)
This is a workaround for https://github.com/angular/tsickle/issues/635.

Fixes #19916
PR Close #19927
2017-10-25 13:38:39 -04:00
56b18ff063 fix(compiler-cli): produce correct paths for windows output (#19915)
The path mapping was broken for Windows by fc0b1d5b61.
Fixed the path mapping and put code in place to make such a problem
to sneek by again.

PR Close #19915
2017-10-24 17:54:58 -04:00
7bfeac746e fix(compiler-cli): only use error collector when needed. (#19912)
The error collector changes behavior of the metadata resolver
in ways that haven't been fully hardened. This changes limits
its use to the lazy route detection and the language service.

Issue: #19906

PR Close #19912
2017-10-24 17:06:41 -04:00
c92efc15fb fix(compiler): don’t type check templates with skipTemplateCodegen (#19909)
This change is needed to prevent users’ builds from breaking.

If a user sets `fullTemlateTypeCheck` to true, we will
continue to check the templates even when `skipTemplateCodegen` is true
as well.

Related to #19906

PR Close #19909
2017-10-24 17:06:34 -04:00
b51d57deb8 docs: add changelog for 5.0.0-rc.5 2017-10-23 23:50:31 -07:00
c357b40dca release: cut the 5.0.0-rc.5 release 2017-10-23 23:50:25 -07:00
a0ae120093 fix(compiler-cli): report all diagnostic error messages (#19886)
This fixes a problem introduced in 8d45fefc31
which modified how diagnostic error messages are reported for structural
metadata errors causing some of the diagnostics to be lost.

PR Close #19886
2017-10-23 22:41:10 -04:00
d3211a2468 feat(router): add "onSameUrlNavigation" router configuration option (#19463)
PR Close #19463
2017-10-23 20:56:53 -04:00
adab4f3e49 fix(router): do not call location.go when skipping a navigation (#19463)
Closes #18036

PR Close #19463
2017-10-23 20:56:52 -04:00
82fed62af2 fix(router): navigating to the current location works (#19463)
Closes #13340

PR Close #19463
2017-10-23 20:56:52 -04:00
21 changed files with 485 additions and 158 deletions

View File

@ -1,3 +1,25 @@
<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)
### 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
* **compiler:** introduce `TestBed.overrideTemplateUsingTestingModule` ([a460066](https://github.com/angular/angular/commit/a460066)), closes [#19815](https://github.com/angular/angular/issues/19815)
### Reverts
* feat(elements): implement `[@angular](https://github.com/angular)/elements` [#19469](https://github.com/angular/angular/issues/19469) ([#20152](https://github.com/angular/angular/issues/20152)) ([3997d97](https://github.com/angular/angular/commit/3997d97))
<a name="5.0.1"></a>
## [5.0.1](https://github.com/angular/angular/compare/5.0.0...5.0.1) (2017-11-08)

View File

@ -1,6 +1,6 @@
{
"name": "angular-srcs",
"version": "5.0.1",
"version": "5.1.0-beta.0",
"private": true,
"branchPattern": "2.0.*",
"description": "Angular - a web framework for modern web apps",

View File

@ -81,7 +81,9 @@ export class Runner {
{provide: WebDriverAdapter, useValue: adapter}
]);
const sampler = injector.get(Sampler);
// TODO: With TypeScript 2.5 injector.get does not infer correctly the
// return type. Remove 'any' and investigate the issue.
const sampler = injector.get(Sampler) as any;
return sampler.sample();
});
}

View File

@ -41,7 +41,9 @@ export class SpyLocation implements Location {
return currPath == givenPath + (query.length > 0 ? ('?' + query) : '');
}
simulateUrlPop(pathname: string) { this._subject.emit({'url': pathname, 'pop': true}); }
simulateUrlPop(pathname: string) {
this._subject.emit({'url': pathname, 'pop': true, 'type': 'popstate'});
}
simulateHashChange(pathname: string) {
// Because we don't prevent the native event, the browser will independently update the path

View File

@ -116,8 +116,8 @@ export class MetadataCollector {
function classMetadataOf(classDeclaration: ts.ClassDeclaration): ClassMetadata {
const result: ClassMetadata = {__symbolic: 'class'};
function getDecorators(decorators: ts.Decorator[] | undefined): MetadataSymbolicExpression[]|
undefined {
function getDecorators(decorators: ReadonlyArray<ts.Decorator>| undefined):
MetadataSymbolicExpression[]|undefined {
if (decorators && decorators.length)
return decorators.map(decorator => objFromDecorator(decorator));
return undefined;

View File

@ -606,7 +606,8 @@ class AngularCompilerProgram implements Program {
private writeFile(
outFileName: string, outData: string, writeByteOrderMark: boolean,
onError?: (message: string) => void, genFile?: GeneratedFile, sourceFiles?: ts.SourceFile[]) {
onError?: (message: string) => void, genFile?: GeneratedFile,
sourceFiles?: ReadonlyArray<ts.SourceFile>) {
// collect emittedLibrarySummaries
let baseFile: ts.SourceFile|undefined;
if (genFile) {
@ -653,7 +654,8 @@ class AngularCompilerProgram implements Program {
if (baseFile) {
sourceFiles = sourceFiles ? [...sourceFiles, baseFile] : [baseFile];
}
this.host.writeFile(outFileName, outData, writeByteOrderMark, onError, sourceFiles);
// TODO: remove any when TS 2.4 support is removed.
this.host.writeFile(outFileName, outData, writeByteOrderMark, onError, sourceFiles as any);
}
}

View File

@ -42,6 +42,7 @@ export class JitCompiler {
private _compiledDirectiveWrapperCache = new Map<Type, Type>();
private _compiledNgModuleCache = new Map<Type, object>();
private _sharedStylesheetCount = 0;
private _addedAotSummaries = new Set<() => any[]>();
constructor(
private _metadataResolver: CompileMetadataResolver, private _templateParser: TemplateParser,
@ -74,10 +75,25 @@ export class JitCompiler {
loadAotSummaries(summaries: () => any[]) {
this.clearCache();
flattenSummaries(summaries).forEach((summary) => {
this._summaryResolver.addSummary(
{symbol: summary.type.reference, metadata: null, type: summary});
});
this._addAotSummaries(summaries);
}
private _addAotSummaries(fn: () => any[]) {
if (this._addedAotSummaries.has(fn)) {
return;
}
this._addedAotSummaries.add(fn);
const summaries = fn();
for (let i = 0; i < summaries.length; i++) {
const entry = summaries[i];
if (typeof entry === 'function') {
this._addAotSummaries(entry);
} else {
const summary = entry as CompileTypeSummary;
this._summaryResolver.addSummary(
{symbol: summary.type.reference, metadata: null, type: summary});
}
}
}
hasAotSummary(ref: Type) { return !!this._summaryResolver.resolveSummary(ref); }
@ -200,6 +216,7 @@ export class JitCompiler {
}
clearCache(): void {
// Note: don't clear the _addedAotSummaries, as they don't change!
this._metadataResolver.clearCache();
this._compiledTemplateCache.clear();
this._compiledHostTemplateCache.clear();
@ -335,25 +352,6 @@ function assertComponent(meta: CompileDirectiveMetadata) {
}
}
function flattenSummaries(
fn: () => any[], out: CompileTypeSummary[] = [],
seen = new Set<() => any[]>()): CompileTypeSummary[] {
if (seen.has(fn)) {
return out;
}
seen.add(fn);
const summaries = fn();
for (let i = 0; i < summaries.length; i++) {
const entry = summaries[i];
if (typeof entry === 'function') {
flattenSummaries(entry, out, seen);
} else {
out.push(entry);
}
}
return out;
}
function createOutputContext(): OutputContext {
const importExpr = (symbol: any) =>
ir.importExpr({name: identifierName(symbol), moduleName: null, runtime: symbol});

View File

@ -20,5 +20,5 @@ export {DirectRenderer as ɵDirectRenderer, RenderDebugInfo as ɵRenderDebugInfo
export {global as ɵglobal, looseIdentical as ɵlooseIdentical, stringify as ɵstringify} from './util';
export {makeDecorator as ɵmakeDecorator} from './util/decorators';
export {isObservable as ɵisObservable, isPromise as ɵisPromise} from './util/lang';
export {clearProviderOverrides as ɵclearProviderOverrides, overrideProvider as ɵoverrideProvider} from './view/index';
export {clearOverrides as ɵclearOverrides, overrideComponentView as ɵoverrideComponentView, overrideProvider as ɵoverrideProvider} from './view/index';
export {NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR as ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR} from './view/provider';

View File

@ -7,11 +7,12 @@
*/
import {Injector} from '../di/injector';
import {ComponentFactory} from '../linker/component_factory';
import {NgModuleFactory, NgModuleRef} from '../linker/ng_module_factory';
import {Type} from '../type';
import {initServicesIfNeeded} from './services';
import {NgModuleDefinitionFactory, ProviderOverride, Services} from './types';
import {NgModuleDefinitionFactory, ProviderOverride, Services, ViewDefinition} from './types';
import {resolveDefinition} from './util';
export function overrideProvider(override: ProviderOverride) {
@ -19,9 +20,14 @@ export function overrideProvider(override: ProviderOverride) {
return Services.overrideProvider(override);
}
export function clearProviderOverrides() {
export function overrideComponentView(comp: Type<any>, componentFactory: ComponentFactory<any>) {
initServicesIfNeeded();
return Services.clearProviderOverrides();
return Services.overrideComponentView(comp, componentFactory);
}
export function clearOverrides() {
initServicesIfNeeded();
return Services.clearOverrides();
}
// Attention: this function is called as top level function.

View File

@ -7,7 +7,7 @@
*/
export {anchorDef, elementDef} from './element';
export {clearProviderOverrides, createNgModuleFactory, overrideProvider} from './entrypoint';
export {clearOverrides, createNgModuleFactory, overrideComponentView, overrideProvider} from './entrypoint';
export {ngContentDef} from './ng_content';
export {moduleDef, moduleProvideDef} from './ng_module';
export {directiveDef, pipeDef, providerDef} from './provider';

View File

@ -10,6 +10,7 @@ import {isDevMode} from '../application_ref';
import {DebugElement, DebugNode, EventListener, getDebugNode, indexDebugNode, removeDebugNodeFromIndex} from '../debug/debug_node';
import {Injector} from '../di';
import {ErrorHandler} from '../error_handler';
import {ComponentFactory} from '../linker/component_factory';
import {NgModuleRef} from '../linker/ng_module_factory';
import {Renderer2, RendererFactory2, RendererStyleFlags2, RendererType2} from '../render/api';
import {Sanitizer} from '../security';
@ -18,9 +19,9 @@ import {Type} from '../type';
import {isViewDebugError, viewDestroyedError, viewWrappedDebugError} from './errors';
import {resolveDep} from './provider';
import {dirtyParentQueries, getQueryValue} from './query';
import {createInjector, createNgModuleRef} from './refs';
import {createInjector, createNgModuleRef, getComponentViewDefinitionFactory} from './refs';
import {ArgumentType, BindingFlags, CheckType, DebugContext, DepDef, ElementData, NgModuleDefinition, NgModuleProviderDef, NodeDef, NodeFlags, NodeLogger, ProviderOverride, RootData, Services, ViewData, ViewDefinition, ViewState, asElementData, asPureExpressionData} from './types';
import {NOOP, isComponentView, renderNode, splitDepsDsl, viewParentEl} from './util';
import {NOOP, isComponentView, renderNode, resolveDefinition, splitDepsDsl, viewParentEl} from './util';
import {checkAndUpdateNode, checkAndUpdateView, checkNoChangesNode, checkNoChangesView, createComponentView, createEmbeddedView, createRootView, destroyView} from './view';
@ -38,7 +39,8 @@ export function initServicesIfNeeded() {
Services.createComponentView = services.createComponentView;
Services.createNgModuleRef = services.createNgModuleRef;
Services.overrideProvider = services.overrideProvider;
Services.clearProviderOverrides = services.clearProviderOverrides;
Services.overrideComponentView = services.overrideComponentView;
Services.clearOverrides = services.clearOverrides;
Services.checkAndUpdateView = services.checkAndUpdateView;
Services.checkNoChangesView = services.checkNoChangesView;
Services.destroyView = services.destroyView;
@ -58,7 +60,8 @@ function createProdServices() {
createComponentView: createComponentView,
createNgModuleRef: createNgModuleRef,
overrideProvider: NOOP,
clearProviderOverrides: NOOP,
overrideComponentView: NOOP,
clearOverrides: NOOP,
checkAndUpdateView: checkAndUpdateView,
checkNoChangesView: checkNoChangesView,
destroyView: destroyView,
@ -84,7 +87,8 @@ function createDebugServices() {
createComponentView: debugCreateComponentView,
createNgModuleRef: debugCreateNgModuleRef,
overrideProvider: debugOverrideProvider,
clearProviderOverrides: debugClearProviderOverrides,
overrideComponentView: debugOverrideComponentView,
clearOverrides: debugClearOverrides,
checkAndUpdateView: debugCheckAndUpdateView,
checkNoChangesView: debugCheckNoChangesView,
destroyView: debugDestroyView,
@ -139,10 +143,15 @@ function debugCreateEmbeddedView(
function debugCreateComponentView(
parentView: ViewData, nodeDef: NodeDef, viewDef: ViewDefinition, hostElement: any): ViewData {
const defWithOverride = applyProviderOverridesToView(viewDef);
const overrideComponentView =
viewDefOverrides.get(nodeDef.element !.componentProvider !.provider !.token);
if (overrideComponentView) {
viewDef = overrideComponentView;
} else {
viewDef = applyProviderOverridesToView(viewDef);
}
return callWithDebugContext(
DebugAction.create, createComponentView, null,
[parentView, nodeDef, defWithOverride, hostElement]);
DebugAction.create, createComponentView, null, [parentView, nodeDef, viewDef, hostElement]);
}
function debugCreateNgModuleRef(
@ -153,13 +162,21 @@ function debugCreateNgModuleRef(
}
const providerOverrides = new Map<any, ProviderOverride>();
const viewDefOverrides = new Map<any, ViewDefinition>();
function debugOverrideProvider(override: ProviderOverride) {
providerOverrides.set(override.token, override);
}
function debugClearProviderOverrides() {
function debugOverrideComponentView(comp: any, compFactory: ComponentFactory<any>) {
const hostViewDef = resolveDefinition(getComponentViewDefinitionFactory(compFactory));
const compViewDef = resolveDefinition(hostViewDef.nodes[0].element !.componentView !);
viewDefOverrides.set(comp, compViewDef);
}
function debugClearOverrides() {
providerOverrides.clear();
viewDefOverrides.clear();
}
// Notes about the algorithm:

View File

@ -8,6 +8,7 @@
import {Injector} from '../di';
import {ErrorHandler} from '../error_handler';
import {ComponentFactory} from '../linker/component_factory';
import {NgModuleRef} from '../linker/ng_module_factory';
import {QueryList} from '../linker/query_list';
import {TemplateRef} from '../linker/template_ref';
@ -16,6 +17,7 @@ import {Renderer2, RendererFactory2, RendererType2} from '../render/api';
import {Sanitizer, SecurityContext} from '../security';
import {Type} from '../type';
// -------------------------------------
// Defs
// -------------------------------------
@ -522,7 +524,8 @@ export interface Services {
moduleType: Type<any>, parent: Injector, bootstrapComponents: Type<any>[],
def: NgModuleDefinition): NgModuleRef<any>;
overrideProvider(override: ProviderOverride): void;
clearProviderOverrides(): void;
overrideComponentView(compType: Type<any>, compFactory: ComponentFactory<any>): void;
clearOverrides(): void;
checkAndUpdateView(view: ViewData): void;
checkNoChangesView(view: ViewData): void;
destroyView(view: ViewData): void;
@ -547,7 +550,8 @@ export const Services: Services = {
createComponentView: undefined !,
createNgModuleRef: undefined !,
overrideProvider: undefined !,
clearProviderOverrides: undefined !,
overrideComponentView: undefined !,
clearOverrides: undefined !,
checkAndUpdateView: undefined !,
checkNoChangesView: undefined !,
destroyView: undefined !,

View File

@ -11,10 +11,12 @@ import {CompileMetadataResolver} from '@angular/compiler/src/metadata_resolver';
import {MockResourceLoader} from '@angular/compiler/testing/src/resource_loader_mock';
import {Component, Directive, Injectable, NgModule, Pipe, Type} from '@angular/core';
import {TestBed, async, getTestBed} from '@angular/core/testing';
import {expect} from '@angular/platform-browser/testing/src/matchers';
export function main() {
describe('Jit Summaries', () => {
let instances: Map<any, Base>;
let summaries: () => any[];
class SomeDep {}
@ -69,7 +71,7 @@ export function main() {
TestBed.configureCompiler({providers: [{provide: ResourceLoader, useValue: resourceLoader}]});
TestBed.configureTestingModule({imports: [SomeModule], providers: [SomeDep]});
TestBed.compileComponents().then(() => {
let summariesPromise = TestBed.compileComponents().then(() => {
const metadataResolver = TestBed.get(CompileMetadataResolver) as CompileMetadataResolver;
const summaries = [
metadataResolver.getNgModuleSummary(SomeModule),
@ -83,10 +85,12 @@ export function main() {
metadataResolver.getInjectableSummary(SomeService)
];
clearMetadata();
resetTestEnvironmentWithSummaries(() => summaries);
TestBed.resetTestingModule();
return () => summaries;
});
resourceLoader.flush();
return summariesPromise;
}
function setMetadata(resourceLoader: MockResourceLoader) {
@ -123,12 +127,14 @@ export function main() {
beforeEach(async(() => {
instances = new Map<any, any>();
createSummaries();
createSummaries().then(s => summaries = s);
}));
afterEach(() => { resetTestEnvironmentWithSummaries(); });
it('should use directive metadata from summaries', () => {
resetTestEnvironmentWithSummaries(summaries);
@Component({template: '<div someDir></div>'})
class TestComp {
}
@ -140,6 +146,8 @@ export function main() {
});
it('should use pipe metadata from summaries', () => {
resetTestEnvironmentWithSummaries(summaries);
@Component({template: '{{1 | somePipe}}'})
class TestComp {
}
@ -150,6 +158,8 @@ export function main() {
});
it('should use Service metadata from summaries', () => {
resetTestEnvironmentWithSummaries(summaries);
TestBed.configureTestingModule({
providers: [SomeService, SomeDep],
});
@ -158,6 +168,8 @@ export function main() {
});
it('should use NgModule metadata from summaries', () => {
resetTestEnvironmentWithSummaries(summaries);
TestBed
.configureTestingModule(
{providers: [SomeDep], declarations: [TestComp3], imports: [SomeModule]})
@ -170,12 +182,16 @@ export function main() {
});
it('should allow to create private components from imported NgModule summaries', () => {
resetTestEnvironmentWithSummaries(summaries);
TestBed.configureTestingModule({providers: [SomeDep], imports: [SomeModule]})
.createComponent(SomePrivateComponent);
expectInstanceCreated(SomePrivateComponent);
});
it('should throw when trying to mock a type with a summary', () => {
resetTestEnvironmentWithSummaries(summaries);
TestBed.resetTestingModule();
expect(() => TestBed.overrideComponent(SomePrivateComponent, {add: {}}).compileComponents())
.toThrowError(
@ -190,5 +206,47 @@ export function main() {
expect(() => TestBed.overrideModule(SomeModule, {add: {}}).compileComponents())
.toThrowError('SomeModule was AOT compiled, so its metadata cannot be changed.');
});
it('should allow to add summaries via configureTestingModule', () => {
resetTestEnvironmentWithSummaries();
@Component({template: '<div someDir></div>'})
class TestComp {
}
TestBed
.configureTestingModule({
providers: [SomeDep],
declarations: [TestComp, SomeDirective],
aotSummaries: summaries
})
.createComponent(TestComp);
expectInstanceCreated(SomeDirective);
});
it('should allow to override a provider', () => {
resetTestEnvironmentWithSummaries(summaries);
const overwrittenValue = {};
const fixture =
TestBed.overrideProvider(SomeDep, {useFactory: () => overwrittenValue, deps: []})
.configureTestingModule({providers: [SomeDep], imports: [SomeModule]})
.createComponent(SomePublicComponent);
expect(fixture.componentInstance.dep).toBe(overwrittenValue);
});
it('should allow to override a template', () => {
resetTestEnvironmentWithSummaries(summaries);
TestBed.overrideTemplateUsingTestingModule(SomePublicComponent, 'overwritten');
const fixture = TestBed.configureTestingModule({providers: [SomeDep], imports: [SomeModule]})
.createComponent(SomePublicComponent);
expectInstanceCreated(SomePublicComponent);
expect(fixture.nativeElement).toHaveText('overwritten');
});
});
}

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {ApplicationInitStatus, CompilerOptions, Component, Directive, InjectionToken, Injector, ModuleWithComponentFactories, NgModule, NgModuleFactory, NgModuleRef, NgZone, Optional, Pipe, PlatformRef, Provider, SchemaMetadata, SkipSelf, Type, ɵDepFlags as DepFlags, ɵNodeFlags as NodeFlags, ɵclearProviderOverrides as clearProviderOverrides, ɵoverrideProvider as overrideProvider, ɵstringify as stringify} from '@angular/core';
import {ApplicationInitStatus, CompilerOptions, Component, Directive, InjectionToken, Injector, ModuleWithComponentFactories, NgModule, NgModuleFactory, NgModuleRef, NgZone, Optional, Pipe, PlatformRef, Provider, SchemaMetadata, SkipSelf, StaticProvider, Type, ɵDepFlags as DepFlags, ɵNodeFlags as NodeFlags, ɵclearOverrides as clearOverrides, ɵgetComponentViewDefinitionFactory as getComponentViewDefinitionFactory, ɵoverrideComponentView as overrideComponentView, ɵoverrideProvider as overrideProvider, ɵstringify as stringify} from '@angular/core';
import {AsyncTestCompleter} from './async_test_completer';
import {ComponentFixture} from './component_fixture';
@ -45,6 +45,7 @@ export type TestModuleMetadata = {
declarations?: any[],
imports?: any[],
schemas?: Array<SchemaMetadata|any[]>,
aotSummaries?: () => any[],
};
/**
@ -141,15 +142,29 @@ export class TestBed implements Injector {
return TestBed;
}
/**
* Overrides the template of the given component, compiling the template
* in the context of the TestingModule.
*
* Note: This works for JIT and AOTed components as well.
*/
static overrideTemplateUsingTestingModule(component: Type<any>, template: string):
typeof TestBed {
getTestBed().overrideTemplateUsingTestingModule(component, template);
return TestBed;
}
/**
* Overwrites all providers for the given token with the given provider definition.
*
* Note: This works for JIT and AOTed components as well.
*/
static overrideProvider(token: any, provider: {
useFactory: Function,
deps: any[],
}): void;
static overrideProvider(token: any, provider: {useValue: any;}): void;
}): typeof TestBed;
static overrideProvider(token: any, provider: {useValue: any;}): typeof TestBed;
static overrideProvider(token: any, provider: {
useFactory?: Function,
useValue?: any,
@ -205,7 +220,9 @@ export class TestBed implements Injector {
private _schemas: Array<SchemaMetadata|any[]> = [];
private _activeFixtures: ComponentFixture<any>[] = [];
private _aotSummaries: () => any[] = () => [];
private _testEnvAotSummaries: () => any[] = () => [];
private _aotSummaries: Array<() => any[]> = [];
private _templateOverrides: Array<{component: Type<any>, templateOf: Type<any>}> = [];
platform: PlatformRef = null !;
@ -232,7 +249,7 @@ export class TestBed implements Injector {
this.platform = platform;
this.ngModule = ngModule;
if (aotSummaries) {
this._aotSummaries = aotSummaries;
this._testEnvAotSummaries = aotSummaries;
}
}
@ -245,11 +262,13 @@ export class TestBed implements Injector {
this.resetTestingModule();
this.platform = null !;
this.ngModule = null !;
this._aotSummaries = () => [];
this._testEnvAotSummaries = () => [];
}
resetTestingModule() {
clearProviderOverrides();
clearOverrides();
this._aotSummaries = [];
this._templateOverrides = [];
this._compiler = null !;
this._moduleOverrides = [];
this._componentOverrides = [];
@ -293,6 +312,9 @@ export class TestBed implements Injector {
if (moduleDef.schemas) {
this._schemas.push(...moduleDef.schemas);
}
if (moduleDef.aotSummaries) {
this._aotSummaries.push(moduleDef.aotSummaries);
}
}
compileComponents(): Promise<any> {
@ -327,6 +349,11 @@ export class TestBed implements Injector {
}
}
}
for (const {component, templateOf} of this._templateOverrides) {
const compFactory = this._compiler.getComponentFactory(templateOf);
overrideComponentView(component, compFactory);
}
const ngZone = new NgZone({enableLongStackTrace: true});
const ngZoneInjector =
Injector.create([{provide: NgZone, useValue: ngZone}], this.platform.injector);
@ -339,7 +366,8 @@ export class TestBed implements Injector {
private _createCompilerAndModule(): Type<any> {
const providers = this._providers.concat([{provide: TestBed, useValue: this}]);
const declarations = this._declarations;
const declarations =
[...this._declarations, ...this._templateOverrides.map(entry => entry.templateOf)];
const imports = [this.ngModule, this._imports];
const schemas = this._schemas;
@ -350,7 +378,9 @@ export class TestBed implements Injector {
const compilerFactory: TestingCompilerFactory =
this.platform.injector.get(TestingCompilerFactory);
this._compiler = compilerFactory.createTestingCompiler(this._compilerOptions);
this._compiler.loadAotSummaries(this._aotSummaries);
for (const summary of [this._testEnvAotSummaries, ...this._aotSummaries]) {
this._compiler.loadAotSummaries(summary);
}
this._moduleOverrides.forEach((entry) => this._compiler.overrideModule(entry[0], entry[1]));
this._componentOverrides.forEach(
(entry) => this._compiler.overrideComponent(entry[0], entry[1]));
@ -470,6 +500,16 @@ export class TestBed implements Injector {
overrideProvider({token, flags, deps, value, deprecatedBehavior: deprecated});
}
overrideTemplateUsingTestingModule(component: Type<any>, template: string) {
this._assertNotInstantiated('overrideTemplateUsingTestingModule', 'override template');
@Component({selector: 'empty', template})
class OverrideComponent {
}
this._templateOverrides.push({component, templateOf: OverrideComponent});
}
createComponent<T>(component: Type<T>): ComponentFixture<T> {
this._initIfNeeded();
const componentFactory = this._compiler.getComponentFactory(component);

View File

@ -179,7 +179,13 @@ export function create(info: any /* ts.server.PluginCreateInfo */): ts.LanguageS
}
function completionToEntry(c: Completion): ts.CompletionEntry {
return {kind: c.kind, name: c.name, sortText: c.sort, kindModifiers: ''};
return {
// TODO: remove any and fix type error.
kind: c.kind as any,
name: c.name,
sortText: c.sort,
kindModifiers: ''
};
}
function diagnosticToDiagnostic(d: Diagnostic, file: ts.SourceFile): ts.Diagnostic {
@ -294,9 +300,10 @@ export function create(info: any /* ts.server.PluginCreateInfo */): ts.LanguageS
fileName: loc.fileName,
textSpan: {start: loc.span.start, length: loc.span.end - loc.span.start},
name: '',
kind: 'definition',
// TODO: remove any and fix type error.
kind: 'definition' as any,
containerName: loc.fileName,
containerKind: 'file'
containerKind: 'file' as any,
});
}
}

View File

@ -712,6 +712,60 @@ export function main() {
});
});
describe('overrideTemplateUsingTestingModule', () => {
it('should compile the template in the context of the testing module', () => {
@Component({selector: 'comp', template: 'a'})
class MyComponent {
prop = 'some prop';
}
let testDir: TestDir|undefined;
@Directive({selector: '[test]'})
class TestDir {
constructor() { testDir = this; }
@Input('test')
test: string;
}
TestBed.overrideTemplateUsingTestingModule(
MyComponent, '<div [test]="prop">Hello world!</div>');
const fixture = TestBed.configureTestingModule({declarations: [MyComponent, TestDir]})
.createComponent(MyComponent);
fixture.detectChanges();
expect(fixture.nativeElement).toHaveText('Hello world!');
expect(testDir).toBeAnInstanceOf(TestDir);
expect(testDir !.test).toBe('some prop');
});
it('should throw if the TestBed is already created', () => {
@Component({selector: 'comp', template: 'a'})
class MyComponent {
}
TestBed.get(Injector);
expect(() => TestBed.overrideTemplateUsingTestingModule(MyComponent, 'b'))
.toThrowError(
/Cannot override template when the test module has already been instantiated/);
});
it('should reset overrides when the testing module is resetted', () => {
@Component({selector: 'comp', template: 'a'})
class MyComponent {
}
TestBed.overrideTemplateUsingTestingModule(MyComponent, 'b');
const fixture = TestBed.resetTestingModule()
.configureTestingModule({declarations: [MyComponent]})
.createComponent(MyComponent);
expect(fixture.nativeElement).toHaveText('a');
});
});
describe('setting up the compiler', () => {
describe('providers', () => {

View File

@ -43,12 +43,12 @@ declare let Zone: any;
*/
export interface NavigationExtras {
/**
* Enables relative navigation from the current ActivatedRoute.
*
* Configuration:
*
* ```
* [{
* Enables relative navigation from the current ActivatedRoute.
*
* Configuration:
*
* ```
* [{
* path: 'parent',
* component: ParentComponent,
* children: [{
@ -59,92 +59,92 @@ export interface NavigationExtras {
* component: ChildComponent
* }]
* }]
* ```
*
* Navigate to list route from child route:
*
* ```
* @Component({...})
* class ChildComponent {
* ```
*
* Navigate to list route from child route:
*
* ```
* @Component({...})
* class ChildComponent {
* constructor(private router: Router, private route: ActivatedRoute) {}
*
* go() {
* this.router.navigate(['../list'], { relativeTo: this.route });
* }
* }
* ```
*/
* ```
*/
relativeTo?: ActivatedRoute|null;
/**
* Sets query parameters to the URL.
*
* ```
* // Navigate to /results?page=1
* this.router.navigate(['/results'], { queryParams: { page: 1 } });
* ```
*/
* Sets query parameters to the URL.
*
* ```
* // Navigate to /results?page=1
* this.router.navigate(['/results'], { queryParams: { page: 1 } });
* ```
*/
queryParams?: Params|null;
/**
* Sets the hash fragment for the URL.
*
* ```
* // Navigate to /results#top
* this.router.navigate(['/results'], { fragment: 'top' });
* ```
*/
* Sets the hash fragment for the URL.
*
* ```
* // Navigate to /results#top
* this.router.navigate(['/results'], { fragment: 'top' });
* ```
*/
fragment?: string;
/**
* Preserves the query parameters for the next navigation.
*
* deprecated, use `queryParamsHandling` instead
*
* ```
* // Preserve query params from /results?page=1 to /view?page=1
* this.router.navigate(['/view'], { preserveQueryParams: true });
* ```
*
* @deprecated since v4
*/
* Preserves the query parameters for the next navigation.
*
* deprecated, use `queryParamsHandling` instead
*
* ```
* // Preserve query params from /results?page=1 to /view?page=1
* this.router.navigate(['/view'], { preserveQueryParams: true });
* ```
*
* @deprecated since v4
*/
preserveQueryParams?: boolean;
/**
* config strategy to handle the query parameters for the next navigation.
*
* ```
* // from /results?page=1 to /view?page=1&page=2
* this.router.navigate(['/view'], { queryParams: { page: 2 }, queryParamsHandling: "merge" });
* ```
*/
* config strategy to handle the query parameters for the next navigation.
*
* ```
* // from /results?page=1 to /view?page=1&page=2
* this.router.navigate(['/view'], { queryParams: { page: 2 }, queryParamsHandling: "merge" });
* ```
*/
queryParamsHandling?: QueryParamsHandling|null;
/**
* Preserves the fragment for the next navigation
*
* ```
* // Preserve fragment from /results#top to /view#top
* this.router.navigate(['/view'], { preserveFragment: true });
* ```
*/
* Preserves the fragment for the next navigation
*
* ```
* // Preserve fragment from /results#top to /view#top
* this.router.navigate(['/view'], { preserveFragment: true });
* ```
*/
preserveFragment?: boolean;
/**
* Navigates without pushing a new state into history.
*
* ```
* // Navigate silently to /view
* this.router.navigate(['/view'], { skipLocationChange: true });
* ```
*/
* Navigates without pushing a new state into history.
*
* ```
* // Navigate silently to /view
* this.router.navigate(['/view'], { skipLocationChange: true });
* ```
*/
skipLocationChange?: boolean;
/**
* Navigates while replacing the current state in history.
*
* ```
* // Navigate to /view
* this.router.navigate(['/view'], { replaceUrl: true });
* ```
*/
* Navigates while replacing the current state in history.
*
* ```
* // Navigate to /view
* this.router.navigate(['/view'], { replaceUrl: true });
* ```
*/
replaceUrl?: boolean;
}
@ -241,6 +241,14 @@ export class Router {
routeReuseStrategy: RouteReuseStrategy = new DefaultRouteReuseStrategy();
/**
* Define what the router should do if it receives a navigation request to the current URL.
* By default, the router will ignore this navigation. However, this prevents features such
* as a "refresh" button. Use this option to configure the behavior when navigating to the
* current URL. Default is 'ignore'.
*/
onSameUrlNavigation: 'reload'|'ignore' = 'ignore';
/**
* Creates the router service.
*/
@ -518,11 +526,18 @@ export class Router {
// Because of a bug in IE and Edge, the location class fires two events (popstate and
// hashchange) every single time. The second one should be ignored. Otherwise, the URL will
// flicker.
// flicker. Handles the case when a popstate was emitted first.
if (lastNavigation && source == 'hashchange' && lastNavigation.source === 'popstate' &&
lastNavigation.rawUrl.toString() === rawUrl.toString()) {
return Promise.resolve(true); // return value is not used
}
// Because of a bug in IE and Edge, the location class fires two events (popstate and
// hashchange) every single time. The second one should be ignored. Otherwise, the URL will
// flicker. Handles the case when a hashchange was emitted first.
if (lastNavigation && source == 'popstate' && lastNavigation.source === 'hashchange' &&
lastNavigation.rawUrl.toString() === rawUrl.toString()) {
return Promise.resolve(true); // return value is not used
}
let resolve: any = null;
let reject: any = null;
@ -545,7 +560,8 @@ export class Router {
const url = this.urlHandlingStrategy.extract(rawUrl);
const urlTransition = !this.navigated || url.toString() !== this.currentUrlTree.toString();
if (urlTransition && this.urlHandlingStrategy.shouldProcessUrl(rawUrl)) {
if ((this.onSameUrlNavigation === 'reload' ? true : urlTransition) &&
this.urlHandlingStrategy.shouldProcessUrl(rawUrl)) {
(this.events as Subject<Event>).next(new NavigationStart(id, this.serializeUrl(url)));
Promise.resolve()
.then(
@ -573,10 +589,9 @@ export class Router {
}
private runNavigate(
url: UrlTree, rawUrl: UrlTree, shouldPreventPushState: boolean, shouldReplaceUrl: boolean,
id: number, precreatedState: RouterStateSnapshot|null): Promise<boolean> {
url: UrlTree, rawUrl: UrlTree, skipLocationChange: boolean, replaceUrl: boolean, id: number,
precreatedState: RouterStateSnapshot|null): Promise<boolean> {
if (id !== this.navigationId) {
this.location.go(this.urlSerializer.serialize(this.currentUrlTree));
(this.events as Subject<Event>)
.next(new NavigationCancel(
id, this.serializeUrl(url),
@ -698,9 +713,9 @@ export class Router {
(this as{routerState: RouterState}).routerState = state;
if (!shouldPreventPushState) {
if (!skipLocationChange) {
const path = this.urlSerializer.serialize(this.rawUrlTree);
if (this.location.isCurrentPathEqualTo(path) || shouldReplaceUrl) {
if (this.location.isCurrentPathEqualTo(path) || replaceUrl) {
this.location.replaceState(path);
} else {
this.location.go(path);
@ -748,14 +763,13 @@ export class Router {
(this as{routerState: RouterState}).routerState = storedState;
this.currentUrlTree = storedUrl;
this.rawUrlTree = this.urlHandlingStrategy.merge(this.currentUrlTree, rawUrl);
this.location.replaceState(this.serializeUrl(this.rawUrlTree));
this.resetUrlToCurrentUrlTree();
});
});
}
private resetUrlToCurrentUrlTree(): void {
const path = this.urlSerializer.serialize(this.rawUrlTree);
this.location.replaceState(path);
this.location.replaceState(this.urlSerializer.serialize(this.rawUrlTree));
}
}

View File

@ -129,12 +129,15 @@ export class RouterModule {
* Creates a module with all the router providers and directives. It also optionally sets up an
* application listener to perform an initial navigation.
*
* Options:
* Options (see {@link ExtraOptions}):
* * `enableTracing` makes the router log all its internal events to the console.
* * `useHash` enables the location strategy that uses the URL fragment instead of the history
* API.
* * `initialNavigation` disables the initial navigation.
* * `errorHandler` provides a custom error handler.
* * `preloadingStrategy` configures a preloading strategy (see {@link PreloadAllModules}).
* * `onSameUrlNavigation` configures how the router handles navigation to the current URL. See
* {@link ExtraOptions} for more details.
*/
static forRoot(routes: Routes, config?: ExtraOptions): ModuleWithProviders {
return {
@ -267,6 +270,14 @@ export interface ExtraOptions {
* Configures a preloading strategy. See {@link PreloadAllModules}.
*/
preloadingStrategy?: any;
/**
* Define what the router should do if it receives a navigation request to the current URL.
* By default, the router will ignore this navigation. However, this prevents features such
* as a "refresh" button. Use this option to configure the behavior when navigating to the
* current URL. Default is 'ignore'.
*/
onSameUrlNavigation?: 'reload'|'ignore';
}
export function setupRouter(
@ -299,6 +310,10 @@ export function setupRouter(
});
}
if (opts.onSameUrlNavigation) {
router.onSameUrlNavigation = opts.onSameUrlNavigation;
}
return router;
}

View File

@ -12,6 +12,7 @@ import {ComponentFixture, TestBed, fakeAsync, inject, tick} from '@angular/core/
import {By} from '@angular/platform-browser/src/dom/debug/by';
import {expect} from '@angular/platform-browser/testing/src/matchers';
import {ActivatedRoute, ActivatedRouteSnapshot, ActivationEnd, ActivationStart, CanActivate, CanDeactivate, ChildActivationEnd, ChildActivationStart, DetachedRouteHandle, Event, GuardsCheckEnd, GuardsCheckStart, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, PRIMARY_OUTLET, ParamMap, Params, PreloadAllModules, PreloadingStrategy, Resolve, ResolveEnd, ResolveStart, RouteConfigLoadEnd, RouteConfigLoadStart, RouteReuseStrategy, Router, RouterEvent, RouterModule, RouterPreloader, RouterStateSnapshot, RoutesRecognized, RunGuardsAndResolvers, UrlHandlingStrategy, UrlSegmentGroup, UrlTree} from '@angular/router';
import {SpyLocation} from 'common/testing';
import {Observable} from 'rxjs/Observable';
import {Observer} from 'rxjs/Observer';
import {of } from 'rxjs/observable/of';
@ -50,6 +51,89 @@ describe('Integration', () => {
expect(fixture.nativeElement).toHaveText('route');
})));
describe('navigation', function() {
it('should navigate to the current URL', fakeAsync(inject([Router], (router: Router) => {
router.onSameUrlNavigation = 'reload';
router.resetConfig([
{path: '', component: SimpleCmp},
{path: 'simple', component: SimpleCmp},
]);
const fixture = createRoot(router, RootCmp);
const events: Event[] = [];
router.events.subscribe(e => onlyNavigationStartAndEnd(e) && events.push(e));
router.navigateByUrl('/simple');
tick();
router.navigateByUrl('/simple');
tick();
expectEvents(events, [
[NavigationStart, '/simple'], [NavigationEnd, '/simple'], [NavigationStart, '/simple'],
[NavigationEnd, '/simple']
]);
})));
it('should not pollute browser history when replaceUrl is set to true',
fakeAsync(inject([Router, Location], (router: Router, location: SpyLocation) => {
router.resetConfig([
{path: '', component: SimpleCmp}, {path: 'a', component: SimpleCmp},
{path: 'b', component: SimpleCmp}
]);
const fixture = createRoot(router, RootCmp);
router.navigateByUrl('/a', {replaceUrl: true});
router.navigateByUrl('/b', {replaceUrl: true});
tick();
expect(location.urlChanges).toEqual(['replace: /', 'replace: /b']);
})));
it('should skip navigation if another navigation is already scheduled',
fakeAsync(inject([Router, Location], (router: Router, location: SpyLocation) => {
router.resetConfig([
{path: '', component: SimpleCmp}, {path: 'a', component: SimpleCmp},
{path: 'b', component: SimpleCmp}
]);
const fixture = createRoot(router, RootCmp);
router.navigate(
['/a'], {queryParams: {a: true}, queryParamsHandling: 'merge', replaceUrl: true});
router.navigate(
['/b'], {queryParams: {b: true}, queryParamsHandling: 'merge', replaceUrl: true});
tick();
/**
* Why do we have '/b?b=true' and not '/b?a=true&b=true'?
*
* This is because the router has the right to stop a navigation mid-flight if another
* navigation has been already scheduled. This is why we can use a top-level guard
* to perform redirects. Calling `navigate` in such a guard will stop the navigation, and
* the components won't be instantiated.
*
* This is a fundamental property of the router: it only cares about its latest state.
*
* This means that components should only map params to something else, not reduce them.
* In other words, the following component is asking for trouble:
*
* ```
* class MyComponent {
* constructor(a: ActivatedRoute) {
* a.params.scan(...)
* }
* }
* ```
*
* This also means "queryParamsHandling: 'merge'" should only be used to merge with
* long-living query parameters (e.g., debug).
*/
expect(router.url).toEqual('/b?b=true');
})));
});
describe('should execute navigations serially', () => {
let log: any[] = [];
@ -428,7 +512,7 @@ describe('Integration', () => {
}]);
const recordedEvents: any[] = [];
router.events.forEach(e => e instanceof RouterEvent && recordedEvents.push(e));
router.events.forEach(e => onlyNavigationStartAndEnd(e) && recordedEvents.push(e));
router.navigateByUrl('/team/22/user/victor');
advance(fixture);
@ -442,15 +526,8 @@ describe('Integration', () => {
expect(fixture.nativeElement).toHaveText('team 22 [ user fedor, right: ]');
expectEvents(recordedEvents, [
[NavigationStart, '/team/22/user/victor'], [RoutesRecognized, '/team/22/user/victor'],
[GuardsCheckStart, '/team/22/user/victor'], [GuardsCheckEnd, '/team/22/user/victor'],
[ResolveStart, '/team/22/user/victor'], [ResolveEnd, '/team/22/user/victor'],
[NavigationEnd, '/team/22/user/victor'],
[NavigationStart, '/team/22/user/fedor'], [RoutesRecognized, '/team/22/user/fedor'],
[GuardsCheckStart, '/team/22/user/fedor'], [GuardsCheckEnd, '/team/22/user/fedor'],
[ResolveStart, '/team/22/user/fedor'], [ResolveEnd, '/team/22/user/fedor'],
[NavigationEnd, '/team/22/user/fedor']
[NavigationStart, '/team/22/user/victor'], [NavigationEnd, '/team/22/user/victor'],
[NavigationStart, '/team/22/user/fedor'], [NavigationEnd, '/team/22/user/fedor']
]);
})));
@ -3638,6 +3715,10 @@ function expectEvents(events: Event[], pairs: any[]) {
}
}
function onlyNavigationStartAndEnd(e: Event): boolean {
return e instanceof NavigationStart || e instanceof NavigationEnd;
}
@Component(
{selector: 'link-cmp', template: `<a routerLink="/team/33/simple" [target]="'_self'">link</a>`})
class StringLinkCmp {

View File

@ -71,13 +71,13 @@ export declare class TestBed implements Injector {
}): void;
configureTestingModule(moduleDef: TestModuleMetadata): void;
createComponent<T>(component: Type<T>): ComponentFixture<T>;
deprecatedOverrideProvider(token: any, provider: {
useValue: any;
}): void;
/** @deprecated */ deprecatedOverrideProvider(token: any, provider: {
useFactory: Function;
deps: any[];
}): void;
deprecatedOverrideProvider(token: any, provider: {
useValue: any;
}): void;
execute(tokens: any[], fn: Function, context?: any): any;
get(token: any, notFoundValue?: any): any;
/** @experimental */ initTestEnvironment(ngModule: Type<any> | Type<any>[], platform: PlatformRef, aotSummaries?: () => any[]): void;
@ -92,6 +92,7 @@ export declare class TestBed implements Injector {
overrideProvider(token: any, provider: {
useValue: any;
}): void;
overrideTemplateUsingTestingModule(component: Type<any>, template: string): void;
/** @experimental */ resetTestEnvironment(): void;
resetTestingModule(): void;
static compileComponents(): Promise<any>;
@ -101,13 +102,13 @@ export declare class TestBed implements Injector {
}): typeof TestBed;
static configureTestingModule(moduleDef: TestModuleMetadata): typeof TestBed;
static createComponent<T>(component: Type<T>): ComponentFixture<T>;
static deprecatedOverrideProvider(token: any, provider: {
useValue: any;
}): void;
/** @deprecated */ static deprecatedOverrideProvider(token: any, provider: {
useFactory: Function;
deps: any[];
}): void;
static deprecatedOverrideProvider(token: any, provider: {
useValue: any;
}): void;
static get(token: any, notFoundValue?: any): any;
/** @experimental */ static initTestEnvironment(ngModule: Type<any> | Type<any>[], platform: PlatformRef, aotSummaries?: () => any[]): TestBed;
static overrideComponent(component: Type<any>, override: MetadataOverride<Component>): typeof TestBed;
@ -117,11 +118,12 @@ export declare class TestBed implements Injector {
static overrideProvider(token: any, provider: {
useFactory: Function;
deps: any[];
}): void;
}): typeof TestBed;
static overrideProvider(token: any, provider: {
useValue: any;
}): void;
}): typeof TestBed;
static overrideTemplate(component: Type<any>, template: string): typeof TestBed;
static overrideTemplateUsingTestingModule(component: Type<any>, template: string): typeof TestBed;
/** @experimental */ static resetTestEnvironment(): void;
static resetTestingModule(): typeof TestBed;
}
@ -137,6 +139,7 @@ export declare type TestModuleMetadata = {
declarations?: any[];
imports?: any[];
schemas?: Array<SchemaMetadata | any[]>;
aotSummaries?: () => any[];
};
/** @experimental */

View File

@ -126,6 +126,7 @@ export interface ExtraOptions {
enableTracing?: boolean;
errorHandler?: ErrorHandler;
initialNavigation?: InitialNavigation;
onSameUrlNavigation?: 'reload' | 'ignore';
preloadingStrategy?: any;
useHash?: boolean;
}
@ -327,6 +328,7 @@ export declare class Router {
errorHandler: ErrorHandler;
readonly events: Observable<Event>;
navigated: boolean;
onSameUrlNavigation: 'reload' | 'ignore';
routeReuseStrategy: RouteReuseStrategy;
readonly routerState: RouterState;
readonly url: string;