Compare commits

..

110 Commits
9.0.3 ... 9.0.6

Author SHA1 Message Date
ecac8c032b release: cut the v9.0.6 release 2020-03-10 17:32:16 -07:00
ce728dd323 build: adding a script to compare commits in master and stable branches (#35130)
Adding a script that compares commits in master and patch branches and finds a delta between them. This is useful for release reviews, to make sure all the necessary commits are included into the patch branch and there is no discrepancy.

PR Close #35130
2020-03-10 17:40:56 -04:00
20dd0ac4f2 build: Add pullapprove verification tool to dev-infra-private package (#35911)
Migrates pullapprove verification tool to be available in the dev-infra-private
package

PR Close #35911
2020-03-10 14:17:56 -04:00
0f4d424da9 build: creates a script to get contributor stats from across the angular org (#35834)
This script gets all of the current users for the organization and retrieves
information about PR/Issue contributions/authorship since a provided date.
Returning this information as a CSV.

PR Close #35834
2020-03-10 14:17:25 -04:00
6f2fd6e4b4 fix(compiler): process imports first and declarations second while calculating scopes (#35850)
Prior to this commit, while calculating the scope for a module, Ivy compiler processed `declarations` field first and `imports` after that. That results in a couple issues:

* for Pipes with the same `name` and present in `declarations` and in an imported module, Pipe from imported module was selected. In View Engine the logic is opposite: Pipes from `declarations` field receive higher priority.
* for Directives with the same selector and present in `declarations` and in an imported module, we first invoked the logic of a Directive from `declarations` field and after that - imported Directive logic. In View Engine, it was the opposite and the logic of a Directive from the `declarations` field was invoked last.

In order to align Ivy and View Engine behavior, this commit updates the logic in which we populate module scope: we first process all imports and after that handle `declarations` field. As a result, in Ivy both use-cases listed above work similar to View Engine.

Resolves #35502.

PR Close #35850
2020-03-10 14:16:59 -04:00
8a68a7c490 build: fix elements test failures on IE (#35940)
Fixes the following issues which caused the `elements` unit tests to break on IE:
1. `core.js` wasn't included which caused an error about `Promise` and `Symbol` to be thrown.
2. We were using a version of `@webcomponents/custom-elements` which was shipping ES6 code to npm. As a result, IE was throwing a syntax error.

PR Close #35940
2020-03-10 14:16:34 -04:00
800e31b6d3 build: set dev-infra package to be private (#35910)
Setting the dev-infra package to private will prevent us
from accidentally publishing the package to npm.

PR Close #35910
2020-03-10 14:15:58 -04:00
0d784e0b00 test(compiler): add a public API guard for the public compiler options (#35885)
This commit adds a public API test which guards against unintentional
changes to the accepted keys in `angularCompilerOptions`.

PR Close #35885
2020-03-10 14:15:29 -04:00
8b0e26f786 refactor(compiler): split core/api.ts into multiple files (#35885)
This commit splits the ngtsc `core` package's api entrypoint, which
previously was a single `api.ts` file, into an api/ directory with multiple
files. This is done to isolate the parts of the API definitions pertaining
to the public-facing `angularCompilerOptions` field in tsconfig.json into a
single file, which will enable a public API guard test to be added in a
future commit.

PR Close #35885
2020-03-10 14:15:29 -04:00
6ff6159e32 ci: update components-repo-unit-tests job commit (#35961)
Updates the commit that the `components-repo-unit-tests` job runs
against to the latest available commit at time of writing.

The motivation for updating is that a lot of changes have been made, and
that a upcoming framework PR that fixes check no changes for OnPush
components exposed a test failure in `angular/components`.

See: eae5cf886d

PR Close #35961
2020-03-10 13:29:03 -04:00
db9704a433 fix(platform-browser): add missing peerDependency on @angular/animations (#35949)
`@angular/platform-browser/animations` has a dependency on `@angular/animations` however, this is not listed in `peerDependencies`

With this change we add this package as an optional peerDependency as it's only required when using the `@angular/platform-browser/animations` entrypoint.

Fixes #35888

PR Close #35949
2020-03-10 13:28:33 -04:00
add3e18e9d test(router): use pageYOffset in testing when scrollY is not available (#35976)
IE 9, 10, and 11 use the non-standard name `pageYOffset` instead of
`scrollY`.

PR Close #35976
2020-03-10 13:28:04 -04:00
b71cdf99fc refactor(compiler): optionalOperator -> consumeOptionalOperator (#35980)
PR Close #35980
2020-03-10 13:27:37 -04:00
f882ff01f3 fix(language-service): resolve the variable from the template context first (#35982)
PR Close #35982
2020-03-10 13:27:04 -04:00
2184ad5436 feat(dev-infra): add dev-infra to the commit message scopes (#35992)
Adds dev-infra to the commit message scopes.  Also, sets the scope to be ignored
in changelogs.

PR Close #35992
2020-03-10 13:26:14 -04:00
83d7819bfc fix(localize): merge translation from all XLIFF <file> elements (#35936)
XLIFF translation files can contain multiple `<file>` elements,
each of which contains translations. In ViewEngine all these
translations are merged into a single translation bundle.

Previously in Ivy only the translations from the last `<file>`
element were being loaded. Now all the translations from each
`<file>` are merged into a single translation bundle.

Fixes #35839

PR Close #35936
2020-03-09 13:06:05 -04:00
4cc519eb10 refactor(benchpress): remove benchmarks_external from ..pullapprove.yml (#35670)
PR Close #35670
2020-03-09 12:19:25 -04:00
8bcb0784bc refactor(benchpress): delete unused code (#35670)
PR Close #35670
2020-03-09 12:19:25 -04:00
9f68ff9e5b fix(localize): improve matching and parsing of XTB translation files (#35793)
This commit improves the `canParse()` method to check that the file is
valid XML and has the expected root node. Previously it was relying upon
a regular expression to do this.

PR Close #35793
2020-03-09 12:12:00 -04:00
689964b20f fix(localize): improve matching and parsing of XLIFF 2.0 translation files (#35793)
Previously, the `Xliff2TranslationParser` only matched files that had a narrow
choice of extensions (e.g. `xlf`) and also relied upon a regular expression
match of an optional XML namespace directive.

This commit relaxes the requirement on both of these and, instead, relies
upon parsing the file into XML and identifying an element of the form
`<xliff version="2.0">` which is the minimal requirement for such files.

PR Close #35793
2020-03-09 12:11:59 -04:00
677d666a20 fix(localize): improve matching and parsing of XLIFF 1.2 translation files (#35793)
Previously, the `Xliff1TranslationParser` only matched files that had a narrow
choice of extensions (e.g. `xlf`) and also relied upon a regular expression
match of an optional XML namespace directive.

This commit relaxes the requirement on both of these and, instead, relies
upon parsing the file into XML and identifying an element of the form
`<xliff version="1.2">` which is the minimal requirement for such files.

PR Close #35793
2020-03-09 12:11:59 -04:00
4d7b176329 refactor(localize): allow hints from canParse() to parse() (#35793)
This enables complex work to be done in `TranslationParser.canParse()`
without duplicating the work in `TranslationParser.parse()`.

PR Close #35793
2020-03-09 12:11:59 -04:00
6b0e247412 refactor(localize): add support for TranslationParser diagnostics (#35793)
This modifies the internal (but shared with CLI) API for loading/parsing
translation files. Now the parsers will return a new `Diagnostics` object
along with any translations and locale extracted from the file.

It is up to the caller to decide what to do about this, if there are errors
it is suggested that an error is thrown, which is what the `TranslationLoader`
class does.

PR Close #35793
2020-03-09 12:11:59 -04:00
9e23a69d1b refactor: export silentLogger not SilentLoggerFn (#34079)
Export SilentLogger object instead of the SilentLoggerFn and capitalise silentLoggerFn instead of the SilentLoggerFn
PR Close #34079
2020-03-06 17:37:12 -05:00
63bde80ca7 fix(zone.js): tickOptions's processNewMacroTasksSynchronously should default to true when flag omitted (#35814)
Calling `tick(0, null)` defaults `processNewMacroTasksSynchronously` flag to `true`, however calling  `tick(0, null, {})` defaults `processNewMacroTasksSynchronously` to `undefined`. This is undesirable behavior since unless the flag is set explicitly it should still default to `true`.

PR Close #35814
2020-03-06 17:33:57 -05:00
5ea9a61a87 fix(bazel): do not use manifest paths for generated imports within compilation unit (#35841)
Currently, the `ng_module` rule incorrectly uses manifest paths for
generated imports from the Angular compiler.

This breaks packaging as prodmode output (i.e. `esnext`) is copied in
various targets (`es5` and `es2015`) to the npm package output.

e.g. imports are generated like:

_node_modules/my-pkg/es2015/imports/public-api.js_
```ts
import * as i1 from "angular/packages/bazel/test/ng_package/example/imports/second";
```

while it should be actually:

```ts
import * as i1 from "./second";
```

The imports can, and should be relative so that the files are
self-contained and do not rely on custom module resolution.

PR Close #35841
2020-03-06 17:31:11 -05:00
5a09ea328f test: add entry-point with generated imports to ng_package test (#35841)
PR Close #35841
2020-03-06 17:31:11 -05:00
000c834554 fix(core): remove side effects from ɵɵgetInheritedFactory() (#35769) (#35846)
`ɵɵgetInheritedFactory()` is called from generated code for a component which extends another class. This function is detected by Closure to have a side effect and is not able to tree shake the component as a result. Marking it with `noSideEffects()` tells Closure it can remove this function under the relevant tree shaking conditions.

PR Close #35769

(cherry picked from commit c195d22f68)

PR Close #35846
2020-03-06 17:30:47 -05:00
d24ce21c45 fix(core): remove side effects from ɵɵNgOnChangesFeature() (#35769) (#35846)
`ɵɵNgOnChangesFeature()` would set `ngInherit`, which is a side effect and also not necessary. This was pulled out to module scope so the function itself can be pure. Since it only curries another function, the call is entirely unnecessary. Updated the compiler to only generate a reference to this function, rather than a call to it, and removed the extra curry indirection.

PR Close #35769

(cherry picked from commit 9cf85d2177)

PR Close #35846
2020-03-06 17:30:47 -05:00
68ca32fe51 fix(core): add noSideEffects() to ɵɵdefineComponent() (#35769) (#35846)
This marks the function are "pure" and eligible to be tree shaken by Closure. Without this, initializing `ngDevMode` is considered a side effect which prevents this function from being tree shaken and also any component which calls it.

PR Close #35769

(cherry picked from commit ba3612774f)

PR Close #35846
2020-03-06 17:30:47 -05:00
4fe3f37b3c fix(core): add noSideEffects() to make*Decorator() functions (#35769) (#35846)
This causes all the `make*Decorator()` functions to be considered pure and to be eligible for associated tree shaking by Closure.

PR Close #35769

(cherry picked from commit dc6a7918e3)

PR Close #35846
2020-03-06 17:30:47 -05:00
e0cf3ad4b3 refactor(core): update noSideEffects() to return the result of the inner function (#35769) (#35846)
This is useful for propagating return values without them being converted to a string. It still provides the same guarantees to Closure, which will assume that the function invoked is pure and can be tree-shaken accordingly.

PR Close #35769

(cherry picked from commit 4052dd8188)

PR Close #35846
2020-03-06 17:30:47 -05:00
5abf068b23 build(docs-infra): use local version of Zone.js when testing against local packages (#35858)
In some cases, we want to test the AIO app or docs examples against the
locally built Angular packages (for example to ensure that the changes
in a commit do not introduce a breaking change). In order to achieve
this, we have the `ng-packages-installer` script that handles updating
a project's `package.json` file to use the locally built Angular
packages (and appropriate versions for their (dev-/peer-)dependencies).

Previously, `ng-packages-installer` would only consider the locally
built Angular packages (from `dist/packages-dist/`). However, given that
Zone.js is now part of the `angular/angular` repo, it makes sense to
also use the locally built Zone.js package (from `dist/zone.js-dist/`).
Otherwise, the tests might fail for commits that update both the Angular
packages (and related docs examples) and the Zone.js package. An example
of such a simultaneous change (that would have broken tests) is #33838.

This commit updates the script to install the locally built Zone.js
package (in addition to the Angular ones). The commit ensures that the
Zone.js package will always be available alongside the Angular packages
(i.e. that the Zone.js package will be built by the same script that
builds the Angular packages and that the `dist/zone.js-dist/` directory
will be cached on CI).

Note: This problem was discovered while enabling docs examples unit
tests in #34374.

PR Close #35858
2020-03-06 17:30:20 -05:00
28d2bf7d7c docs(zone.js): update comment and chapter format of ngzone doc. (#35738)
PR Close #35738
2020-03-06 16:51:44 -05:00
51c1911c56 docs: markup mini fix (#35883)
PR Close #35883
2020-03-06 16:50:10 -05:00
eaf5b5856d fix(core): undecorated-classes-with-di migration should handle libraries generated with CLI versions past v6.2.0 (#35824)
The options for `flatModuleId` and `flatModuleOutFile` had been removed in the CLI
from generated libraries with 718ee15b9a.

This has been done because `ng-packagr` (which is used to build the
libraries) automatically set these options in-memory when it compiles the library.
No migration has been created for this because there was no actual need to get rid of
this. Keeping the options in the library `tsconfig` does not cause any problems unless
the `tsconfig` is used outside of `ng-packagr`. This was not anticipated, but is now
commonly done in `ng update` migrations.

The `ng update` migrations try to create an instance of the `AngularCompilerProgram` by
simply parsing the `tsconfig`. The migrations make the valid assumption that `tsconfig` files
are not incomplete/invalid. They _definitely_ are in the file system though. It just works for
libraries because `ng-packagr` in-memory completes the invalid `tsconfig` files, so that they
can be passed to the `@angular/compiler-cli`.

We can't have this logic in the `ng update` migrations because it's
out-of-scope for individual migrations to distinguish between libraries
and applications. Also it would be out-of-scope to parse the
`ng-packagr` configuration and handle the tsconfig in-memory completion.

As a workaround though, we can remove the flat-module bundle options
in-memory when creating the compiler program. This is acceptable since
we don't emit the program and the flat module bundles are not needed.

Fixes #34985.

PR Close #35824
2020-03-06 12:40:18 -05:00
9a9cc01be1 refactor(compiler): rename _ParseAST.optionalCharacter TemplateBinding.expression (#35886)
This commit renames
1. _ParseAST.optionalCharacter -> consumeOptionalCharacter
2. TemplateBinding.expression -> value

PR Close #35886
2020-03-06 12:39:49 -05:00
6330200004 docs: move ngIndia 2020 to past events on events page (#35901)
ng india was an outdated event removed it from upcoming events on the events page and added to already presented events

PR Close #35901
2020-03-06 12:39:25 -05:00
645fa40571 docs: add missing closing bracket (#35890)
Closes #35887
PR Close #35890
2020-03-06 12:38:30 -05:00
2cccf59415 build: create dev-infra-private npm package (#35862)
Creates the scaffolding for an @angular/dev-infra-private package
which will not be published to npm but will be pushed to
https://github.com/angular/dev-infra-private-builds repo for each
commit to master.

The contents of this npm package will then be depended on via
package.json dependency for angular/angular angular/angular-cli and
angular/components.

PR Close #35862
2020-03-05 18:55:40 -05:00
2a9b254ca5 refactor(compiler): Break up parseTemplateBindings() for microsyntax (#35812)
This commit is purely a refactoring of the logic in
`parseTemplateBindings` method for parsing the microsyntax expression.
This is done to enable the introduction of `keySpan` and `valueSpan` in
subsequent PR.

For a detailed explanation of this work and the subsequent work items,
please see https://docs.google.com/document/d/1mEVF2pSSMSnOloqOPQTYNiAJO0XQxA1H0BZyESASOrE/edit?usp=sharing

PR Close #35812
2020-03-05 16:04:42 -05:00
78f968b7dd fix(docs-infra): in 404 page some text is not visible (#35866)
In pr #34978 colors were not properly set, if we type wrong url in the browser and we are directed to the 404 page there some text is set to white color which as not visible set it to dark gray for visibility

PR Close #35866
2020-03-05 16:00:53 -05:00
2eaf420bdf perf(ngcc): reduce directory traversing (#35756)
This reduces the time that `findEntryPoints` takes from 9701.143ms to 4177.278ms, by reducing the file operations done.

Reference: #35717

PR Close #35756
2020-03-05 15:57:31 -05:00
07efe2a6aa build: fix integration tests flakes using local yarn cache for bazel-schematics & ng_elements_schematics demos (#35877)
ng_update_migrations will still access the global yarn cache on its `ng update` call and there is no way to avoid this that I can see but if no other integration tests access the global yarn cache then that one test can have free reign over it.

PR Close #35877
2020-03-05 15:30:20 -05:00
773d7b86aa fix(router): state data missing in routerLink (#33203)
Fixes 33173

PR Close #33203
2020-03-04 16:51:14 -05:00
9de9227de3 release: cut the v9.0.5 release 2020-03-04 11:12:22 -08:00
6c5ddb2649 Revert "build(docs-infra): use local version of Zone.js when testing against local packages (#35780)" (#35857)
This reverts commit 7d832ae1001b6264bb7124086089e9e69c10c9b6; breaks CI
with error `Concurrent upstream jobs persisted the same file(s) into the workspace:`

PR Close #35857
2020-03-04 10:57:37 -08:00
7a822d2dca Revert "fix(animations): process shorthand margin and padding styles correctly (#35701)" (#35847)
This reverts commit 35c9f0dc2f, breaks
internal tests

PR Close #35847
2020-03-04 18:22:10 +00:00
26dbefd11a Revert "fix(animations): allow computeStyle to work on elements created in Node (#35810)" (#35847)
This reverts commit 17cf04ebea6a7d2857881c13140af4ba0ffb6990;
breaking internal tests.

PR Close #35847
2020-03-04 18:22:10 +00:00
6f6bfcb01c build(docs-infra): ensure that CLI options are included in search (#35801)
PR Close #35801
2020-03-04 08:48:59 -08:00
07ab0ee04c style(docs-infra): format files (#35801)
PR Close #35801
2020-03-04 08:48:59 -08:00
5d6ead4e23 build(docs-infra): use local version of Zone.js when testing against local packages (#35780)
In some cases, we want to test the AIO app or docs examples against the
locally built Angular packages (for example to ensure that the changes
in a commit do not introduce a breaking change). In order to achieve
this, we have the `ng-packages-installer` script that handles updating
a project's `package.json` file to use the locally built Angular
packages (and appropriate versions for their (dev-/peer-)dependencies).

Previously, `ng-packages-installer` would only consider the locally
built Angular packages (from `dist/packages-dist/`). However, given that
Zone.js is now part of the `angular/angular` repo, it makes sense to
also use the locally built Zone.js package (from `dist/zone.js-dist/`).
Otherwise, the tests might fail for commits that update both the Angular
packages (and related docs examples) and the Zone.js package. An example
of such a simultaneous change (that would have broken tests) is #33838.

This commit updates the script to install the locally built Zone.js
package (in addition to the Angular ones). The commit ensures that the
Zone.js package will always be available alongside the Angular packages
(i.e. that the Zone.js package will be built by the same script that
builds the Angular packages and that the `dist/zone.js-dist/` directory
will be cached on CI).

Note: This problem was discovered while enabling docs examples unit
tests in #34374.

PR Close #35780
2020-03-04 08:35:27 -08:00
b03aa7e279 refactor(docs-infra): simplify NgPackagesInstaller and speed up local package detection (#35780)
Previously, `NgPackagesInstaller` would only look for Angular local
packages and do so by listing all (deeply nested) files in
`dist/packages-dist/` and looking for `package.json` files nested two
levels deep (i.e. `dist/packages-dist/*/package.json`). Thus, it would
unnecessarily check a large number of files.

This commit changes the package detection logic to instead look for
a `package.json` file directly inside each subdirectory of
`dist/packages-dist/`, which speeds up the operation.
It also refactors the code to make it easier to look for packages in
other directories (besides `dist/packages-dist/`). This will be useful
in a subsequent commit to look for and use the locally built `zone.js`
package (from `dist/zone.js-dist/`).

PR Close #35780
2020-03-04 08:35:27 -08:00
b5b33e0361 build: move build scripts to dedicated directory (#35780)
This commit moves the build-related scripts
(`build-ivy-npm-packages.js`, `build-packages-dist.js` and
`package-builder.js`) to a dedicated directory to keep the `scripts/`
directory cleaner.

It also moves the logic for building the `zone.js` package to a separate
script, `zone-js-builder.js`, to make it re-usable. A subsequent commit
will use it to build the `zone.js` package when building the Ivy Angular
packages as well.

PR Close #35780
2020-03-04 08:35:27 -08:00
42ffab630c docs: remove ivy and mention ve label in docs (#35809)
This is a follow-up to #35799.

PR Close #35809
2020-03-04 08:34:54 -08:00
d2d4225ce6 Revert "fix(core): log error instead of warning for unknown properties and elements (#35798)" (#35845)
This reverts commit 00f3c58bb9.
Rolling back because it could be breaking e2e tests that assert that
there are no errors in the console after the assertions have run. We can
re-add this in v10.

PR Close #35845
2020-03-03 16:02:59 -08:00
218e82ebb4 fix(core): log error instead of warning for unknown properties and elements (#35798)
Changes the Ivy unknown element/property messages from being logged with `console.warn` to `console.error`. This should make them a bit more visible without breaking existing apps. Furthermore, a lot of folks filter out warning messages in the dev tools' console, whereas errors are usually still shown.

Fixes #35699.

PR Close #35798
2020-03-03 13:55:23 -08:00
12072954de fix(compiler): type-checking error for duplicate variables in templates (#35674)
It's an error to declare a variable twice on a specific template:

```html
<div *ngFor="let i of items; let i = index">
</div>
```

This commit introduces a template type-checking error which helps to detect
and diagnose this problem.

Fixes #35186

PR Close #35674
2020-03-03 13:52:50 -08:00
1980d69ec3 fix(core): unable to NgModuleRef.injector in module constructor (#35731)
This is a follow up to #35637 which resolved a similar issue for `ComponentFactoryResolver`, but not the root cause. When a `NgModuleRef` is created, it instantiates an `Injector` internally which in turn resolves all of injector types. This can result in a circular call that results in an error, because the module is one of the injector types being resolved.

These changes work around the issue by allowing the constructor to run before resolving the injector types.

Fixes #35677.
Fixes #35639.

PR Close #35731
2020-03-03 13:51:51 -08:00
2b63b7f15f fix(animations): allow computeStyle to work on elements created in Node (#35810)
This patch is a follow-up patch to 35c9f0dc2f.
It changes the `computeStyle` function to handle situations where
non string based values are returned from `window.getComputedStyle`.
This situation usually ocurrs in Node-based test environments where
the element or `window.getComputedStyle` is mocked out.

PR Close #35810
2020-03-03 13:38:26 -08:00
3fdd304b03 perf(ngcc): only create tasks for non-processed formats (#35719) (#35832)
Change the behaviour in `analyzeEntryPoints` to only create tasks for non-processed formats.

PR Close #35719

PR Close #35832
2020-03-03 13:35:48 -08:00
525dc6a036 perf(ngcc): spawn workers lazily (#35719) (#35832)
With this change we spawn workers lazily based on the amount of work that needs to be done.

Before this change we spawned the maximum of workers possible. However, in some cases there are less tasks than the max number of workers which resulted in created unnecessary workers

Reference: #35717

PR Close #35719

PR Close #35832
2020-03-03 13:35:48 -08:00
12e52a7696 Revert "build: update to rules_nodejs 1.4.0 (#35813)" (#35836)
This reverts commit fc59d841a9.

PR Close #35836
2020-03-03 11:09:33 -08:00
8abde5c49c Revert "docs: add comment markers for internal goog.define replacement (#32795)" (#35830)
This reverts commit 32b6c2285e as this is
no longer used.

PR Close #35830
2020-03-03 09:34:17 -08:00
e6d7f2022e build: no longer run tslint from within gulp task (#35800)
Switches our tslint setup to the standard `tslint.json` linter excludes.
The set of files that need to be linted is specified through a Yarn script.

For IDEs, open files are linted with the closest tslint configuration, if the
tslint IDE extension is set up, and the source file is not excluded.

We cannot use the language service plugin for tslint as we have multiple nested
tsconfig files, and we don't want to add the plugin to each tsconfig. We
could reduce that bloat by just extending from a top-level tsconfig that
defines the language service plugin, but unfortunately the tslint plugin does
not allow the use of tslint configs which are not part of the tsconfig project.

This is problematic since the tslint configuration is at the project root, and we
don't want to copy tslint configurations next to each tsconfig file.

Additionally, linting of `d.ts` files has been re-enabled. This has been
disabled in the past and a TODO has been left. This commit fixes the
lint issues and re-enables linting.

PR Close #35800
2020-03-03 09:20:49 -08:00
8d51691c42 build: update tslint to latest version (#35800)
The old version we currently use does not properly implement the
option to exclude files from within the `tslint.json` file.

PR Close #35800
2020-03-03 09:20:49 -08:00
b85ec051fb build: fix flakiness in integration/bazel-schematics by disabling symlinked_node_modules (#35808)
Because the WORKSPACE file is generated JIT by schematics in this integration test, we need to patch the schematics to add the work-around.

PR Close #35808
2020-03-03 09:19:32 -08:00
9ab42c970e build: avoid running duplicate tests in language service (#35816)
The test libs should only be included in one jasmine_node_test
otherwise `bazel build //packages/language-service/...` would
end up running `feature_test` and `infra_test` twice.

PR Close #35816
2020-03-03 08:59:37 -08:00
cebb674f6e fix(docs-infra): add top level folders into topLevelFolders (#35815)
Closes #35676

PR Close #35815
2020-03-03 08:59:10 -08:00
fc59d841a9 build: update to rules_nodejs 1.4.0 (#35813)
This brings in the 'silent' attribute in rollup_bundle to allow the suppression of verbose output in the zone.js package build.

PR Close #35813
2020-03-03 08:58:26 -08:00
a07917bd22 perf(core): add micro benchmark for destroy hook invocation (#35784)
Adds a micro benchmark which excercises the logic that invokes `ngOnDestroy` hooks.

PR Close #35784
2020-03-03 08:57:58 -08:00
89901e4ccb docs(common): switch HTTP guide examples to TestBed.inject() (#35777)
`TestBed.get()` has been [deprecated in v9][1], in favor of
`TestBed.inject()`. In ##32382, the HTTP guide wording has been updated
to mention `TestBed.inject()` instead of `TestBed.get()`, but the
associated code snippets (extracted from the `http` example) were not.

This commit updates the HTTP guide examples to also use
`TestBed.inject()`.

[1]: https://v9.angular.io/guide/deprecations#testing

Fixes #35609

PR Close #35777
2020-03-03 08:57:18 -08:00
bcff8739a7 feat(language-service): modularize error messages (#35678)
This commit performs a modularization of the Language Service's existing
diagnostic messages. Such a modularization has two primary advantages:

- Centralization and decoupling of error messages from the code that
  generates them makes it easy to add/delete/edit diagnostic messages,
  and allows for independent iteration of diagnostic messages and
  diagnostic generation.
- Prepares for additional features like annotating the locations where a
  diagnostic is generated and enabling the configuration of which
  diagnostics should be reported by the language service.

Although it would be preferable to place the diagnostics registry in an
independent JSON file, for ease of typing diagnostic types as an enum
variant of 'ts.DiagnosticCategory', the registry is stored as an object.

Part of #32663.

PR Close #35678
2020-03-03 08:49:34 -08:00
54288401f2 docs: fix docs and associated code snippets for enabling more macro tasks in fakeAsync() (#35778)
In the `testing` guide, there is a section discussing configuring
`fakeAsync()` to handle more macro tasks (e.g.
`HTMLCanvasElement#toBlob()`).

Previously, the corresponding code snippets (some of which were
hard-coded in the guide) were incorrect/incomplete and the associated
tests were broken. This was discovered while enabling docs examples unit
tests in #34374.

This commit fixes the code snippets and associated tests and ensures the
examples used in the guide come from an example app (i.e. are not
hard-coded).

Note: The docs examples unit tests are currently not run on CI. This
will be fixed in #34374.

PR Close #35778
2020-03-02 13:30:26 -08:00
371a973e5e build: fix flakiness in integration/bazel by disabling symlinked_node_modules (#35804)
The flakiness in integration/bazel-schematics is going to be a bit tricker as the WORKSPACE file is JIT generated by the architect build layer

PR Close #35804
2020-03-02 13:29:57 -08:00
710fca2b8e style: Remove ivy scope, and add ve scope (#35799)
Since ivy is now default having `ivy` scope does not make sense. We are creating `ve` scope for cases where we are specifically fixing view-engine.

NOTE: Also sorted scopes alphabetically.

PR Close #35799
2020-03-02 11:25:36 -08:00
120ce42ac2 fix(core): allow null / undefined values in query results (#35796)
Before this change ngIvy implementation of queries would throw upon
encountering null / undefined query result collected from an embedded
view. It turns out that we might have a provider that explicitly provides
a null / undefined value in a place of a token queried for.

This commit removes a check from the ngIvy query implementation that was
asserting on a query result to be defined.

Fixes #35673

PR Close #35796
2020-03-02 11:16:22 -08:00
1503408a3d docs: reword explanation for using singleton services decorative to be more understandable (#35002)
To understand the current sentence it requires to read it multiple times.
This fix should help developers to understand the sentence in a quicker way.

PR Close #35002
2020-03-02 09:30:54 -08:00
48025eb3e8 fix(core): treat [class] and [className] as unrelated bindings (#35668)
Before this change `[class]` and `[className]` were both converted into `ɵɵclassMap`. The implication of this is that at runtime we could not differentiate between the two and as a result we treated `@Input('class')` and `@Input('className)` as equivalent.

This change makes `[class]` and `[className]` distinct. The implication of this is that `[class]` becomes `ɵɵclassMap` instruction but  `[className]` becomes `ɵɵproperty' instruction. This means that `[className]` will no longer participate in styling and will overwrite the DOM `class` value.

Fix #35577

PR Close #35668
2020-03-02 08:18:59 -08:00
11c2e8c14d style: Reformat test comment for line breaks (#35668)
PR Close #35668
2020-03-02 08:18:59 -08:00
d1966fc29b fix(compiler): support i18n attributes on <ng-template> tags (#35681)
Prior to this commit, i18n attributes defined on `<ng-template>` tags were not processed by the compiler. This commit adds the necessary logic to handle i18n attributes in the same way how these attrs are processed for regular elements.

PR Close #35681
2020-03-02 08:18:06 -08:00
2e251b7d2e fix(animations): process shorthand margin and padding styles correctly (#35701)
Prior to this patch, the `margin` and `padding` properties were not
detected properly by Firefox due to them being shorthand properties.
This patch ensures that both `margin` and `padding` are converted
read as `top right bottom left` in the event that the shorthand
property detection fails for auto-styling in Angular animations.

Fix #35463 (FW-1886)

PR Close #35701
2020-03-02 08:17:38 -08:00
d035747247 test(docs-infra): add proxy to fake images in tests (#35741)
Previously, when running the unit tests for aio on Windows, many 404s
are logged for images, resulting in progress logs being spread over
multiple lines. This commit fixes this by adding a `proxy` to point
the fake image to a real image within the `src` folder.

Closes #29775

PR Close #35741
2020-03-02 08:16:35 -08:00
532bcc0f67 docs: Fix typo in template syntax (#35767)
Remove unnecessary article from styling precedence

PR Close #35767
2020-03-02 08:16:07 -08:00
c272351282 fix(bazel): ng_package rule creates incorrect UMD module exports (#35792)
The `ng_package` rule currently creates incorrect UMD module exports
if an entry-point has a module name with numbers included.

For example, consider an entry-point called `@angular/cdk/a11y`. The UMD
module name should be `ng.cdk.a11y`. Instead, `ng_package` currently generates
an UMD module export called `ng.cdk.a11Y`.

This is because the logic for converting dash-case to camel case is
invalid as it uses Starlark's `title()` method. The title method
converts text to title case while we actually just want to capitalize
the first letter of a dash-case segment.

Fixes angular/components#18652.

PR Close #35792
2020-03-02 08:15:02 -08:00
f3bbfa4284 test: add entry-point with numbers in name to ng_package test (#35792)
Adds a new entry-point to the `@angular/bazel` `ng_package` test that
contains numbers in the name. e.g. `example/a11y`. This test is added
to replicate a bug where the UMD module export for such entry-points
is incorrectly generated. i.e. `example.a11Y` is generated instead of
`example.a11y`.

PR Close #35792
2020-03-02 08:15:02 -08:00
e13fcbaa6f perf(core): use multiple directives in host bindings micro benchmark (#35736)
This commit updates the host bindings micro benchmark to run tests with mutliple directives (where each directive contains host bindings). The number of directives is configurable as a constant in the micro benchmark file. This change is needed to have an ability to measure/compare perf in different scenarios.

PR Close #35736
2020-02-28 12:26:44 -08:00
5a14a15e32 fix(core): handle <ng-template> with local refs in i18n blocks (#35758)
This commit extends the range of tNode types that may have local refs to include `TNodeType.Container` to account for `<ng-template>`s. Original changes in https://github.com/angular/angular/pull/33415 didn't include that type and as a result, an error is thrown at runtime in case an i18n block contains an `<ng-template>` with local refs.

PR Close #35758
2020-02-28 12:25:11 -08:00
d3ee052ee4 fix(core): Remove debugger statement when assert is thrown (#35763)
Fix #35470
Fix FW-1925

PR Close #35763
2020-02-28 12:23:51 -08:00
e201a84f59 fix(core): Remove debugger statement (#35763)
Fix #35470

PR Close #35763
2020-02-28 12:23:51 -08:00
fcad075ade fix(ivy): narrow NgIf context variables in template type checker (#35125)
When the `NgIf` directive is used in a template, its context variables
can be used to capture the bound value. This is typically used together
with a pipe or function call, where the resulting value is captured in a
context variable. There's two syntax forms available:

1. Binding to `NgIfContext.ngIf` using the `as` syntax:
```html
<span *ngIf="(user$ | async) as user">{{user.name}}</span>
```

2. Binding to `NgIfContext.$implicit` using the `let` syntax:
```html
<span *ngIf="user$ | async; let user">{{user.name}}</span>
```

Because of the semantics of `ngIf`, it is known that the captured
context variable is non-nullable, however the template type checker
would not consider them as such and still report errors when
`strictNullTypes` is enabled.

This commit updates `NgIf`'s context guard to make the types of the
context variables non-nullable, avoiding the issue.

Fixes #34572

PR Close #35125
2020-02-28 07:39:57 -08:00
30ae8805af refactor(compiler): Remove NullAstVisitor and visitAstChildren (#35619)
This commit removes the `NullAstVisitor` and `visitAstChildren` exported
from `packages/compiler/src/expression_parser/ast.ts` because they
contain duplicate and buggy implementation, and their use cases could be
sufficiently covered by `RecursiveAstVisitor` if the latter implements the
`visit` method. This use case is only needed in the language service.

With this change, any visitor that extends `RecursiveAstVisitor` could
just define their own `visit` function and the parent class will behave
correctly.

A bit of historical context:
In language service, we need a way to tranverse the expression AST in a
selective manner based on where the user's cursor is. This means we need a
"filtering" function to decide which node to visit and which node to not
visit. Instead of refactoring `RecursiveAstVisitor` to support this,
`visitAstChildren` was created. `visitAstChildren` duplicates the
implementation of `RecursiveAstVisitor`, but introduced some bugs along
the way. For example, in `visitKeyedWrite`, it visits
```
obj -> key -> obj
```
instead of
```
obj -> key -> value
```

Moreover, because of the following line
```
visitor.visit && visitor.visit(ast, context) || ast.visit(visitor, context);
```
`visitAstChildren` visits every node *twice*.

PR Close #35619
2020-02-28 07:13:18 -08:00
657d98d9b2 fix(docs-infra): fix redirect in angular version selector (#35632)
Closes #35630

PR Close #35632
2020-02-28 07:11:34 -08:00
24f48ed97f test(language-service): differentiate feature and internal infra tests (#35688)
This commit differentiates language service feature and language service
infrastructure tests. This is primarily to make testing of different
components at the development level easier. This commit continues a
small effort to expand our test coverage and normalize testing
structure.

Also adds test coverage to language service tests. We have quite a bit
to go on that front 🙂.

PR Close #35688
2020-02-28 07:10:46 -08:00
d0c26f4bfa ci: bump CircleCI cache version prefix (#35711)
The changes to yarn.lock for the `$localize` typings
support are not filtering through because the cache
contains nested packages that are causing compilation
errors.

This change will force the cache to invalidate and allows
us to have a clean node_modules folder.

PR Close #35711
2020-02-28 07:09:51 -08:00
6279117058 build: enable IDE type checking of $localize code (#35711)
The `packages/localize/src/tools` folder was excluded
from the top level `tsconfig.json` which meant that in IDEs
these source files were not being given the correct configuration.
It was originally excluded because it required the native `node` typings
but this is no longer a requirement.

Removing this folder from the exclusion list exposed a new issue
where there was a typings mismatch between `@babel/...` sources
and the associated `@types/babel__...` typings packages.

A clean up of the package.json and yarn.lock appears to fix this.

PR Close #35711
2020-02-28 07:09:51 -08:00
52fc08754d fix(ivy): support dynamic query tokens in AOT mode (#35307)
For view and content queries, the Ivy compiler attempts to statically
evaluate the predicate token so that string predicates containing
comma-separated reference names can be split into an array of strings
during compilation. When the predicate is a dynamic value that cannot be
statically interpreted at compile time, the compiler would previously
produce an error. This behavior breaks a use-case where an `InjectionToken`
is being used as query predicate, as the usage of the `new` keyword
prevents such predicates from being statically evaluated.

This commit changes the behavior to no longer produce an error for
dynamic values. Instead, the expression is emitted as is into the
generated code, postponing the evaluation to happen at runtime.

Fixes #34267
Resolves FW-1828

PR Close #35307
2020-02-27 16:05:22 -08:00
287d841486 build: allow auto-discover all typings files in npm package by ts-api-guardian (#35691)
Adds a new feature to ts-api-guardian allowing for automatically discovering all
entry point d.ts files from all package.json files in a provided directory.

PR Close #35691
2020-02-27 14:02:17 -08:00
df0859f7e1 fix(core): use proper configuration to compile Injectable in JIT (#35706)
Prior to this change, the logic that compiles Injectable in JIT mode used incorrect configuration that triggers a problem when `ChangeDetectorRef` is used as a dependency. This commit updates the logic to generate correct inject instruction to add the `ChangeDetectorRef` dependency in case it's requested in @Injectable class.

PR Close #35706
2020-02-27 14:01:16 -08:00
4ec7cd12c0 perf(core): adding micro benchmark for host bindings (#35705)
This commit adds micro benchmark for host bindings, so that we can assess the impact of changes related to host bindings (for example PR #35568).

PR Close #35705
2020-02-27 13:59:57 -08:00
d06b6de409 release: cut the v9.0.4 release 2020-02-27 13:42:19 -08:00
9b53054ea8 refactor(ngcc): guard against a crash if source-map flattening fails (#35718)
Source-maps in the wild could be badly formatted,
causing the source-map flattening processing to fail
unexpectedly. Rather than causing the whole of ngcc
to crash, we gracefully fallback to just returning the
generated source-map instead.

PR Close #35718
2020-02-27 16:09:37 -05:00
bfe7657006 fix(ngcc): handle mappings outside the content when flattening source-maps (#35718)
Previously when rendering flattened source-maps, it was assumed that no
mapping would come from a line that is outside the lines of the actual
source content. It turns out this is not a valid assumption.

Now the code that renders flattened source-maps will handle such
mappings, with the additional benefit that the rendered source-map
will only contain mapping lines up to the last mapping, rather than a
mapping line for every content line.

Fixes #35709

PR Close #35718
2020-02-27 16:09:37 -05:00
7ff845b72f fix(ngcc): handle missing sources when flattening source-maps (#35718)
If a package has a source-map but it does not provide
the actual content of the sources, then the source-map
flattening was crashing.

Now we ignore such mappings that have no source
since we are not able to compute the merged
mapping if there is no source file.

Fixes #35709

PR Close #35718
2020-02-27 16:09:37 -05:00
bf6fbf5a74 feat(docs-infra): add useful links if landed on 404 page and no search results found (#34978)
Added additional links which can help user find the things they are
looking for when there are no search results (when searching or on a 404
page).

Note:
This commit increases the main bundle's payload size due to the extra
content of the `aio-search-results` component.

Fixes #31532

PR Close #34978
2020-02-27 11:02:00 -08:00
e4f05d1952 ci(docs-infra): increase AIO ViewEngine payload size limit (#34978)
In #35702, the payload size limit for Ivy builds was bumped to account
for small incremental increases in recent PRs. The ViewEngine size has
also increased similarly (~500B), but it was not updated in #35702,
because its total increase was just below the 500B error threshold (by
6B).

This commit bumps the ViewEngine size limit too.

Note: Any investigation for the Ivy size increase (as a follow-up
to #35702) will most likely also apply to ViewEngine, since the size was
increased by the same amount.

PR Close #34978
2020-02-27 11:01:59 -08:00
f11fc1e3bd docs: correct spelling of 'detection' (#35723)
PR Close #35723
2020-02-27 10:49:16 -08:00
9064f4ecdb fix(ngcc): allow deep-import warnings to be ignored (#35683)
This commit adds a new ngcc configuration, `ignorableDeepImportMatchers`
for packages. This is a list of regular expressions matching deep imports
that can be safely ignored from that package. Deep imports that are not
ignored cause a warning to be logged.

// FW-1892

Fixes #35615

PR Close #35683
2020-02-27 10:48:49 -08:00
0eda98a28b test(docs-infra): fix tests with new topics property (#35539)
PR Close #35539
2020-02-27 10:47:52 -08:00
60921e8efd feat(docs-infra): add searchKeywords preprocessor (#35539)
This commit adds a new preprocessor to use `${@searchKeywords}`, allowing
the docs to use a list of custom search phrases that will be
prioritized over the keywords found in the content.

Closes #35449

PR Close #35539
2020-02-27 10:47:52 -08:00
261 changed files with 9058 additions and 3348 deletions

View File

@ -22,14 +22,14 @@ version: 2.1
# **NOTE 1 **: If you change the cache key prefix, also sync the cache_key_fallback to match. # **NOTE 1 **: If you change the cache key prefix, also sync the cache_key_fallback to match.
# **NOTE 2 **: Keep the static part of the cache key as prefix to enable correct fallbacks. # **NOTE 2 **: Keep the static part of the cache key as prefix to enable correct fallbacks.
# See https://circleci.com/docs/2.0/caching/#restoring-cache for how prefixes work in CircleCI. # See https://circleci.com/docs/2.0/caching/#restoring-cache for how prefixes work in CircleCI.
var_3: &cache_key v3-angular-node-12-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "packages/bazel/package.bzl" }}-{{ checksum "aio/yarn.lock" }} var_3: &cache_key v4-angular-node-12-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "packages/bazel/package.bzl" }}-{{ checksum "aio/yarn.lock" }}
var_4: &cache_key_fallback v3-angular-node-12- var_4: &cache_key_fallback v4-angular-node-12-
var_3_win: &cache_key_win v5-angular-win-node-12-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "packages/bazel/package.bzl" }}-{{ checksum "aio/yarn.lock" }} var_3_win: &cache_key_win v5-angular-win-node-12-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "packages/bazel/package.bzl" }}-{{ checksum "aio/yarn.lock" }}
var_4_win: &cache_key_win_fallback v5-angular-win-node-12- var_4_win: &cache_key_win_fallback v5-angular-win-node-12-
# 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 v5-angular-components-2ec7254f88c4865e0de251f74c27e64c9d00d40a var_5: &components_repo_unit_tests_cache_key v5-angular-components-598db096e668aa7e9debd56eedfd127b7a55e371
var_6: &components_repo_unit_tests_cache_key_fallback v5-angular-components- var_6: &components_repo_unit_tests_cache_key_fallback v5-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
@ -274,7 +274,7 @@ jobs:
- run: 'yarn bazel:lint || - run: 'yarn bazel:lint ||
(echo -e "\n.bzl files have lint errors. Please run ''yarn bazel:lint-fix''"; exit 1)' (echo -e "\n.bzl files have lint errors. Please run ''yarn bazel:lint-fix''"; exit 1)'
- run: yarn gulp lint - run: yarn lint
- run: node tools/pullapprove/verify.js - run: node tools/pullapprove/verify.js
test: test:
@ -465,12 +465,14 @@ jobs:
- when: - when:
condition: << parameters.ivy >> condition: << parameters.ivy >>
steps: steps:
# Rename the Ivy packages dist folder to "dist/packages-dist" as the AIO # Rename the "dist/*-dist-ivy-aot" packages directories (persisted to the workspace by
# package installer picks up the locally built packages from that location. # the `build-ivy-npm-packages` job) to "dist/*-dist" as the AIO package installer
# picks up the locally built packages from that location.
# *Note*: We could also adjust the packages installer, but given we won't have # *Note*: We could also adjust the packages installer, but given we won't have
# two different folders of Angular distributions in the future, we should keep # two different folders of Angular distributions in the future, we should keep
# the packages installer unchanged. # the packages installer unchanged.
- run: mv dist/packages-dist-ivy-aot dist/packages-dist - run: mv dist/packages-dist-ivy-aot dist/packages-dist
- run: mv dist/zone.js-dist-ivy-aot dist/zone.js-dist
# Run examples tests. The "CIRCLE_NODE_INDEX" will be set if "parallelism" is enabled. # Run examples tests. The "CIRCLE_NODE_INDEX" will be set if "parallelism" is enabled.
# Since the parallelism is set to "5", there will be five parallel CircleCI containers. # Since the parallelism is set to "5", there will be five parallel CircleCI containers.
# with either "0", "1", etc as node index. This can be passed to the "--shard" argument. # with either "0", "1", etc as node index. This can be passed to the "--shard" argument.
@ -520,7 +522,7 @@ jobs:
steps: steps:
- custom_attach_workspace - custom_attach_workspace
- init_environment - init_environment
- run: node scripts/build-packages-dist.js - run: node scripts/build/build-packages-dist.js
# Save the npm packages from //packages/... for other workflow jobs to read # Save the npm packages from //packages/... for other workflow jobs to read
- persist_to_workspace: - persist_to_workspace:
@ -545,13 +547,14 @@ jobs:
steps: steps:
- custom_attach_workspace - custom_attach_workspace
- init_environment - init_environment
- run: node scripts/build-ivy-npm-packages.js - run: node scripts/build/build-ivy-npm-packages.js
# Save the npm packages from //packages/... for other workflow jobs to read # Save the npm packages from //packages/... for other workflow jobs to read
- persist_to_workspace: - persist_to_workspace:
root: *workspace_location root: *workspace_location
paths: paths:
- ng/dist/packages-dist-ivy-aot - ng/dist/packages-dist-ivy-aot
- ng/dist/zone.js-dist-ivy-aot
# We run a subset of the integration tests outside of Bazel that track # We run a subset of the integration tests outside of Bazel that track
# payload size. # payload size.

View File

@ -68,7 +68,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 "2ec7254f88c4865e0de251f74c27e64c9d00d40a" setPublicVar COMPONENTS_REPO_COMMIT "598db096e668aa7e9debd56eedfd127b7a55e371"
#################################################################################################### ####################################################################################################

View File

@ -546,7 +546,6 @@ groups:
conditions: conditions:
- > - >
contains_any_globs(files, [ contains_any_globs(files, [
'modules/benchmarks_external/**',
'modules/benchmarks/**' 'modules/benchmarks/**'
]) ])
reviewers: reviewers:
@ -928,6 +927,7 @@ groups:
'.github/**', '.github/**',
'.vscode/**', '.vscode/**',
'.yarn/**', '.yarn/**',
'dev-infra/**',
'docs/BAZEL.md', 'docs/BAZEL.md',
'docs/CARETAKER.md', 'docs/CARETAKER.md',
'docs/COMMITTER.md', 'docs/COMMITTER.md',
@ -952,6 +952,7 @@ groups:
'tools/browsers/**', 'tools/browsers/**',
'tools/build/**', 'tools/build/**',
'tools/circular_dependency_test/**', 'tools/circular_dependency_test/**',
'tools/contributing-stats/**',
'tools/gulp-tasks/**', 'tools/gulp-tasks/**',
'tools/ng_rollup_bundle/**', 'tools/ng_rollup_bundle/**',
'tools/ngcontainer/**', 'tools/ngcontainer/**',

View File

@ -1,3 +1,81 @@
<a name="9.0.6"></a>
## [9.0.6](https://github.com/angular/angular/compare/9.0.5...9.0.6) (2020-03-11)
### Bug Fixes
* **bazel:** do not use manifest paths for generated imports within compilation unit ([#35841](https://github.com/angular/angular/issues/35841)) ([5ea9a61](https://github.com/angular/angular/commit/5ea9a61))
* **compiler:** process `imports` first and `declarations` second while calculating scopes ([#35850](https://github.com/angular/angular/issues/35850)) ([6f2fd6e](https://github.com/angular/angular/commit/6f2fd6e)), closes [#35502](https://github.com/angular/angular/issues/35502)
* **core:** add `noSideEffects()` to `make*Decorator()` functions ([#35769](https://github.com/angular/angular/issues/35769)) ([#35846](https://github.com/angular/angular/issues/35846)) ([4fe3f37](https://github.com/angular/angular/commit/4fe3f37))
* **core:** add `noSideEffects()` to `ɵɵdefineComponent()` ([#35769](https://github.com/angular/angular/issues/35769)) ([#35846](https://github.com/angular/angular/issues/35846)) ([68ca32f](https://github.com/angular/angular/commit/68ca32f))
* **core:** remove side effects from `ɵɵgetInheritedFactory()` ([#35769](https://github.com/angular/angular/issues/35769)) ([#35846](https://github.com/angular/angular/issues/35846)) ([000c834](https://github.com/angular/angular/commit/000c834))
* **core:** remove side effects from `ɵɵNgOnChangesFeature()` ([#35769](https://github.com/angular/angular/issues/35769)) ([#35846](https://github.com/angular/angular/issues/35846)) ([d24ce21](https://github.com/angular/angular/commit/d24ce21))
* **core:** undecorated-classes-with-di migration should handle libraries generated with CLI versions past v6.2.0 ([#35824](https://github.com/angular/angular/issues/35824)) ([eaf5b58](https://github.com/angular/angular/commit/eaf5b58)), closes [#34985](https://github.com/angular/angular/issues/34985)
* **language-service:** resolve the variable from the template context first ([#35982](https://github.com/angular/angular/issues/35982)) ([f882ff0](https://github.com/angular/angular/commit/f882ff0))
* **localize:** improve matching and parsing of XLIFF 1.2 translation files ([#35793](https://github.com/angular/angular/issues/35793)) ([677d666](https://github.com/angular/angular/commit/677d666))
* **localize:** improve matching and parsing of XLIFF 2.0 translation files ([#35793](https://github.com/angular/angular/issues/35793)) ([689964b](https://github.com/angular/angular/commit/689964b))
* **localize:** improve matching and parsing of XTB translation files ([#35793](https://github.com/angular/angular/issues/35793)) ([9f68ff9](https://github.com/angular/angular/commit/9f68ff9))
* **localize:** merge translation from all XLIFF `<file>` elements ([#35936](https://github.com/angular/angular/issues/35936)) ([83d7819](https://github.com/angular/angular/commit/83d7819)), closes [#35839](https://github.com/angular/angular/issues/35839)
* **platform-browser:** add missing peerDependency on `[@angular](https://github.com/angular)/animations` ([#35949](https://github.com/angular/angular/issues/35949)) ([db9704a](https://github.com/angular/angular/commit/db9704a)), closes [#35888](https://github.com/angular/angular/issues/35888)
* **router:** state data missing in routerLink ([#33203](https://github.com/angular/angular/issues/33203)) ([773d7b8](https://github.com/angular/angular/commit/773d7b8))
### Performance Improvements
* **ngcc:** reduce directory traversing ([#35756](https://github.com/angular/angular/issues/35756)) ([2eaf420](https://github.com/angular/angular/commit/2eaf420)), closes [#35717](https://github.com/angular/angular/issues/35717)
<a name="9.0.5"></a>
## [9.0.5](https://github.com/angular/angular/compare/9.0.4...9.0.5) (2020-03-04)
### Bug Fixes
* **animations:** allow computeStyle to work on elements created in Node ([#35810](https://github.com/angular/angular/issues/35810)) ([2b63b7f](https://github.com/angular/angular/commit/2b63b7f))
* **animations:** process shorthand `margin` and `padding` styles correctly ([#35701](https://github.com/angular/angular/issues/35701)) ([2e251b7](https://github.com/angular/angular/commit/2e251b7)), closes [#35463](https://github.com/angular/angular/issues/35463)
* **bazel:** ng_package rule creates incorrect UMD module exports ([#35792](https://github.com/angular/angular/issues/35792)) ([c272351](https://github.com/angular/angular/commit/c272351)), closes [angular/components#18652](https://github.com/angular/components/issues/18652)
* **compiler:** support i18n attributes on `<ng-template>` tags ([#35681](https://github.com/angular/angular/issues/35681)) ([d1966fc](https://github.com/angular/angular/commit/d1966fc))
* **compiler:** type-checking error for duplicate variables in templates ([#35674](https://github.com/angular/angular/issues/35674)) ([1207295](https://github.com/angular/angular/commit/1207295)), closes [#35186](https://github.com/angular/angular/issues/35186)
* **core:** allow null / undefined values in query results ([#35796](https://github.com/angular/angular/issues/35796)) ([120ce42](https://github.com/angular/angular/commit/120ce42)), closes [#35673](https://github.com/angular/angular/issues/35673)
* **core:** handle `<ng-template>` with local refs in i18n blocks ([#35758](https://github.com/angular/angular/issues/35758)) ([5a14a15](https://github.com/angular/angular/commit/5a14a15))
* **core:** log error instead of warning for unknown properties and elements ([#35798](https://github.com/angular/angular/issues/35798)) ([218e82e](https://github.com/angular/angular/commit/218e82e)), closes [#35699](https://github.com/angular/angular/issues/35699)
* **core:** Remove `debugger` statement ([#35763](https://github.com/angular/angular/issues/35763)) ([e201a84](https://github.com/angular/angular/commit/e201a84)), closes [#35470](https://github.com/angular/angular/issues/35470)
* **core:** Remove `debugger` statement when assert is thrown ([#35763](https://github.com/angular/angular/issues/35763)) ([d3ee052](https://github.com/angular/angular/commit/d3ee052)), closes [#35470](https://github.com/angular/angular/issues/35470)
* **core:** treat `[class]` and `[className]` as unrelated bindings ([#35668](https://github.com/angular/angular/issues/35668)) ([48025eb](https://github.com/angular/angular/commit/48025eb)), closes [#35577](https://github.com/angular/angular/issues/35577)
* **core:** unable to NgModuleRef.injector in module constructor ([#35731](https://github.com/angular/angular/issues/35731)) ([1980d69](https://github.com/angular/angular/commit/1980d69)), closes [#35677](https://github.com/angular/angular/issues/35677) [#35639](https://github.com/angular/angular/issues/35639)
* **core:** use proper configuration to compile Injectable in JIT ([#35706](https://github.com/angular/angular/issues/35706)) ([df0859f](https://github.com/angular/angular/commit/df0859f))
* **ivy:** narrow `NgIf` context variables in template type checker ([#35125](https://github.com/angular/angular/issues/35125)) ([fcad075](https://github.com/angular/angular/commit/fcad075)), closes [#34572](https://github.com/angular/angular/issues/34572)
* **ivy:** support dynamic query tokens in AOT mode ([#35307](https://github.com/angular/angular/issues/35307)) ([52fc087](https://github.com/angular/angular/commit/52fc087)), closes [#34267](https://github.com/angular/angular/issues/34267)
### Features
* **language-service:** modularize error messages ([#35678](https://github.com/angular/angular/issues/35678)) ([bcff873](https://github.com/angular/angular/commit/bcff873)), closes [#32663](https://github.com/angular/angular/issues/32663)
### Performance Improvements
* **core:** add micro benchmark for destroy hook invocation ([#35784](https://github.com/angular/angular/issues/35784)) ([a07917b](https://github.com/angular/angular/commit/a07917b))
* **core:** adding micro benchmark for host bindings ([#35705](https://github.com/angular/angular/issues/35705)) ([4ec7cd1](https://github.com/angular/angular/commit/4ec7cd1)), closes [#35568](https://github.com/angular/angular/issues/35568)
* **core:** use multiple directives in host bindings micro benchmark ([#35736](https://github.com/angular/angular/issues/35736)) ([e13fcba](https://github.com/angular/angular/commit/e13fcba))
* **ngcc:** only create tasks for non-processed formats ([#35719](https://github.com/angular/angular/issues/35719)) ([#35832](https://github.com/angular/angular/issues/35832)) ([3fdd304](https://github.com/angular/angular/commit/3fdd304))
* **ngcc:** spawn workers lazily ([#35719](https://github.com/angular/angular/issues/35719)) ([#35832](https://github.com/angular/angular/issues/35832)) ([525dc6a](https://github.com/angular/angular/commit/525dc6a)), closes [#35717](https://github.com/angular/angular/issues/35717)
<a name="9.0.4"></a>
## [9.0.4](https://github.com/angular/angular/compare/9.0.3...9.0.4) (2020-02-27)
### Bug Fixes
* **ngcc:** allow deep-import warnings to be ignored ([#35683](https://github.com/angular/angular/issues/35683)) ([9064f4e](https://github.com/angular/angular/commit/9064f4e)), closes [#35615](https://github.com/angular/angular/issues/35615)
* **ngcc:** handle mappings outside the content when flattening source-maps ([#35718](https://github.com/angular/angular/issues/35718)) ([bfe7657](https://github.com/angular/angular/commit/bfe7657)), 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)) ([7ff845b](https://github.com/angular/angular/commit/7ff845b)), closes [#35709](https://github.com/angular/angular/issues/35709)
<a name="9.0.3"></a> <a name="9.0.3"></a>
## [9.0.3](https://github.com/angular/angular/compare/9.0.2...9.0.3) (2020-02-27) ## [9.0.3](https://github.com/angular/angular/compare/9.0.2...9.0.3) (2020-02-27)

View File

@ -232,8 +232,8 @@ There are currently a few exceptions to the "use package name" rule:
* **changelog**: used for updating the release notes in CHANGELOG.md * **changelog**: used for updating the release notes in CHANGELOG.md
* **docs-infra**: used for docs-app (angular.io) related changes within the /aio directory of the * **docs-infra**: used for docs-app (angular.io) related changes within the /aio directory of the
repo repo
* **ivy**: used for changes to the [Ivy renderer](https://github.com/angular/angular/issues/21706).
* **ngcc**: used for changes to the [Angular Compatibility Compiler](./packages/compiler-cli/ngcc/README.md) * **ngcc**: used for changes to the [Angular Compatibility Compiler](./packages/compiler-cli/ngcc/README.md)
* **ve**: used for changes specific to ViewEngine (legacy compiler/renderer).
* none/empty string: useful for `style`, `test` and `refactor` changes that are done across all * none/empty string: useful for `style`, `test` and `refactor` changes that are done across all
packages (e.g. `style: add missing semicolons`) and for docs changes that are not related to a packages (e.g. `style: add missing semicolons`) and for docs changes that are not related to a
specific package (e.g. `docs: fix typo in tutorial`). specific package (e.g. `docs: fix typo in tutorial`).

View File

@ -158,11 +158,11 @@ export class Provider6bComponent {
// #docregion silent-logger // #docregion silent-logger
// An object in the shape of the logger service // An object in the shape of the logger service
export function SilentLoggerFn() {} function silentLoggerFn() {}
const silentLogger = { export const SilentLogger = {
logs: ['Silent logger says "Shhhhh!". Provided via "useValue"'], logs: ['Silent logger says "Shhhhh!". Provided via "useValue"'],
log: SilentLoggerFn log: silentLoggerFn
}; };
// #enddocregion silent-logger // #enddocregion silent-logger
@ -171,7 +171,7 @@ const silentLogger = {
template: template, template: template,
providers: providers:
// #docregion providers-7 // #docregion providers-7
[{ provide: Logger, useValue: silentLogger }] [{ provide: Logger, useValue: SilentLogger }]
// #enddocregion providers-7 // #enddocregion providers-7
}) })
export class Provider7Component { export class Provider7Component {

View File

@ -28,9 +28,9 @@ describe('HeroesService', () => {
// Inject the http, test controller, and service-under-test // Inject the http, test controller, and service-under-test
// as they will be referenced by each test. // as they will be referenced by each test.
httpClient = TestBed.get(HttpClient); httpClient = TestBed.inject(HttpClient);
httpTestingController = TestBed.get(HttpTestingController); httpTestingController = TestBed.inject(HttpTestingController);
heroService = TestBed.get(HeroesService); heroService = TestBed.inject(HeroesService);
}); });
afterEach(() => { afterEach(() => {
@ -44,7 +44,7 @@ describe('HeroesService', () => {
let expectedHeroes: Hero[]; let expectedHeroes: Hero[];
beforeEach(() => { beforeEach(() => {
heroService = TestBed.get(HeroesService); heroService = TestBed.inject(HeroesService);
expectedHeroes = [ expectedHeroes = [
{ id: 1, name: 'A' }, { id: 1, name: 'A' },
{ id: 2, name: 'B' }, { id: 2, name: 'B' },

View File

@ -27,8 +27,8 @@ describe('HttpClient testing', () => {
}); });
// Inject the http service and test controller for each test // Inject the http service and test controller for each test
httpClient = TestBed.get(HttpClient); httpClient = TestBed.inject(HttpClient);
httpTestingController = TestBed.get(HttpTestingController); httpTestingController = TestBed.inject(HttpTestingController);
}); });
// #enddocregion setup // #enddocregion setup
// #docregion afterEach // #docregion afterEach

View File

@ -1,6 +1,21 @@
// #docplaster
// #docregion without-toBlob-macrotask
import { TestBed, async, tick, fakeAsync } 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', () => {
// #enddocregion without-toBlob-macrotask
// #docregion enable-toBlob-macrotask
beforeEach(() => {
window['__zone_symbol__FakeAsyncTestMacroTask'] = [
{
source: 'HTMLCanvasElement.toBlob',
callbackArgs: [{ size: 200 }],
},
];
});
// #enddocregion enable-toBlob-macrotask
// #docregion without-toBlob-macrotask
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [ declarations: [
@ -8,20 +23,16 @@ describe('CanvasComponent', () => {
], ],
}).compileComponents(); }).compileComponents();
})); }));
beforeEach(() => {
window['__zone_symbol__FakeAsyncTestMacroTask'] = [
{
source: 'HTMLCanvasElement.toBlob',
callbackArgs: [{ size: 200 }]
}
];
});
it('should be able to generate blob data from canvas', fakeAsync(() => { it('should be able to generate blob data from canvas', fakeAsync(() => {
const fixture = TestBed.createComponent(CanvasComponent); const fixture = TestBed.createComponent(CanvasComponent);
const canvasComp = fixture.debugElement.componentInstance;
fixture.detectChanges(); fixture.detectChanges();
expect(canvasComp.blobSize).toBe(0);
tick(); tick();
const app = fixture.debugElement.componentInstance; expect(canvasComp.blobSize).toBeGreaterThan(0);
expect(app.blobSize).toBeGreaterThan(0);
})); }));
}); });
// #enddocregion without-toBlob-macrotask

View File

@ -1,25 +1,32 @@
// #docplaster
// #docregion import-canvas-patch
// Import patch to make async `HTMLCanvasElement` methods (such as `.toBlob()`) Zone.js-aware.
// Either import in `polyfills.ts` (if used in more than one places in the app) or in the component
// file using `HTMLCanvasElement` (if it is only used in a single file).
import 'zone.js/dist/zone-patch-canvas';
// #enddocregion import-canvas-patch
// #docregion main
import { Component, AfterViewInit, ViewChild, ElementRef } from '@angular/core'; import { Component, AfterViewInit, ViewChild, ElementRef } from '@angular/core';
@Component({ @Component({
selector: 'sample-canvas', selector: 'sample-canvas',
template: '<canvas #sampleCanvas width="200" height="200"></canvas>' template: '<canvas #sampleCanvas width="200" height="200"></canvas>',
}) })
export class CanvasComponent implements AfterViewInit { export class CanvasComponent implements AfterViewInit {
blobSize: number; blobSize = 0;
@ViewChild('sampleCanvas') sampleCanvas: ElementRef; @ViewChild('sampleCanvas') sampleCanvas: ElementRef;
constructor() { }
ngAfterViewInit() { ngAfterViewInit() {
const canvas = this.sampleCanvas.nativeElement; const canvas: HTMLCanvasElement = this.sampleCanvas.nativeElement;
const context = canvas.getContext('2d'); const context = canvas.getContext('2d');
if (context) {
context.clearRect(0, 0, 200, 200); context.clearRect(0, 0, 200, 200);
context.fillStyle = '#FF1122'; context.fillStyle = '#FF1122';
context.fillRect(0, 0, 200, 200); context.fillRect(0, 0, 200, 200);
canvas.toBlob((blob: any) => {
this.blobSize = blob.size; canvas.toBlob(blob => {
}); this.blobSize = blob.size;
} });
} }
} }
// #enddocregion main

View File

@ -185,7 +185,7 @@ searchHeroes(term: string): Observable {
let heroesURL = `${this.heroesURL}?${term}`; let heroesURL = `${this.heroesURL}?${term}`;
return this.http.jsonp(heroesUrl, 'callback').pipe( return this.http.jsonp(heroesUrl, 'callback').pipe(
catchError(this.handleError('searchHeroes', []) // then handle the error catchError(this.handleError('searchHeroes', [])) // then handle the error
); );
}; };
``` ```

View File

@ -9,7 +9,7 @@ For a sample app using the app-wide singleton service that this page describes,
There are two ways to make a service a singleton in Angular: There are two ways to make a service a singleton in Angular:
* Declare `root` for the value of the `@Injectable()` `providedIn` property * Set the `providedIn` property of the `@Injectable()` to `"root"`.
* Include the service in the `AppModule` or in a module that is only imported by the `AppModule` * Include the service in the `AppModule` or in a module that is only imported by the `AppModule`

View File

@ -1065,7 +1065,7 @@ However, using the above style binding syntax without `NgStyle` is preferred bec
{@a styling-precedence} {@a styling-precedence}
### Styling Precedence ### Styling Precedence
A single HTML element can have its CSS class list and style values bound to a multiple sources (for example, host bindings from multiple directives). A single HTML element can have its CSS class list and style values bound to multiple sources (for example, host bindings from multiple directives).
When there are multiple bindings to the same class name or style property, Angular uses a set of precedence rules to resolve conflicts and determine which classes or styles are ultimately applied to the element. When there are multiple bindings to the same class name or style property, Angular uses a set of precedence rules to resolve conflicts and determine which classes or styles are ultimately applied to the element.

View File

@ -899,8 +899,7 @@ In production, change detection kicks in automatically
when Angular creates a component or the user enters a keystroke or when Angular creates a component or the user enters a keystroke or
an asynchronous activity (e.g., AJAX) completes. an asynchronous activity (e.g., AJAX) completes.
The `TestBed.createComponent` does _not_ trigger change detection. The `TestBed.createComponent` does _not_ trigger change detection; a fact confirmed in the revised test:
a fact confirmed in the revised test:
<code-example <code-example
path="testing/src/app/banner/banner.component.spec.ts" region="test-w-o-detect-changes"></code-example> path="testing/src/app/banner/banner.component.spec.ts" region="test-w-o-detect-changes"></code-example>
@ -1051,8 +1050,7 @@ attempt to reach an authentication server.
These behaviors can be hard to intercept. These behaviors can be hard to intercept.
It is far easier and safer to create and register a test double in place of the real `UserService`. It is far easier and safer to create and register a test double in place of the real `UserService`.
This particular test suite supplies a minimal mock of the `UserService` that satisfies the needs of the `WelcomeComponent` This particular test suite supplies a minimal mock of the `UserService` that satisfies the needs of the `WelcomeComponent` and its tests:
and its tests:
<code-example <code-example
path="testing/src/app/welcome/welcome.component.spec.ts" path="testing/src/app/welcome/welcome.component.spec.ts"
@ -1266,8 +1264,7 @@ You do have to call [tick()](api/core/testing/tick) to advance the (virtual) clo
Calling [tick()](api/core/testing/tick) simulates the passage of time until all pending asynchronous activities finish. Calling [tick()](api/core/testing/tick) simulates the passage of time until all pending asynchronous activities finish.
In this case, it waits for the error handler's `setTimeout()`. In this case, it waits for the error handler's `setTimeout()`.
The [tick()](api/core/testing/tick) function accepts milliseconds and tickOptions as parameters, the millisecond (defaults to 0 if not provided) parameter represents how much the virtual clock advances. For example, if you have a `setTimeout(fn, 100)` in a `fakeAsync()` test, you need to use tick(100) to trigger the fn callback. The tickOptions is an optional parameter with a property called processNewMacroTasksSynchronously (defaults is true) represents whether to invoke The [tick()](api/core/testing/tick) function accepts milliseconds and tickOptions as parameters, the millisecond (defaults to 0 if not provided) parameter represents how much the virtual clock advances. For example, if you have a `setTimeout(fn, 100)` in a `fakeAsync()` test, you need to use tick(100) to trigger the fn callback. The tickOptions is an optional parameter with a property called `processNewMacroTasksSynchronously` (defaults to true) represents whether to invoke new generated macro tasks when ticking.
new generated macro tasks when ticking.
<code-example <code-example
path="testing/src/app/demo/async-helper.spec.ts" path="testing/src/app/demo/async-helper.spec.ts"
@ -1331,51 +1328,46 @@ You can also use RxJS scheduler in `fakeAsync()` just like using `setTimeout()`
#### Support more macroTasks #### Support more macroTasks
By default `fakeAsync()` supports the following `macroTasks`. By default, `fakeAsync()` supports the following macro tasks.
- setTimeout - `setTimeout`
- setInterval - `setInterval`
- requestAnimationFrame - `requestAnimationFrame`
- webkitRequestAnimationFrame - `webkitRequestAnimationFrame`
- mozRequestAnimationFrame - `mozRequestAnimationFrame`
If you run other `macroTask` such as `HTMLCanvasElement.toBlob()`, `Unknown macroTask scheduled in fake async test` error will be thrown. If you run other macro tasks such as `HTMLCanvasElement.toBlob()`, an _"Unknown macroTask scheduled in fake async test"_ error will be thrown.
<code-tabs> <code-tabs>
<code-pane <code-pane
header="src/app/shared/canvas.component.spec.ts (failing)"
path="testing/src/app/shared/canvas.component.spec.ts" path="testing/src/app/shared/canvas.component.spec.ts"
header="src/app/shared/canvas.component.spec.ts"> region="without-toBlob-macrotask">
</code-pane> </code-pane>
<code-pane <code-pane
header="src/app/shared/canvas.component.ts"
path="testing/src/app/shared/canvas.component.ts" path="testing/src/app/shared/canvas.component.ts"
header="src/app/shared/canvas.component.ts"> region="main">
</code-pane> </code-pane>
</code-tabs> </code-tabs>
If you want to support such a case, you need to define the `macroTask` you want to support in `beforeEach()`. If you want to support such a case, you need to define the macro task you want to support in `beforeEach()`.
For example: For example:
```javascript <code-example
beforeEach(() => { header="src/app/shared/canvas.component.spec.ts (excerpt)"
window['__zone_symbol__FakeAsyncTestMacroTask'] = [ path="testing/src/app/shared/canvas.component.spec.ts"
{ region="enable-toBlob-macrotask">
source: 'HTMLCanvasElement.toBlob', </code-example>
callbackArgs: [{ size: 200 }]
} Note that in order to make the `<canvas>` element Zone.js-aware in your app, you need to import the `zone-patch-canvas` patch (either in `polyfills.ts` or in the specific file that uses `<canvas>`):
];
}); <code-example
header="src/polyfills.ts or src/app/shared/canvas.component.ts"
path="testing/src/app/shared/canvas.component.ts"
region="import-canvas-patch">
</code-example>
it('toBlob should be able to run in fakeAsync', fakeAsync(() => {
const canvas: HTMLCanvasElement = document.getElementById('canvas') as HTMLCanvasElement;
let blob = null;
canvas.toBlob(function(b) {
blob = b;
});
tick();
expect(blob.size).toBe(200);
})
);
```
#### Async observables #### Async observables
@ -3635,7 +3627,7 @@ next to their corresponding helper files.
#### Keep it simple #### Keep it simple
[Component class testing](#component-class-testing) should be kept very clean and simple. [Component class testing](#component-class-testing) should be kept very clean and simple.
It should test only a single unit. On a first glance, you should be able to understand It should test only a single unit. On a first glance, you should be able to understand
what the test is testing. If it's doing more, then it doesn't belong here. what the test is testing. If it's doing more, then it doesn't belong here.
{@a q-end-to-end} {@a q-end-to-end}

View File

@ -218,7 +218,7 @@ zone.run(() => {
This new context, `zoneThis`, can be retrieved from the `setTimeout()` callback function, and this context is the same when the `setTimeout()` is scheduled. This new context, `zoneThis`, can be retrieved from the `setTimeout()` callback function, and this context is the same when the `setTimeout()` is scheduled.
To get the context, you can call [`Zone.current`](https://github.com/angular/angular/blob/master/packages/zone.js/lib/zone.ts). To get the context, you can call [`Zone.current`](https://github.com/angular/angular/blob/master/packages/zone.js/lib/zone.ts).
### Zones and async lifecycle hooks ## Zones and async lifecycle hooks
Zone.js can create contexts that persist across asynchronous operations as well as provide lifecycle hooks for asynchronous operations. Zone.js can create contexts that persist across asynchronous operations as well as provide lifecycle hooks for asynchronous operations.
@ -296,14 +296,14 @@ Monkey patching is a technique to add or modify the default behavior of a functi
## NgZone ## NgZone
While Zone.js can monitor all the states of synchronous and asynchronous operations, Angular additionally provides a service called NgZone. While Zone.js can monitor all the states of synchronous and asynchronous operations, Angular additionally provides a service called NgZone.
This service creates a zone named `angular` to automatically trigger change detction when the following conditions are satisfied: This service creates a zone named `angular` to automatically trigger change detection when the following conditions are satisfied:
1. When a sync or async function is executed. 1. When a sync or async function is executed.
1. When there is no `microTask` scheduled. 1. When there is no `microTask` scheduled.
### NgZone `run()`/`runOutsideOfAngular()` ### NgZone `run()`/`runOutsideOfAngular()`
`Zone` handles most asynchronous APIs such as `setTimeout()`, `Promise.then(),and `addEventListener()`. `Zone` handles most asynchronous APIs such as `setTimeout()`, `Promise.then()`, and `addEventListener()`.
For the full list, see the [Zone Module document](https://github.com/angular/angular/blob/master/packages/zone.js/MODULE.md). For the full list, see the [Zone Module document](https://github.com/angular/angular/blob/master/packages/zone.js/MODULE.md).
Therefore in those asynchronous APIs, you don't need to trigger change detection manually. Therefore in those asynchronous APIs, you don't need to trigger change detection manually.
@ -315,12 +315,12 @@ This function, and all asynchronous operations in that function, trigger change
export class AppComponent implements OnInit { export class AppComponent implements OnInit {
constructor(private ngZone: NgZone) {} constructor(private ngZone: NgZone) {}
ngOnInit() { ngOnInit() {
// new async API is not handled by Zone, so you need to // New async API is not handled by Zone, so you need to
// use ngZone.run to make the asynchronous operation in angular zone // use ngZone.run() to make the asynchronous operation in the angular zone
// and trigger change detection automatically // and trigger change detection automatically.
this.ngZone.run(() => { this.ngZone.run(() => {
someNewAsyncAPI(() => { someNewAsyncAPI(() => {
// update data of component // update the data of the component
}); });
}); });
} }
@ -335,19 +335,20 @@ In that situation, you can use another NgZone method: [runOutsideAngular()](api/
export class AppComponent implements OnInit { export class AppComponent implements OnInit {
constructor(private ngZone: NgZone) {} constructor(private ngZone: NgZone) {}
ngOnInit() { ngOnInit() {
// you know no data will be updated // You know no data will be updated,
// you don't want to do change detection in this // so you don't want to trigger change detection in this
// specified operation, you can call runOutsideAngular // specified operation. Instead, call ngZone.runOutsideAngular()
this.ngZone.runOutsideAngular(() => { this.ngZone.runOutsideAngular(() => {
setTimeout(() => { setTimeout(() => {
// do something will not update component data // update component data
// but don't trigger change detection.
}); });
}); });
} }
} }
``` ```
### Seting up Zone.js ### Setting up Zone.js
To make Zone.js available in Angular, you need to import the zone.js package. To make Zone.js available in Angular, you need to import the zone.js package.
If you are using the Angular CLI, this step is done automatically, and you will see the following line in the `src/polyfills.ts`: If you are using the Angular CLI, this step is done automatically, and you will see the following line in the `src/polyfills.ts`:

View File

@ -13,12 +13,6 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<!-- ngIndia 2020 -->
<tr>
<th><a href="https://www.ng-ind.com/" title="ngIndia">ngIndia</a></th>
<td>Delhi, India</td>
<td>Feb 29, 2020</td>
</tr>
<!-- ng-conf 2020 --> <!-- ng-conf 2020 -->
<tr> <tr>
<th><a href="https://ng-conf.org/" title="ng-conf">ng-conf</a></th> <th><a href="https://ng-conf.org/" title="ng-conf">ng-conf</a></th>
@ -38,6 +32,12 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<!-- ngIndia 2020 -->
<tr>
<th><a href="https://www.ng-ind.com/" title="ngIndia">ngIndia</a></th>
<td>Delhi, India</td>
<td>Feb 29, 2020</td>
</tr>
<!-- ReactiveConf 2019 --> <!-- ReactiveConf 2019 -->
<tr> <tr>
<th><a href="https://reactiveconf.com/" title="ReactiveConf">ReactiveConf</a></th> <th><a href="https://reactiveconf.com/" title="ReactiveConf">ReactiveConf</a></th>

View File

@ -14,6 +14,9 @@ module.exports = function (config) {
require('@angular-devkit/build-angular/plugins/karma'), require('@angular-devkit/build-angular/plugins/karma'),
{'reporter:jasmine-seed': ['type', JasmineSeedReporter]}, {'reporter:jasmine-seed': ['type', JasmineSeedReporter]},
], ],
proxies: {
'/dummy/image': 'src/assets/images/logos/angular/angular.png',
},
client: { client: {
clearContext: false, // leave Jasmine Spec Runner output visible in browser clearContext: false, // leave Jasmine Spec Runner output visible in browser
jasmine: { jasmine: {

View File

@ -3,7 +3,7 @@
"master": { "master": {
"uncompressed": { "uncompressed": {
"runtime-es2015": 2987, "runtime-es2015": 2987,
"main-es2015": 449223, "main-es2015": 450612,
"polyfills-es2015": 52195 "polyfills-es2015": 52195
} }
} }
@ -12,7 +12,7 @@
"master": { "master": {
"uncompressed": { "uncompressed": {
"runtime-es2015": 2987, "runtime-es2015": 2987,
"main-es2015": 450541, "main-es2015": 451469,
"polyfills-es2015": 52195 "polyfills-es2015": 52195
} }
} }
@ -21,7 +21,7 @@
"master": { "master": {
"uncompressed": { "uncompressed": {
"runtime-es2015": 3097, "runtime-es2015": 3097,
"main-es2015": 426533, "main-es2015": 429230,
"polyfills-es2015": 52195 "polyfills-es2015": 52195
} }
} }

View File

@ -417,6 +417,15 @@ describe('AppComponent', () => {
selectElement.triggerEventHandler('change', { option: versionWithoutUrl, index: versionWithoutUrlIndex }); selectElement.triggerEventHandler('change', { option: versionWithoutUrl, index: versionWithoutUrlIndex });
expect(locationService.go).not.toHaveBeenCalled(); expect(locationService.go).not.toHaveBeenCalled();
}); });
it('should navigate when change to a version with a url that does not end with `/`', async () => {
await setupSelectorForTesting();
locationService.urlSubject.next('docs#section-1');
const versionWithoutSlashIndex = component.docVersions.length;
const versionWithoutSlashUrl = component.docVersions[versionWithoutSlashIndex] = { url: 'https://next.angular.io', title: 'foo' };
selectElement.triggerEventHandler('change', { option: versionWithoutSlashUrl, index: versionWithoutSlashIndex });
expect(locationService.go).toHaveBeenCalledWith('https://next.angular.io/docs#section-1');
});
}); });
describe('currentDocument', () => { describe('currentDocument', () => {
@ -792,7 +801,7 @@ describe('AppComponent', () => {
const searchService = TestBed.inject(SearchService) as Partial<SearchService> as MockSearchService; const searchService = TestBed.inject(SearchService) as Partial<SearchService> as MockSearchService;
const results = [ const results = [
{ path: 'news', title: 'News', type: 'marketing', keywords: '', titleWords: '', deprecated: false } { path: 'news', title: 'News', type: 'marketing', keywords: '', titleWords: '', deprecated: false, topics: '' }
]; ];
searchService.searchResults.next({ query: 'something', results }); searchService.searchResults.next({ query: 'something', results });

View File

@ -149,8 +149,8 @@ export class AppComponent implements OnInit {
]).subscribe(([versionInfo, versions]) => { ]).subscribe(([versionInfo, versions]) => {
// TODO(pbd): consider whether we can lookup the stable and next versions from the internet // TODO(pbd): consider whether we can lookup the stable and next versions from the internet
const computedVersions: NavigationNode[] = [ const computedVersions: NavigationNode[] = [
{ title: 'next', url: 'https://next.angular.io' }, { title: 'next', url: 'https://next.angular.io/' },
{ title: 'stable', url: 'https://angular.io' }, { title: 'stable', url: 'https://angular.io/' },
]; ];
if (this.deployment.mode === 'archive') { if (this.deployment.mode === 'archive') {
computedVersions.push({ title: `v${versionInfo.major}` }); computedVersions.push({ title: `v${versionInfo.major}` });
@ -232,7 +232,8 @@ export class AppComponent implements OnInit {
onDocVersionChange(versionIndex: number) { onDocVersionChange(versionIndex: number) {
const version = this.docVersions[versionIndex]; const version = this.docVersions[versionIndex];
if (version.url) { if (version.url) {
this.locationService.go(`${version.url}${this.currentUrl}`); const versionUrl = version.url + (!version.url.endsWith('/') ? '/' : '');
this.locationService.go(`${versionUrl}${this.currentUrl}`);
} }
} }

View File

@ -88,7 +88,7 @@ describe('AnnouncementBarComponent', () => {
describe('rendering', () => { describe('rendering', () => {
beforeEach(() => { beforeEach(() => {
component.announcement = { component.announcement = {
imageUrl: 'link/to/image', imageUrl: 'dummy/image',
linkUrl: 'link/to/website', linkUrl: 'link/to/website',
message: 'this is an <b>important</b> message', message: 'this is an <b>important</b> message',
endDate: '2018-03-01', endDate: '2018-03-01',
@ -102,7 +102,7 @@ describe('AnnouncementBarComponent', () => {
}); });
it('should display an image', () => { it('should display an image', () => {
expect(element.querySelector('img')!.src).toContain('link/to/image'); expect(element.querySelector('img')!.src).toContain('dummy/image');
}); });
it('should display a link', () => { it('should display a link', () => {

View File

@ -9,6 +9,7 @@ export interface SearchResult {
type: string; type: string;
titleWords: string; titleWords: string;
keywords: string; keywords: string;
topics: string;
deprecated: boolean; deprecated: boolean;
} }

View File

@ -15,6 +15,7 @@ interface PageInfo {
type: string; type: string;
titleWords: string; titleWords: string;
keyWords: string; keyWords: string;
topics: string;
} }
addEventListener('message', handleMessage); addEventListener('message', handleMessage);
@ -27,6 +28,7 @@ function createIndex(loadIndexFn: IndexLoader): lunr.Index {
queryLexer.termSeparator = lunr.tokenizer.separator = /\s+/; queryLexer.termSeparator = lunr.tokenizer.separator = /\s+/;
return lunr(/** @this */function() { return lunr(/** @this */function() {
this.ref('path'); this.ref('path');
this.field('topics', { boost: 15 });
this.field('titleWords', { boost: 10 }); this.field('titleWords', { boost: 10 });
this.field('headingWords', { boost: 5 }); this.field('headingWords', { boost: 5 });
this.field('members', { boost: 4 }); this.field('members', { boost: 4 });

View File

@ -1,30 +1,57 @@
<div class="search-results"> <div class="search-results" [ngSwitch]="searchState">
<div *ngIf="searchAreas.length; then searchResults; else notFound"></div>
<ng-container *ngSwitchCase="'in-progress'">
<p class="no-results">Searching ...</p>
</ng-container>
<ng-container *ngSwitchCase="'results-found'">
<h2 class="visually-hidden">Search Results</h2>
<div class="search-area" *ngFor="let area of searchAreas">
<h3 class="search-section-header">{{area.name}} ({{area.pages.length + area.priorityPages.length}})</h3>
<ul class="priority-pages" >
<li class="search-page" *ngFor="let page of area.priorityPages">
<a class="search-result-item" href="{{ page.path }}" (click)="onResultSelected(page, $event)">
<span class="symbol {{page.type}}" *ngIf="area.name === 'api'"></span>
<span [class.deprecated-api-item]="page.deprecated">{{ page.title }}</span>
</a>
</li>
</ul>
<ul>
<li class="search-page" *ngFor="let page of area.pages">
<a class="search-result-item" href="{{ page.path }}" (click)="onResultSelected(page, $event)">
<span class="symbol {{page.type}}" *ngIf="area.name === 'api'"></span>
<span [class.deprecated-api-item]="page.deprecated">{{ page.title }}</span>
</a>
</li>
</ul>
</div>
</ng-container>
<ng-container *ngSwitchCase="'no-results-found'">
<div class="search-area">
<p class="no-results">
No results found.<br>
Here are a few links that might be helpful in finding what you are looking for:
</p>
<ul class="priority-pages">
<li class="search-page">
<a class="search-result-item" href="api">API reference</a>
</li>
<li class="search-page">
<a class="search-result-item" href="resources">Resources</a>
</li>
<li class="search-page">
<a class="search-result-item" href="guide/glossary">Glossary</a>
</li>
<li class="search-page">
<a class="search-result-item" href="guide/cheatsheet">Cheat-sheet</a>
</li>
<li class="search-page">
<a class="search-result-item" href="https://blog.angular.io/">Angular blog</a>
</li>
</ul>
</div>
</ng-container>
</div> </div>
<ng-template #searchResults>
<h2 class="visually-hidden">Search Results</h2>
<div class="search-area" *ngFor="let area of searchAreas">
<h3 class="search-section-header">{{area.name}} ({{area.pages.length + area.priorityPages.length}})</h3>
<ul class="priority-pages" >
<li class="search-page" *ngFor="let page of area.priorityPages">
<a class="search-result-item" href="{{ page.path }}" (click)="onResultSelected(page, $event)">
<span class="symbol {{page.type}}" *ngIf="area.name === 'api'"></span>
<span [class.deprecated-api-item]="page.deprecated">{{ page.title }}</span>
</a>
</li>
</ul>
<ul>
<li class="search-page" *ngFor="let page of area.pages">
<a class="search-result-item" href="{{ page.path }}" (click)="onResultSelected(page, $event)">
<span class="symbol {{page.type}}" *ngIf="area.name === 'api'"></span>
<span [class.deprecated-api-item]="page.deprecated">{{ page.title }}</span>
</a>
</li>
</ul>
</div>
</ng-template>
<ng-template #notFound>
<p class="not-found">{{notFoundMessage}}</p>
</ng-template>

View File

@ -37,21 +37,21 @@ describe('SearchResultsComponent', () => {
/** Get a full set of test results. "Take" what you need */ /** Get a full set of test results. "Take" what you need */
beforeEach(() => { beforeEach(() => {
apiD = { path: 'api/d', title: 'API D', deprecated: false, keywords: '', titleWords: '', type: '' }; apiD = { path: 'api/d', title: 'API D', deprecated: false, keywords: '', titleWords: '', type: '', topics: '' };
apiC = { path: 'api/c', title: 'API C', deprecated: false, keywords: '', titleWords: '', type: '' }; apiC = { path: 'api/c', title: 'API C', deprecated: false, keywords: '', titleWords: '', type: '', topics: '' };
guideA = { path: 'guide/a', title: 'Guide A', deprecated: false, keywords: '', titleWords: '', type: '' }; guideA = { path: 'guide/a', title: 'Guide A', deprecated: false, keywords: '', titleWords: '', type: '', topics: '' };
guideB = { path: 'guide/b', title: 'Guide B', deprecated: false, keywords: '', titleWords: '', type: '' }; guideB = { path: 'guide/b', title: 'Guide B', deprecated: false, keywords: '', titleWords: '', type: '', topics: '' };
guideAC = { path: 'guide/a/c', title: 'Guide A - C', deprecated: false, keywords: '', titleWords: '', type: '' }; guideAC = { path: 'guide/a/c', title: 'Guide A - C', deprecated: false, keywords: '', titleWords: '', type: '', topics: '' };
guideE = { path: 'guide/e', title: 'Guide e', deprecated: false, keywords: '', titleWords: '', type: '' }; guideE = { path: 'guide/e', title: 'Guide e', deprecated: false, keywords: '', titleWords: '', type: '', topics: '' };
guideF = { path: 'guide/f', title: 'Guide f', deprecated: false, keywords: '', titleWords: '', type: '' }; guideF = { path: 'guide/f', title: 'Guide f', deprecated: false, keywords: '', titleWords: '', type: '', topics: '' };
guideG = { path: 'guide/g', title: 'Guide g', deprecated: false, keywords: '', titleWords: '', type: '' }; guideG = { path: 'guide/g', title: 'Guide g', deprecated: false, keywords: '', titleWords: '', type: '', topics: '' };
guideH = { path: 'guide/h', title: 'Guide h', deprecated: false, keywords: '', titleWords: '', type: '' }; guideH = { path: 'guide/h', title: 'Guide h', deprecated: false, keywords: '', titleWords: '', type: '', topics: '' };
guideI = { path: 'guide/i', title: 'Guide i', deprecated: false, keywords: '', titleWords: '', type: '' }; guideI = { path: 'guide/i', title: 'Guide i', deprecated: false, keywords: '', titleWords: '', type: '', topics: '' };
guideJ = { path: 'guide/j', title: 'Guide j', deprecated: false, keywords: '', titleWords: '', type: '' }; guideJ = { path: 'guide/j', title: 'Guide j', deprecated: false, keywords: '', titleWords: '', type: '', topics: '' };
guideK = { path: 'guide/k', title: 'Guide k', deprecated: false, keywords: '', titleWords: '', type: '' }; guideK = { path: 'guide/k', title: 'Guide k', deprecated: false, keywords: '', titleWords: '', type: '', topics: '' };
guideL = { path: 'guide/l', title: 'Guide l', deprecated: false, keywords: '', titleWords: '', type: '' }; guideL = { path: 'guide/l', title: 'Guide l', deprecated: false, keywords: '', titleWords: '', type: '', topics: '' };
guideM = { path: 'guide/m', title: 'Guide m', deprecated: false, keywords: '', titleWords: '', type: '' }; guideM = { path: 'guide/m', title: 'Guide m', deprecated: false, keywords: '', titleWords: '', type: '', topics: '' };
guideN = { path: 'guide/n', title: 'Guide n', deprecated: false, keywords: '', titleWords: '', type: '' }; guideN = { path: 'guide/n', title: 'Guide n', deprecated: false, keywords: '', titleWords: '', type: '', topics: '' };
standardResults = [ standardResults = [
guideA, apiD, guideB, guideAC, apiC, guideN, guideM, guideL, guideK, guideJ, guideI, guideH, guideG, guideF, guideE, guideA, apiD, guideB, guideAC, apiC, guideN, guideM, guideL, guideK, guideJ, guideI, guideH, guideG, guideF, guideE,
@ -80,13 +80,13 @@ describe('SearchResultsComponent', () => {
it('should special case results that are top level folders', () => { it('should special case results that are top level folders', () => {
setSearchResults('', [ setSearchResults('', [
{ path: 'tutorial', title: 'Tutorial index', type: '', keywords: '', titleWords: '', deprecated: false }, { path: 'tutorial', title: 'Tutorial index', type: '', keywords: '', titleWords: '', deprecated: false, topics: '' },
{ path: 'tutorial/toh-pt1', title: 'Tutorial - part 1', type: '', keywords: '', titleWords: '', deprecated: false }, { path: 'tutorial/toh-pt1', title: 'Tutorial - part 1', type: '', keywords: '', titleWords: '', deprecated: false, topics: '' },
]); ]);
expect(component.searchAreas).toEqual([ expect(component.searchAreas).toEqual([
{ name: 'tutorial', priorityPages: [ { name: 'tutorial', priorityPages: [
{ path: 'tutorial', title: 'Tutorial index', type: '', keywords: '', titleWords: '', deprecated: false }, { path: 'tutorial', title: 'Tutorial index', type: '', keywords: '', titleWords: '', deprecated: false, topics: '' },
{ path: 'tutorial/toh-pt1', title: 'Tutorial - part 1', type: '', keywords: '', titleWords: '', deprecated: false }, { path: 'tutorial/toh-pt1', title: 'Tutorial - part 1', type: '', keywords: '', titleWords: '', deprecated: false, topics: '' },
], pages: [] } ], pages: [] }
]); ]);
}); });
@ -116,20 +116,20 @@ describe('SearchResultsComponent', () => {
it('should put search results with no containing folder into the default area (other)', () => { it('should put search results with no containing folder into the default area (other)', () => {
const results = [ const results = [
{ path: 'news', title: 'News', type: 'marketing', keywords: '', titleWords: '', deprecated: false } { path: 'news', title: 'News', type: 'marketing', keywords: '', titleWords: '', deprecated: false, topics: '' }
]; ];
setSearchResults('', results); setSearchResults('', results);
expect(component.searchAreas).toEqual([ expect(component.searchAreas).toEqual([
{ name: 'other', priorityPages: [ { name: 'other', priorityPages: [
{ path: 'news', title: 'News', type: 'marketing', keywords: '', titleWords: '', deprecated: false } { path: 'news', title: 'News', type: 'marketing', keywords: '', titleWords: '', deprecated: false, topics: '' }
], pages: [] } ], pages: [] }
]); ]);
}); });
it('should omit search results with no title', () => { it('should omit search results with no title', () => {
const results = [ const results = [
{ path: 'news', title: '', type: 'marketing', keywords: '', titleWords: '', deprecated: false } { path: 'news', title: '', type: 'marketing', keywords: '', titleWords: '', deprecated: false, topics: '' }
]; ];
setSearchResults('something', results); setSearchResults('something', results);
@ -170,6 +170,12 @@ describe('SearchResultsComponent', () => {
expect(getText()).toContain('Searching ...'); expect(getText()).toContain('Searching ...');
}); });
it('should not display default links while searching', () => {
fixture.detectChanges();
const resultLinks = fixture.debugElement.queryAll(By.css('.search-page a'));
expect(resultLinks.length).toEqual(0);
});
describe('when a search result anchor is clicked', () => { describe('when a search result anchor is clicked', () => {
let searchResult: SearchResult; let searchResult: SearchResult;
let selected: SearchResult|null; let selected: SearchResult|null;
@ -179,7 +185,7 @@ describe('SearchResultsComponent', () => {
component.resultSelected.subscribe((result: SearchResult) => selected = result); component.resultSelected.subscribe((result: SearchResult) => selected = result);
selected = null; selected = null;
searchResult = { path: 'news', title: 'News', type: 'marketing', keywords: '', titleWords: '', deprecated: false }; searchResult = { path: 'news', title: 'News', type: 'marketing', keywords: '', titleWords: '', deprecated: false, topics: '' };
setSearchResults('something', [searchResult]); setSearchResults('something', [searchResult]);
fixture.detectChanges(); fixture.detectChanges();
@ -214,9 +220,25 @@ describe('SearchResultsComponent', () => {
}); });
describe('when no query results', () => { describe('when no query results', () => {
it('should display "not found" message', () => { beforeEach(() => {
setSearchResults('something', []); setSearchResults('something', []);
});
it('should display "not found" message', () => {
expect(getText()).toContain('No results'); expect(getText()).toContain('No results');
}); });
it('should contain reference links', () => {
const resultLinks = fixture.debugElement.queryAll(By.css('.search-page a'));
const resultHrefs = resultLinks.map(a => a.nativeNode.getAttribute('href'));
expect(resultHrefs.length).toEqual(5);
expect(resultHrefs).toEqual([
'api',
'resources',
'guide/glossary',
'guide/cheatsheet',
'https://blog.angular.io/',
]);
});
}); });
}); });

View File

@ -1,6 +1,12 @@
import { Component, EventEmitter, Input, OnChanges, Output } from '@angular/core'; import { Component, EventEmitter, Input, OnChanges, Output } from '@angular/core';
import { SearchResult, SearchResults, SearchArea } from 'app/search/interfaces'; import { SearchResult, SearchResults, SearchArea } from 'app/search/interfaces';
enum SearchState {
InProgress = 'in-progress',
ResultsFound = 'results-found',
NoResultsFound = 'no-results-found'
}
/** /**
* A component to display search results in groups * A component to display search results in groups
*/ */
@ -23,11 +29,18 @@ export class SearchResultsComponent implements OnChanges {
resultSelected = new EventEmitter<SearchResult>(); resultSelected = new EventEmitter<SearchResult>();
readonly defaultArea = 'other'; readonly defaultArea = 'other';
notFoundMessage = 'Searching ...'; searchState: SearchState = SearchState.InProgress;
readonly topLevelFolders = ['guide', 'tutorial']; readonly topLevelFolders = ['api', 'cli', 'guide', 'start', 'tutorial'];
searchAreas: SearchArea[] = []; searchAreas: SearchArea[] = [];
ngOnChanges() { ngOnChanges() {
if (this.searchResults === null) {
this.searchState = SearchState.InProgress;
} else if (this.searchResults.results.length) {
this.searchState = SearchState.ResultsFound;
} else {
this.searchState = SearchState.NoResultsFound;
}
this.searchAreas = this.processSearchResults(this.searchResults); this.searchAreas = this.processSearchResults(this.searchResults);
} }
@ -43,7 +56,6 @@ export class SearchResultsComponent implements OnChanges {
if (!search) { if (!search) {
return []; return [];
} }
this.notFoundMessage = 'No results found.';
const searchAreaMap: { [key: string]: SearchResult[] } = {}; const searchAreaMap: { [key: string]: SearchResult[] } = {};
search.results.forEach(result => { search.results.forEach(result => {
if (!result.title) { return; } // bad data; should fix if (!result.title) { return; } // bad data; should fix

View File

@ -67,12 +67,17 @@ aio-search-results {
} }
} }
.not-found { .no-results {
color: $white; color: $white;
text-align: center; text-align: center;
margin: 16px; margin: 16px;
} }
a {
color: $white;
font-weight: 500;
}
@media (max-width: 600px) { @media (max-width: 600px) {
display: block; display: block;
} }
@ -101,9 +106,13 @@ aio-search-results {
} }
} }
.not-found { .no-results {
color: $darkgray; color: $darkgray;
} }
a {
color: $blue;
}
} }
} }
} }

View File

@ -11,15 +11,15 @@ const yargs = require('yargs');
const PACKAGE_JSON = 'package.json'; const PACKAGE_JSON = 'package.json';
const YARN_LOCK = 'yarn.lock'; const YARN_LOCK = 'yarn.lock';
const LOCAL_MARKER_PATH = 'node_modules/_local_.json'; const LOCAL_MARKER_PATH = 'node_modules/_local_.json';
const PACKAGE_JSON_REGEX = /^[^/]+\/package\.json$/;
const ANGULAR_ROOT_DIR = path.resolve(__dirname, '../../..'); const ANGULAR_ROOT_DIR = path.resolve(__dirname, '../../..');
const ANGULAR_DIST_PACKAGES = path.join(ANGULAR_ROOT_DIR, 'dist/packages-dist'); const ANGULAR_DIST_PACKAGES_DIR = path.join(ANGULAR_ROOT_DIR, 'dist/packages-dist');
const ANGULAR_DIST_PACKAGES_BUILD_SCRIPT = path.join(ANGULAR_ROOT_DIR, 'scripts/build-packages-dist.js'); const ZONEJS_DIST_PACKAGES_DIR = path.join(ANGULAR_ROOT_DIR, 'dist/zone.js-dist');
const ANGULAR_DIST_PACKAGES_BUILD_CMD = `"${process.execPath}" "${ANGULAR_DIST_PACKAGES_BUILD_SCRIPT}"`; const DIST_PACKAGES_BUILD_SCRIPT = path.join(ANGULAR_ROOT_DIR, 'scripts/build/build-packages-dist.js');
const DIST_PACKAGES_BUILD_CMD = `"${process.execPath}" "${DIST_PACKAGES_BUILD_SCRIPT}"`;
/** /**
* A tool that can install Angular dependencies for a project from NPM or from the * A tool that can install Angular/Zone.js dependencies for a project from NPM or from the
* locally built distributables. * locally built distributables.
* *
* This tool is used to change dependencies of the `aio` application and the example * This tool is used to change dependencies of the `aio` application and the example
@ -34,7 +34,7 @@ class NgPackagesInstaller {
* @param {object} options - a hash of options for the install: * @param {object} options - a hash of options for the install:
* * `debug` (`boolean`) - whether to display debug messages. * * `debug` (`boolean`) - whether to display debug messages.
* * `force` (`boolean`) - whether to force a local installation even if there is a local marker file. * * `force` (`boolean`) - whether to force a local installation even if there is a local marker file.
* * `buildPackages` (`boolean`) - whether to build the local Angular packages before using them. * * `buildPackages` (`boolean`) - whether to build the local Angular/Zone.js packages before using them.
* (NOTE: Building the packages is currently not supported on Windows, so a message is printed instead.) * (NOTE: Building the packages is currently not supported on Windows, so a message is printed instead.)
* * `ignorePackages` (`string[]`) - a collection of names of packages that should not be copied over. * * `ignorePackages` (`string[]`) - a collection of names of packages that should not be copied over.
*/ */
@ -53,7 +53,7 @@ class NgPackagesInstaller {
/** /**
* Check whether the dependencies have been overridden with locally built * Check whether the dependencies have been overridden with locally built
* Angular packages. This is done by checking for the `_local_.json` marker file. * Angular/Zone.js packages. This is done by checking for the `_local_.json` marker file.
* This will emit a warning to the console if the dependencies have been overridden. * This will emit a warning to the console if the dependencies have been overridden.
*/ */
checkDependencies() { checkDependencies() {
@ -63,8 +63,8 @@ class NgPackagesInstaller {
} }
/** /**
* Install locally built Angular dependencies, overriding the dependencies in the package.json * Install locally built Angular/Zone.js dependencies, overriding the dependencies in the `package.json`.
* This will also write a "marker" file (`_local_.json`), which contains the overridden package.json * This will also write a "marker" file (`_local_.json`), which contains the overridden `package.json`
* contents and acts as an indicator that dependencies have been overridden. * contents and acts as an indicator that dependencies have been overridden.
*/ */
installLocalDependencies() { installLocalDependencies() {
@ -87,14 +87,14 @@ class NgPackagesInstaller {
// Prevent accidental publishing of the package, if something goes wrong. // Prevent accidental publishing of the package, if something goes wrong.
tmpConfig.private = true; tmpConfig.private = true;
// Overwrite project dependencies/devDependencies to Angular packages with local files. // Overwrite project dependencies/devDependencies to Angular/Zone.js packages with local files.
['dependencies', 'devDependencies'].forEach(prop => { ['dependencies', 'devDependencies'].forEach(prop => {
const deps = tmpConfig[prop] || {}; const deps = tmpConfig[prop] || {};
Object.keys(deps).forEach(key2 => { Object.keys(deps).forEach(key2 => {
const pkg2 = packages[key2]; const pkg2 = packages[key2];
if (pkg2) { if (pkg2) {
// point the core Angular packages at the distributable folder // point the local packages at the distributable folder
deps[key2] = `file:${pkg2.parentDir}/${key2.replace('@angular/', '')}`; deps[key2] = `file:${pkg2.packageDir}`;
this._log(`Overriding dependency of local ${key} with local package: ${key2}: ${deps[key2]}`); this._log(`Overriding dependency of local ${key} with local package: ${key2}: ${deps[key2]}`);
} }
}); });
@ -126,8 +126,8 @@ class NgPackagesInstaller {
fs.writeFileSync(pathToPackageConfig, packageConfigFile); fs.writeFileSync(pathToPackageConfig, packageConfigFile);
} }
} finally { } finally {
// Restore local Angular packages dependencies to other Angular packages. // Restore local Angular/Zone.js packages dependencies to other Angular packages.
this._log(`Restoring original ${PACKAGE_JSON} for local Angular packages.`); this._log(`Restoring original ${PACKAGE_JSON} for local packages.`);
Object.keys(packages).forEach(key => { Object.keys(packages).forEach(key => {
const pkg = packages[key]; const pkg = packages[key];
fs.writeFileSync(pkg.packageJsonPath, JSON.stringify(pkg.config, null, 2)); fs.writeFileSync(pkg.packageJsonPath, JSON.stringify(pkg.config, null, 2));
@ -168,7 +168,7 @@ class NgPackagesInstaller {
} }
/** /**
* Build the local Angular packages. * Build the local Angular/Zone.js packages.
* *
* NOTE: * NOTE:
* Building the packages is currently not supported on Windows, so a message is printed instead, prompting the user to * Building the packages is currently not supported on Windows, so a message is printed instead, prompting the user to
@ -178,14 +178,14 @@ class NgPackagesInstaller {
const canBuild = process.platform !== 'win32'; const canBuild = process.platform !== 'win32';
if (canBuild) { if (canBuild) {
this._log(`Building the Angular packages with: ${ANGULAR_DIST_PACKAGES_BUILD_SCRIPT}`); this._log(`Building the local packages with: ${DIST_PACKAGES_BUILD_SCRIPT}`);
shelljs.exec(ANGULAR_DIST_PACKAGES_BUILD_CMD); shelljs.exec(DIST_PACKAGES_BUILD_CMD);
} else { } else {
this._warn([ this._warn([
'Automatically building the local Angular packages is currently not supported on Windows.', 'Automatically building the local Angular/Zone.js packages is currently not supported on Windows.',
`Please, ensure '${ANGULAR_DIST_PACKAGES}' exists and is up-to-date (e.g. by running ` + `Please, ensure '${ANGULAR_DIST_PACKAGES_DIR}' and '${ZONEJS_DIST_PACKAGES_DIR}' exist and are up-to-date ` +
`'${ANGULAR_DIST_PACKAGES_BUILD_SCRIPT}' in Git Bash for Windows, Windows Subsystem for Linux or a Linux ` + `(e.g. by running '${DIST_PACKAGES_BUILD_SCRIPT}' in Git Bash for Windows, Windows Subsystem for Linux or ` +
'docker container or VM).', 'a Linux docker container or VM).',
'', '',
'Proceeding anyway...', 'Proceeding anyway...',
].join('\n')); ].join('\n'));
@ -200,12 +200,12 @@ class NgPackagesInstaller {
const sourcePackage = packages[key]; const sourcePackage = packages[key];
if (sourcePackage) { if (sourcePackage) {
// point the core Angular packages at the distributable folder // point the core Angular packages at the distributable folder
mergedDependencies[key] = `file:${sourcePackage.parentDir}/${key.replace('@angular/', '')}`; mergedDependencies[key] = `file:${sourcePackage.packageDir}`;
this._log(`Overriding dependency with local package: ${key}: ${mergedDependencies[key]}`); this._log(`Overriding dependency with local package: ${key}: ${mergedDependencies[key]}`);
// grab peer dependencies // grab peer dependencies
const sourcePackagePeerDeps = sourcePackage.config.peerDependencies || {}; const sourcePackagePeerDeps = sourcePackage.config.peerDependencies || {};
Object.keys(sourcePackagePeerDeps) Object.keys(sourcePackagePeerDeps)
// ignore peerDependencies which are already core Angular packages // ignore peerDependencies which are already core Angular/Zone.js packages
.filter(key => !packages[key]) .filter(key => !packages[key])
.forEach(key => peerDependencies[key] = sourcePackagePeerDeps[key]); .forEach(key => peerDependencies[key] = sourcePackagePeerDeps[key]);
} }
@ -215,36 +215,52 @@ class NgPackagesInstaller {
} }
/** /**
* A hash of Angular package configs. * A hash of Angular/Zone.js package configs.
* (Detected as directories in '/dist/packages-dist/' that contain a top-level 'package.json' file.) * (Detected as directories in '/dist/packages-dist/' and '/dist/zone.js-dist/' that contain a top-level
* 'package.json' file.)
*/ */
_getDistPackages() { _getDistPackages() {
const packageConfigs = Object.create(null); this._log(`Angular distributable directory: ${ANGULAR_DIST_PACKAGES_DIR}.`);
const distDir = ANGULAR_DIST_PACKAGES; this._log(`Zone.js distributable directory: ${ZONEJS_DIST_PACKAGES_DIR}.`);
this._log(`Angular distributable directory: ${distDir}.`);
if (this.buildPackages) { if (this.buildPackages) {
this._buildDistPackages(); this._buildDistPackages();
} }
shelljs const collectPackages = containingDir => {
.find(distDir) const packages = {};
.map(filePath => filePath.slice(distDir.length + 1))
.filter(filePath => PACKAGE_JSON_REGEX.test(filePath)) for (const dirName of shelljs.ls(containingDir)) {
.forEach(packagePath => { const packageDir = path.resolve(containingDir, dirName);
const packageName = `@angular/${packagePath.slice(0, -PACKAGE_JSON.length -1)}`; const packageJsonPath = path.join(packageDir, PACKAGE_JSON);
if (this.ignorePackages.indexOf(packageName) === -1) { const packageConfig = fs.existsSync(packageJsonPath) ? require(packageJsonPath) : null;
const packageConfig = require(path.resolve(distDir, packagePath)); const packageName = packageConfig && packageConfig.name;
packageConfigs[packageName] = {
parentDir: distDir, if (!packageConfig) {
packageJsonPath: path.resolve(distDir, packagePath), // No `package.json` found - this directory is not a package.
config: packageConfig continue;
}; } else if (!packageName) {
} else { // No `name` property in `package.json`. (This should never happen.)
this._log('Ignoring package', packageName); throw new Error(`Package '${packageDir}' specifies no name in its '${PACKAGE_JSON}'.`);
} else if (this.ignorePackages.includes(packageName)) {
this._log(`Ignoring package '${packageName}'.`);
continue;
} }
});
packages[packageName] = {
packageDir,
packageJsonPath,
config: packageConfig,
};
}
return packages;
};
const packageConfigs = {
...collectPackages(ANGULAR_DIST_PACKAGES_DIR),
...collectPackages(ZONEJS_DIST_PACKAGES_DIR),
};
this._log('Found the following Angular distributables:', Object.keys(packageConfigs).map(key => `\n - ${key}`)); this._log('Found the following Angular distributables:', Object.keys(packageConfigs).map(key => `\n - ${key}`));
return packageConfigs; return packageConfigs;
@ -333,7 +349,7 @@ class NgPackagesInstaller {
// Log a warning. // Log a warning.
this._warn([ this._warn([
`The project at "${absoluteProjectDir}" is running against the local Angular build.`, `The project at "${absoluteProjectDir}" is running against the local Angular/Zone.js build.`,
'', '',
'To restore the npm packages run:', 'To restore the npm packages run:',
'', '',
@ -386,10 +402,10 @@ function main() {
.option('debug', { describe: 'Print additional debug information.', default: false }) .option('debug', { describe: 'Print additional debug information.', default: false })
.option('force', { describe: 'Force the command to execute even if not needed.', default: false }) .option('force', { describe: 'Force the command to execute even if not needed.', default: false })
.option('build-packages', { describe: 'Build the local Angular packages, before using them.', default: false }) .option('build-packages', { describe: 'Build the local Angular/Zone.js packages, before using them.', default: false })
.option('ignore-packages', { describe: 'List of Angular packages that should not be used in local mode.', default: [], array: true }) .option('ignore-packages', { describe: 'List of Angular/Zone.js packages that should not be used in local mode.', default: [], array: true })
.command('overwrite <projectDir> [--force] [--debug] [--ignore-packages package1 package2]', 'Install dependencies from the locally built Angular distributables.', () => {}, argv => { .command('overwrite <projectDir> [--force] [--debug] [--ignore-packages package1 package2]', 'Install dependencies from the locally built Angular/Zone.js distributables.', () => {}, argv => {
createInstaller(argv).installLocalDependencies(); createInstaller(argv).installLocalDependencies();
}) })
.command('restore <projectDir> [--debug]', 'Install dependencies from the npm registry.', () => {}, argv => { .command('restore <projectDir> [--debug]', 'Install dependencies from the npm registry.', () => {}, argv => {

View File

@ -15,6 +15,7 @@ describe('NgPackagesInstaller', () => {
const yarnLockPath = path.resolve(absoluteProjectDir, 'yarn.lock'); const yarnLockPath = path.resolve(absoluteProjectDir, 'yarn.lock');
const ngRootDir = path.resolve(__dirname, '../../..'); const ngRootDir = path.resolve(__dirname, '../../..');
const packagesDir = path.join(ngRootDir, 'dist/packages-dist'); const packagesDir = path.join(ngRootDir, 'dist/packages-dist');
const zoneJsDir = path.join(ngRootDir, 'dist/zone.js-dist');
const toolsDir = path.join(ngRootDir, 'dist/tools/@angular'); const toolsDir = path.join(ngRootDir, 'dist/tools/@angular');
let installer; let installer;
@ -51,7 +52,7 @@ describe('NgPackagesInstaller', () => {
describe('installLocalDependencies()', () => { describe('installLocalDependencies()', () => {
const copyJsonObj = obj => JSON.parse(JSON.stringify(obj)); const copyJsonObj = obj => JSON.parse(JSON.stringify(obj));
let dummyNgPackages, dummyPackage, dummyPackageJson, expectedModifiedPackage, expectedModifiedPackageJson; let dummyLocalPackages, dummyPackage, dummyPackageJson, expectedModifiedPackage, expectedModifiedPackageJson;
beforeEach(() => { beforeEach(() => {
spyOn(installer, '_checkLocalMarker'); spyOn(installer, '_checkLocalMarker');
@ -60,34 +61,35 @@ describe('NgPackagesInstaller', () => {
spyOn(installer, '_parseLockfile').and.returnValue({ spyOn(installer, '_parseLockfile').and.returnValue({
'rxjs@^6.3.0': {version: '6.3.3'}, 'rxjs@^6.3.0': {version: '6.3.3'},
'zone.js@^0.8.26': {version: '0.8.27'} 'rxjs-dev@^6.3.0': {version: '6.4.2'}
}); });
// These are the packages that are "found" in the dist directory // These are the packages that are "found" in the dist directory
dummyNgPackages = { dummyLocalPackages = {
'@angular/core': { '@angular/core': {
parentDir: packagesDir, packageDir: `${packagesDir}/core`,
packageJsonPath: `${packagesDir}/core/package.json`, packageJsonPath: `${packagesDir}/core/package.json`,
config: { config: {
peerDependencies: { peerDependencies: {
'rxjs': '^6.4.0', 'rxjs': '^6.4.0',
'rxjs-dev': '^6.4.0',
'some-package': '5.0.1', 'some-package': '5.0.1',
'zone.js': '~0.8.26' 'zone.js': '~0.8.26'
} }
} }
}, },
'@angular/common': { '@angular/common': {
parentDir: packagesDir, packageDir: `${packagesDir}/common`,
packageJsonPath: `${packagesDir}/common/package.json`, packageJsonPath: `${packagesDir}/common/package.json`,
config: { peerDependencies: { '@angular/core': '4.4.4-1ab23cd4' } } config: { peerDependencies: { '@angular/core': '4.4.4-1ab23cd4' } }
}, },
'@angular/compiler': { '@angular/compiler': {
parentDir: packagesDir, packageDir: `${packagesDir}/compiler`,
packageJsonPath: `${packagesDir}/compiler/package.json`, packageJsonPath: `${packagesDir}/compiler/package.json`,
config: { peerDependencies: { '@angular/common': '4.4.4-1ab23cd4' } } config: { peerDependencies: { '@angular/common': '4.4.4-1ab23cd4' } }
}, },
'@angular/compiler-cli': { '@angular/compiler-cli': {
parentDir: toolsDir, packageDir: `${toolsDir}/compiler-cli`,
packageJsonPath: `${toolsDir}/compiler-cli/package.json`, packageJsonPath: `${toolsDir}/compiler-cli/package.json`,
config: { config: {
dependencies: { '@angular/tsc-wrapped': '4.4.4-1ab23cd4' }, dependencies: { '@angular/tsc-wrapped': '4.4.4-1ab23cd4' },
@ -95,38 +97,46 @@ describe('NgPackagesInstaller', () => {
} }
}, },
'@angular/tsc-wrapped': { '@angular/tsc-wrapped': {
parentDir: toolsDir, packageDir: `${toolsDir}/tsc-wrapped`,
packageJsonPath: `${toolsDir}/tsc-wrapped/package.json`, packageJsonPath: `${toolsDir}/tsc-wrapped/package.json`,
config: { config: {
devDependencies: { '@angular/common': '4.4.4-1ab23cd4' }, devDependencies: { '@angular/common': '4.4.4-1ab23cd4' },
peerDependencies: { tsickle: '^1.4.0' } peerDependencies: { tsickle: '^1.4.0' }
} }
} },
'zone.js': {
packageDir: `${zoneJsDir}/zone.js`,
packageJsonPath: `${zoneJsDir}/zone.js/package.json`,
config: {
devDependencies: { typescript: '^2.4.2' }
}
},
}; };
spyOn(installer, '_getDistPackages').and.callFake(() => copyJsonObj(dummyNgPackages)); spyOn(installer, '_getDistPackages').and.callFake(() => copyJsonObj(dummyLocalPackages));
// This is the package.json in the "test" folder // This is the package.json in the "test" folder
dummyPackage = { dummyPackage = {
dependencies: { dependencies: {
'@angular/core': '4.4.1', '@angular/core': '4.4.1',
'@angular/common': '4.4.1', '@angular/common': '4.4.1',
rxjs: '^6.3.0' rxjs: '^6.3.0',
'zone.js': '^0.8.26'
}, },
devDependencies: { devDependencies: {
'@angular/compiler-cli': '4.4.1', '@angular/compiler-cli': '4.4.1',
'zone.js': '^0.8.26' 'rxjs-dev': '^6.3.0'
} }
}; };
dummyPackageJson = JSON.stringify(dummyPackage); dummyPackageJson = JSON.stringify(dummyPackage);
fs.readFileSync.and.returnValue(dummyPackageJson); fs.readFileSync.and.returnValue(dummyPackageJson);
// This is the package.json that is temporarily written to the "test" folder // This is the package.json that is temporarily written to the "test" folder
// Note that the Angular (dev)dependencies have been modified to use a "file:" path // Note that the Angular/Zone.js (dev)dependencies have been modified to use a "file:" path
// And that the peerDependencies from `dummyNgPackages` have been updated or added as // and that the peerDependencies from `dummyLocalPackages` have been updated or added as
// (dev)dependencies (unless the current version in lockfile satisfies semver). // (dev)dependencies (unless the current version in lockfile satisfies semver).
// //
// For example, `zone.js@0.8.27` (from lockfile) satisfies `zone.js@~0.8.26` (from // For example, `rxjs-dev@6.4.2` (from lockfile) satisfies `rxjs-dev@^6.4.0` (from
// `@angular/core`), thus `zone.js: ^0.8.26` (from original `package.json`) is retained. // `@angular/core`), thus `rxjs-dev: ^6.3.0` (from original `package.json`) is retained.
// In contrast, `rxjs@6.3.3` (from lockfile) does not satisfy `rxjs@^6.4.0 (from // In contrast, `rxjs@6.3.3` (from lockfile) does not satisfy `rxjs@^6.4.0 (from
// `@angular/core`), thus `rxjs: ^6.3.0` (from original `package.json`) is replaced with // `@angular/core`), thus `rxjs: ^6.3.0` (from original `package.json`) is replaced with
// `rxjs: ^6.4.0` (from `@angular/core`). // `rxjs: ^6.4.0` (from `@angular/core`).
@ -134,11 +144,12 @@ describe('NgPackagesInstaller', () => {
dependencies: { dependencies: {
'@angular/core': `file:${packagesDir}/core`, '@angular/core': `file:${packagesDir}/core`,
'@angular/common': `file:${packagesDir}/common`, '@angular/common': `file:${packagesDir}/common`,
'rxjs': '^6.4.0' 'rxjs': '^6.4.0',
'zone.js': `file:${zoneJsDir}/zone.js`,
}, },
devDependencies: { devDependencies: {
'@angular/compiler-cli': `file:${toolsDir}/compiler-cli`, '@angular/compiler-cli': `file:${toolsDir}/compiler-cli`,
'zone.js': '^0.8.26', 'rxjs-dev': '^6.3.0',
'some-package': '5.0.1', 'some-package': '5.0.1',
typescript: '^2.4.2' typescript: '^2.4.2'
}, },
@ -182,31 +193,56 @@ describe('NgPackagesInstaller', () => {
}); });
it('should temporarily overwrite the package.json files of local Angular packages', () => { it('should temporarily overwrite the package.json files of local Angular packages', () => {
const pkgJsonFor = pkgName => dummyNgPackages[`@angular/${pkgName}`].packageJsonPath; const pkgJsonPathFor = pkgName => dummyLocalPackages[pkgName].packageJsonPath;
const pkgConfigFor = pkgName => copyJsonObj(dummyNgPackages[`@angular/${pkgName}`].config); const pkgConfigFor = pkgName => copyJsonObj(dummyLocalPackages[pkgName].config);
const overwriteConfigFor = (pkgName, newProps) => Object.assign(pkgConfigFor(pkgName), newProps); const overwriteConfigFor = (pkgName, newProps) => Object.assign(pkgConfigFor(pkgName), newProps);
const stringifyConfig = config => JSON.stringify(config, null, 2); const stringifyConfig = config => JSON.stringify(config, null, 2);
const allArgs = fs.writeFileSync.calls.allArgs(); const allArgs = fs.writeFileSync.calls.allArgs();
const firstFiveArgs = allArgs.slice(0, 5); const firstSixArgs = allArgs.slice(0, 6);
const lastFiveArgs = allArgs.slice(-5); const lastSixArgs = allArgs.slice(-6);
expect(firstFiveArgs).toEqual([ expect(firstSixArgs).toEqual([
[pkgJsonFor('core'), stringifyConfig(overwriteConfigFor('core', {private: true}))], [
[pkgJsonFor('common'), stringifyConfig(overwriteConfigFor('common', {private: true}))], pkgJsonPathFor('@angular/core'),
[pkgJsonFor('compiler'), stringifyConfig(overwriteConfigFor('compiler', {private: true}))], stringifyConfig(overwriteConfigFor('@angular/core', {private: true})),
[pkgJsonFor('compiler-cli'), stringifyConfig(overwriteConfigFor('compiler-cli', { ],
private: true, [
dependencies: { '@angular/tsc-wrapped': `file:${toolsDir}/tsc-wrapped` } pkgJsonPathFor('@angular/common'),
}))], stringifyConfig(overwriteConfigFor('@angular/common', {private: true})),
[pkgJsonFor('tsc-wrapped'), stringifyConfig(overwriteConfigFor('tsc-wrapped', { ],
private: true, [
devDependencies: { '@angular/common': `file:${packagesDir}/common` } pkgJsonPathFor('@angular/compiler'),
}))], stringifyConfig(overwriteConfigFor('@angular/compiler', {private: true})),
],
[
pkgJsonPathFor('@angular/compiler-cli'),
stringifyConfig(overwriteConfigFor('@angular/compiler-cli', {
private: true,
dependencies: { '@angular/tsc-wrapped': `file:${toolsDir}/tsc-wrapped` },
})),
],
[
pkgJsonPathFor('@angular/tsc-wrapped'),
stringifyConfig(overwriteConfigFor('@angular/tsc-wrapped', {
private: true,
devDependencies: { '@angular/common': `file:${packagesDir}/common` },
})),
],
[
pkgJsonPathFor('zone.js'),
stringifyConfig(overwriteConfigFor('zone.js', {private: true})),
],
]); ]);
expect(lastFiveArgs).toEqual(['core', 'common', 'compiler', 'compiler-cli', 'tsc-wrapped'] expect(lastSixArgs).toEqual([
.map(pkgName => [pkgJsonFor(pkgName), stringifyConfig(pkgConfigFor(pkgName))])); '@angular/core',
'@angular/common',
'@angular/compiler',
'@angular/compiler-cli',
'@angular/tsc-wrapped',
'zone.js',
].map(pkgName => [pkgJsonPathFor(pkgName), stringifyConfig(pkgConfigFor(pkgName))]));
}); });
it('should load the package.json', () => { it('should load the package.json', () => {
@ -253,7 +289,7 @@ describe('NgPackagesInstaller', () => {
}; };
it('should build the local packages, when not on Windows', () => { it('should build the local packages, when not on Windows', () => {
const buildScript = path.join(ngRootDir, 'scripts/build-packages-dist.js'); const buildScript = path.join(ngRootDir, 'scripts/build/build-packages-dist.js');
const buildCmd = `"${process.execPath}" "${buildScript}"`; const buildCmd = `"${process.execPath}" "${buildScript}"`;
buildDistPackagesOnPlatform('linux'); buildDistPackagesOnPlatform('linux');
@ -280,7 +316,7 @@ describe('NgPackagesInstaller', () => {
expect(shelljs.exec).not.toHaveBeenCalled(); expect(shelljs.exec).not.toHaveBeenCalled();
expect(warning).toContain( expect(warning).toContain(
'Automatically building the local Angular packages is currently not supported on Windows.'); 'Automatically building the local Angular/Zone.js packages is currently not supported on Windows.');
expect(warning).toContain('Git Bash for Windows'); expect(warning).toContain('Git Bash for Windows');
expect(warning).toContain('Windows Subsystem for Linux'); expect(warning).toContain('Windows Subsystem for Linux');
expect(warning).toContain('Linux docker container or VM'); expect(warning).toContain('Linux docker container or VM');
@ -288,7 +324,10 @@ describe('NgPackagesInstaller', () => {
}); });
describe('_getDistPackages()', () => { describe('_getDistPackages()', () => {
beforeEach(() => spyOn(NgPackagesInstaller.prototype, '_buildDistPackages')); beforeEach(() => {
fs.existsSync.and.callThrough();
spyOn(NgPackagesInstaller.prototype, '_buildDistPackages');
});
it('should not build the local packages by default', () => { it('should not build the local packages by default', () => {
installer._getDistPackages(); installer._getDistPackages();
@ -306,37 +345,39 @@ describe('NgPackagesInstaller', () => {
expect(installer._buildDistPackages).not.toHaveBeenCalled(); expect(installer._buildDistPackages).not.toHaveBeenCalled();
}); });
it('should include top level Angular packages', () => { it('should include top level Angular and Zone.js packages', () => {
const ngPackages = installer._getDistPackages(); const localPackages = installer._getDistPackages();
const expectedValue = jasmine.objectContaining({ const expectedValue = jasmine.objectContaining({
parentDir: jasmine.any(String), packageDir: jasmine.any(String),
packageJsonPath: jasmine.any(String), packageJsonPath: jasmine.any(String),
config: jasmine.any(Object), config: jasmine.any(Object),
}); });
// For example... // For example...
expect(ngPackages['@angular/common']).toEqual(expectedValue); expect(localPackages['@angular/common']).toEqual(expectedValue);
expect(ngPackages['@angular/core']).toEqual(expectedValue); expect(localPackages['@angular/core']).toEqual(expectedValue);
expect(ngPackages['@angular/router']).toEqual(expectedValue); expect(localPackages['@angular/router']).toEqual(expectedValue);
expect(ngPackages['@angular/upgrade']).toEqual(expectedValue); expect(localPackages['@angular/upgrade']).toEqual(expectedValue);
expect(localPackages['zone.js']).toEqual(expectedValue);
expect(ngPackages['@angular/upgrade/static']).not.toBeDefined(); expect(localPackages['@angular/upgrade/static']).not.toBeDefined();
}); });
it('should store each package\'s parent directory', () => { it('should store each package\'s directory', () => {
const ngPackages = installer._getDistPackages(); const localPackages = installer._getDistPackages();
// For example... // For example...
expect(ngPackages['@angular/core'].parentDir).toBe(packagesDir); expect(localPackages['@angular/core'].packageDir).toBe(path.join(packagesDir, 'core'));
expect(ngPackages['@angular/router'].parentDir).toBeDefined(toolsDir); expect(localPackages['@angular/router'].packageDir).toBe(path.join(packagesDir, 'router'));
expect(localPackages['zone.js'].packageDir).toBe(path.join(zoneJsDir, 'zone.js'));
}); });
it('should not include packages that have been ignored', () => { it('should not include packages that have been ignored', () => {
installer = new NgPackagesInstaller(projectDir, { ignorePackages: ['@angular/router'] }); installer = new NgPackagesInstaller(projectDir, { ignorePackages: ['@angular/router'] });
const ngPackages = installer._getDistPackages(); const localPackages = installer._getDistPackages();
expect(ngPackages['@angular/common']).toBeDefined(); expect(localPackages['@angular/common']).toBeDefined();
expect(ngPackages['@angular/router']).toBeUndefined(); expect(localPackages['@angular/router']).toBeUndefined();
}); });
}); });
@ -477,7 +518,7 @@ describe('NgPackagesInstaller', () => {
describe('_printWarning()', () => { describe('_printWarning()', () => {
it('should mention the message passed in the warning', () => { it('should mention the message passed in the warning', () => {
installer._printWarning(); installer._printWarning();
expect(console.warn.calls.argsFor(0)[0]).toContain('is running against the local Angular build'); expect(console.warn.calls.argsFor(0)[0]).toContain('is running against the local Angular/Zone.js build');
}); });
it('should mention the command to restore the Angular packages in any warning', () => { it('should mention the command to restore the Angular packages in any warning', () => {

View File

@ -45,6 +45,11 @@ module.exports = new Package('angular-base', [
.factory(require('./post-processors/add-image-dimensions')) .factory(require('./post-processors/add-image-dimensions'))
.factory(require('./post-processors/auto-link-code')) .factory(require('./post-processors/auto-link-code'))
// Configure jsdoc-style tag parsing
.config(function(inlineTagProcessor) {
inlineTagProcessor.inlineTagDefinitions.push(require('./inline-tag-defs/custom-search-defs/'));
})
.config(function(checkAnchorLinksProcessor) { .config(function(checkAnchorLinksProcessor) {
// This is disabled here to prevent false negatives for the `docs-watch` task. // This is disabled here to prevent false negatives for the `docs-watch` task.
// It is re-enabled in the main `angular.io-package` // It is re-enabled in the main `angular.io-package`

View File

@ -0,0 +1,9 @@
module.exports = {
name: 'searchKeywords',
description: 'A shorthand for creating elements with search terms. Usage: `{@searchKeywords term1 term2 termN }`',
handler: function(doc, tagName, tagDescription) {
doc.searchKeywords = tagDescription;
return doc;
}
};

View File

@ -91,7 +91,8 @@ module.exports = function generateKeywordsProcessor(log, readFilesProcessor) {
titleWords: tokenize(doc.searchTitle).join(' '), titleWords: tokenize(doc.searchTitle).join(' '),
headingWords: headingWords.sort().join(' '), headingWords: headingWords.sort().join(' '),
keywords: words.sort().join(' '), keywords: words.sort().join(' '),
members: members.sort().join(' ') members: members.sort().join(' '),
topics: doc.searchKeywords
}; };
}); });

View File

@ -4,10 +4,14 @@ module.exports = function processCliCommands(createDocMessage) {
$runBefore: ['rendering-docs'], $runBefore: ['rendering-docs'],
$process(docs) { $process(docs) {
const navigationDoc = docs.find(doc => doc.docType === 'navigation-json'); const navigationDoc = docs.find(doc => doc.docType === 'navigation-json');
const navigationNode = navigationDoc && navigationDoc.data['SideNav'].find(node => node.children && node.children.length && node.children[0].url === 'cli'); const navigationNode = navigationDoc &&
navigationDoc.data['SideNav'].find(
node => node.children && node.children.length && node.children[0].url === 'cli');
if (!navigationNode) { if (!navigationNode) {
throw new Error(createDocMessage('Missing `cli` url - CLI Commands must include a first child node with url set at `cli`', navigationDoc)); throw new Error(createDocMessage(
'Missing `cli` url - CLI Commands must include a first child node with url set at `cli`',
navigationDoc));
} }
docs.forEach(doc => { docs.forEach(doc => {
@ -15,26 +19,31 @@ module.exports = function processCliCommands(createDocMessage) {
doc.names = collectNames(doc.name, doc.commandAliases); doc.names = collectNames(doc.name, doc.commandAliases);
// Recursively process the options // Recursively process the options
processOptions(doc, doc.options); const optionKeywords = new Set();
processOptions(doc, doc.options, optionKeywords);
doc.optionKeywords = Array.from(optionKeywords).join(' ');
// Add to navigation doc // Add to navigation doc
navigationNode.children.push({ url: doc.path, title: `ng ${doc.name}` }); navigationNode.children.push({url: doc.path, title: `ng ${doc.name}`});
} }
}); });
} }
}; };
}; };
function processOptions(container, options) { function processOptions(container, options, optionKeywords) {
container.positionalOptions = []; container.positionalOptions = [];
container.namedOptions = []; container.namedOptions = [];
options.forEach(option => { options.forEach(option => {
// Ignore any hidden options // Ignore any hidden options
if (option.hidden) { return; } if (option.hidden) {
return;
}
option.types = option.types || [option.type]; option.types = option.types || [option.type];
option.names = collectNames(option.name, option.aliases); option.names = collectNames(option.name, option.aliases);
option.names.forEach(name => optionKeywords.add(name));
// Now work out what kind of option it is: positional/named // Now work out what kind of option it is: positional/named
if (option.positional !== undefined) { if (option.positional !== undefined) {
@ -48,7 +57,8 @@ function processOptions(container, options) {
option.subcommands = getValues(option.subcommands); option.subcommands = getValues(option.subcommands);
option.subcommands.forEach(subcommand => { option.subcommands.forEach(subcommand => {
subcommand.names = collectNames(subcommand.name, subcommand.aliases); subcommand.names = collectNames(subcommand.name, subcommand.aliases);
processOptions(subcommand, subcommand.options); subcommand.names.forEach(name => optionKeywords.add(name));
processOptions(subcommand, subcommand.options, optionKeywords);
}); });
} }
}); });
@ -57,7 +67,7 @@ function processOptions(container, options) {
} }
function collectNames(name, aliases) { function collectNames(name, aliases) {
return [name].concat(aliases); return [name].concat(aliases || []);
} }
function getValues(obj) { function getValues(obj) {

View File

@ -7,11 +7,7 @@ describe('processCliCommands processor', () => {
const navigationStub = { const navigationStub = {
docType: 'navigation-json', docType: 'navigation-json',
data: { data: {SideNav: [{children: [{'url': 'cli'}]}]}
SideNav: [{
children: [{'url': 'cli'}]
}]
}
}; };
beforeEach(() => { beforeEach(() => {
@ -21,17 +17,13 @@ describe('processCliCommands processor', () => {
createDocMessage = injector.get('createDocMessage'); createDocMessage = injector.get('createDocMessage');
}); });
it('should be available on the injector', () => { it('should be available on the injector', () => { expect(processor.$process).toBeDefined(); });
expect(processor.$process).toBeDefined();
});
it('should run after the correct processor', () => { it('should run after the correct processor',
expect(processor.$runAfter).toEqual(['extra-docs-added']); () => { expect(processor.$runAfter).toEqual(['extra-docs-added']); });
});
it('should run before the correct processor', () => { it('should run before the correct processor',
expect(processor.$runBefore).toEqual(['rendering-docs']); () => { expect(processor.$runBefore).toEqual(['rendering-docs']); });
});
it('should collect the names (name + aliases)', () => { it('should collect the names (name + aliases)', () => {
const doc = { const doc = {
@ -51,16 +43,16 @@ describe('processCliCommands processor', () => {
name: 'name', name: 'name',
commandAliases: [], commandAliases: [],
options: [ options: [
{ name: 'option1' }, {name: 'option1'},
{ name: 'option2', hidden: true }, {name: 'option2', hidden: true},
{ name: 'option3' }, {name: 'option3'},
{ name: 'option4', hidden: true }, {name: 'option4', hidden: true},
], ],
}; };
processor.$process([doc, navigationStub]); processor.$process([doc, navigationStub]);
expect(doc.namedOptions).toEqual([ expect(doc.namedOptions).toEqual([
jasmine.objectContaining({ name: 'option1' }), jasmine.objectContaining({name: 'option1'}),
jasmine.objectContaining({ name: 'option3' }), jasmine.objectContaining({name: 'option3'}),
]); ]);
}); });
@ -70,18 +62,18 @@ describe('processCliCommands processor', () => {
name: 'name', name: 'name',
commandAliases: [], commandAliases: [],
options: [ options: [
{ name: 'named1' }, {name: 'named1'},
{ name: 'positional1', positional: 0}, {name: 'positional1', positional: 0},
{ name: 'named2', hidden: true }, {name: 'named2', hidden: true},
{ name: 'positional2', hidden: true, positional: 1}, {name: 'positional2', hidden: true, positional: 1},
], ],
}; };
processor.$process([doc, navigationStub]); processor.$process([doc, navigationStub]);
expect(doc.positionalOptions).toEqual([ expect(doc.positionalOptions).toEqual([
jasmine.objectContaining({ name: 'positional1', positional: 0}), jasmine.objectContaining({name: 'positional1', positional: 0}),
]); ]);
expect(doc.namedOptions).toEqual([ expect(doc.namedOptions).toEqual([
jasmine.objectContaining({ name: 'named1' }), jasmine.objectContaining({name: 'named1'}),
]); ]);
}); });
@ -91,18 +83,34 @@ describe('processCliCommands processor', () => {
name: 'name', name: 'name',
commandAliases: [], commandAliases: [],
options: [ options: [
{ name: 'c' }, {name: 'c'},
{ name: 'a' }, {name: 'a'},
{ name: 'b' }, {name: 'b'},
], ],
}; };
processor.$process([doc, navigationStub]); processor.$process([doc, navigationStub]);
expect(doc.namedOptions).toEqual([ expect(doc.namedOptions).toEqual([
jasmine.objectContaining({ name: 'a' }), jasmine.objectContaining({name: 'a'}),
jasmine.objectContaining({ name: 'b' }), jasmine.objectContaining({name: 'b'}),
jasmine.objectContaining({ name: 'c' }), jasmine.objectContaining({name: 'c'}),
]); ]);
}); });
it('should collect potential search terms from options for indexing', () => {
const doc = {
docType: 'cli-command',
name: 'name',
commandAliases: [],
options: [
{name: 'named1'},
{name: 'positional1', positional: 0},
{name: 'named2', hidden: true},
{name: 'positional2', hidden: true, positional: 1},
],
};
processor.$process([doc, navigationStub]);
expect(doc.optionKeywords).toEqual('named1 positional1');
});
}); });
describe('subcommands', () => { describe('subcommands', () => {
@ -117,15 +125,15 @@ describe('processCliCommands processor', () => {
subcommand1: { subcommand1: {
name: 'subcommand1', name: 'subcommand1',
options: [ options: [
{ name: 'subcommand1-option1' }, {name: 'subcommand1-option1'},
{ name: 'subcommand1-option2' }, {name: 'subcommand1-option2'},
], ],
}, },
subcommand2: { subcommand2: {
name: 'subcommand2', name: 'subcommand2',
options: [ options: [
{ name: 'subcommand2-option1' }, {name: 'subcommand2-option1'},
{ name: 'subcommand2-option2' }, {name: 'subcommand2-option2'},
], ],
} }
}, },
@ -133,8 +141,8 @@ describe('processCliCommands processor', () => {
}; };
processor.$process([doc, navigationStub]); processor.$process([doc, navigationStub]);
expect(doc.options[0].subcommands).toEqual([ expect(doc.options[0].subcommands).toEqual([
jasmine.objectContaining({ name: 'subcommand1' }), jasmine.objectContaining({name: 'subcommand1'}),
jasmine.objectContaining({ name: 'subcommand2' }), jasmine.objectContaining({name: 'subcommand2'}),
]); ]);
}); });
@ -149,15 +157,15 @@ describe('processCliCommands processor', () => {
subcommand1: { subcommand1: {
name: 'subcommand1', name: 'subcommand1',
options: [ options: [
{ name: 'subcommand1-option1' }, {name: 'subcommand1-option1'},
{ name: 'subcommand1-option2', hidden: true }, {name: 'subcommand1-option2', hidden: true},
], ],
}, },
subcommand2: { subcommand2: {
name: 'subcommand2', name: 'subcommand2',
options: [ options: [
{ name: 'subcommand2-option1', hidden: true }, {name: 'subcommand2-option1', hidden: true},
{ name: 'subcommand2-option2' }, {name: 'subcommand2-option2'},
], ],
} }
}, },
@ -165,10 +173,10 @@ describe('processCliCommands processor', () => {
}; };
processor.$process([doc, navigationStub]); processor.$process([doc, navigationStub]);
expect(doc.options[0].subcommands[0].namedOptions).toEqual([ expect(doc.options[0].subcommands[0].namedOptions).toEqual([
jasmine.objectContaining({ name: 'subcommand1-option1' }), jasmine.objectContaining({name: 'subcommand1-option1'}),
]); ]);
expect(doc.options[0].subcommands[1].namedOptions).toEqual([ expect(doc.options[0].subcommands[1].namedOptions).toEqual([
jasmine.objectContaining({ name: 'subcommand2-option2' }), jasmine.objectContaining({name: 'subcommand2-option2'}),
]); ]);
}); });
@ -183,15 +191,15 @@ describe('processCliCommands processor', () => {
subcommand1: { subcommand1: {
name: 'subcommand1', name: 'subcommand1',
options: [ options: [
{ name: 'subcommand1-option1' }, {name: 'subcommand1-option1'},
{ name: 'subcommand1-option2', positional: 0 }, {name: 'subcommand1-option2', positional: 0},
], ],
}, },
subcommand2: { subcommand2: {
name: 'subcommand2', name: 'subcommand2',
options: [ options: [
{ name: 'subcommand2-option1', hidden: true }, {name: 'subcommand2-option1', hidden: true},
{ name: 'subcommand2-option2', hidden: true, positional: 1 }, {name: 'subcommand2-option2', hidden: true, positional: 1},
], ],
} }
}, },
@ -199,10 +207,10 @@ describe('processCliCommands processor', () => {
}; };
processor.$process([doc, navigationStub]); processor.$process([doc, navigationStub]);
expect(doc.options[0].subcommands[0].positionalOptions).toEqual([ expect(doc.options[0].subcommands[0].positionalOptions).toEqual([
jasmine.objectContaining({ name: 'subcommand1-option2', positional: 0}), jasmine.objectContaining({name: 'subcommand1-option2', positional: 0}),
]); ]);
expect(doc.options[0].subcommands[0].namedOptions).toEqual([ expect(doc.options[0].subcommands[0].namedOptions).toEqual([
jasmine.objectContaining({ name: 'subcommand1-option1' }), jasmine.objectContaining({name: 'subcommand1-option1'}),
]); ]);
expect(doc.options[0].subcommands[1].positionalOptions).toEqual([]); expect(doc.options[0].subcommands[1].positionalOptions).toEqual([]);
@ -220,9 +228,9 @@ describe('processCliCommands processor', () => {
subcommand1: { subcommand1: {
name: 'subcommand1', name: 'subcommand1',
options: [ options: [
{ name: 'c' }, {name: 'c'},
{ name: 'a' }, {name: 'a'},
{ name: 'b' }, {name: 'b'},
] ]
} }
} }
@ -230,47 +238,42 @@ describe('processCliCommands processor', () => {
}; };
processor.$process([doc, navigationStub]); processor.$process([doc, navigationStub]);
expect(doc.options[0].subcommands[0].namedOptions).toEqual([ expect(doc.options[0].subcommands[0].namedOptions).toEqual([
jasmine.objectContaining({ name: 'a' }), jasmine.objectContaining({name: 'a'}),
jasmine.objectContaining({ name: 'b' }), jasmine.objectContaining({name: 'b'}),
jasmine.objectContaining({ name: 'c' }), jasmine.objectContaining({name: 'c'}),
]); ]);
}); });
}); });
it('should add the command to the CLI node in the navigation doc if there is a first child node with a `cli` url', () => { it('should add the command to the CLI node in the navigation doc if there is a first child node with a `cli` url',
const command = { () => {
docType: 'cli-command', const command = {
name: 'command1', docType: 'cli-command',
commandAliases: ['alias1', 'alias2'], name: 'command1',
options: [], commandAliases: ['alias1', 'alias2'],
path: 'cli/command1', options: [],
}; path: 'cli/command1',
const navigation = { };
docType: 'navigation-json', const navigation = {
data: { docType: 'navigation-json',
SideNav: [ data: {
{ url: 'some/page', title: 'Some Page' }, SideNav: [
{ {url: 'some/page', title: 'Some Page'}, {
title: 'CLI Commands', title: 'CLI Commands',
tooltip: 'Angular CLI command reference', tooltip: 'Angular CLI command reference',
children: [ children: [{'title': 'Overview', 'url': 'cli'}]
{ },
'title': 'Overview', {url: 'other/page', title: 'Other Page'}
'url': 'cli' ]
} }
] };
}, processor.$process([command, navigation]);
{ url: 'other/page', title: 'Other Page' } expect(navigation.data.SideNav[1].title).toEqual('CLI Commands');
] expect(navigation.data.SideNav[1].children).toEqual([
} {url: 'cli', title: 'Overview'},
}; {url: 'cli/command1', title: 'ng command1'},
processor.$process([command, navigation]); ]);
expect(navigation.data.SideNav[1].title).toEqual('CLI Commands'); });
expect(navigation.data.SideNav[1].children).toEqual([
{ url: 'cli', title: 'Overview' },
{ url: 'cli/command1', title: 'ng command1' },
]);
});
it('should complain if there is no child with `cli` url', () => { it('should complain if there is no child with `cli` url', () => {
const command = { const command = {
@ -284,21 +287,50 @@ describe('processCliCommands processor', () => {
docType: 'navigation-json', docType: 'navigation-json',
data: { data: {
SideNav: [ SideNav: [
{ url: 'some/page', title: 'Some Page' }, {url: 'some/page', title: 'Some Page'}, {
{
title: 'CLI Commands', title: 'CLI Commands',
tooltip: 'Angular CLI command reference', tooltip: 'Angular CLI command reference',
children: [ children: [{'title': 'Overview', 'url': 'client'}]
{
'title': 'Overview',
'url': 'client'
}
]
}, },
{ url: 'other/page', title: 'Other Page' } {url: 'other/page', title: 'Other Page'}
] ]
} }
}; };
expect(() => processor.$process([command, navigation])).toThrowError(createDocMessage('Missing `cli` url - CLI Commands must include a first child node with url set at `cli`', navigation)); expect(() => processor.$process([command, navigation]))
.toThrowError(createDocMessage(
'Missing `cli` url - CLI Commands must include a first child node with url set at `cli`',
navigation));
}); });
it('should collect potential search terms from options for indexing', () => {
const doc = {
docType: 'cli-command',
name: 'name',
commandAliases: [],
options: [{
name: 'supercommand',
subcommands: {
subcommand1: {
name: 'subcommand1',
options: [
{name: 'subcommand1-option1'},
{name: 'subcommand1-option2'},
],
},
subcommand2: {
name: 'subcommand2',
options: [
{name: 'subcommand2-option1'},
{name: 'subcommand2-option2'},
],
}
},
}],
};
processor.$process([doc, navigationStub]);
expect(doc.optionKeywords)
.toEqual(
'supercommand subcommand1 subcommand1-option1 subcommand1-option2 subcommand2 subcommand2-option1 subcommand2-option2');
});
}); });

38
dev-infra/BUILD.bazel Normal file
View File

@ -0,0 +1,38 @@
load("@build_bazel_rules_nodejs//:index.bzl", "pkg_npm")
load("@npm_bazel_typescript//:index.bzl", "ts_library")
load("@npm_bazel_rollup//:index.bzl", "rollup_bundle")
ts_library(
name = "cli",
srcs = [
"cli.ts",
],
deps = [
"//dev-infra/pullapprove",
"@npm//@types/node",
],
)
rollup_bundle(
name = "bundle",
config_file = "rollup.config.js",
entry_point = ":cli.ts",
format = "umd",
sourcemap = "hidden",
deps = [
":cli",
"@npm//rollup-plugin-commonjs",
"@npm//rollup-plugin-node-resolve",
],
)
pkg_npm(
name = "npm_package",
srcs = [
"package.json",
],
visibility = ["//visibility:public"],
deps = [
":bundle",
],
)

20
dev-infra/cli.ts Normal file
View File

@ -0,0 +1,20 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {verify} from './pullapprove/verify';
const args = process.argv.slice(2);
// TODO(josephperrott): Set up proper cli flag/command handling
switch (args[0]) {
case 'pullapprove:verify':
verify();
break;
default:
console.info('No commands were matched');
}

10
dev-infra/package.json Normal file
View File

@ -0,0 +1,10 @@
{
"name": "@angular/dev-infra-private",
"version": "0.0.0",
"description": "INTERNAL USE ONLY - Angular internal DevInfra tooling/scripts - INTERNAL USE ONLY",
"license": "MIT",
"private": true,
"bin": {
"ng-dev": "./bundle.js"
}
}

View File

@ -0,0 +1,19 @@
load("@npm_bazel_typescript//:index.bzl", "ts_library")
ts_library(
name = "pullapprove",
srcs = [
"verify.ts",
],
visibility = ["//dev-infra:__subpackages__"],
deps = [
"@npm//@types/minimatch",
"@npm//@types/node",
"@npm//@types/shelljs",
"@npm//@types/yaml",
"@npm//minimatch",
"@npm//shelljs",
"@npm//tslib",
"@npm//yaml",
],
)

View File

@ -0,0 +1,215 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {readFileSync} from 'fs';
import {IMinimatch, Minimatch} from 'minimatch';
import * as path from 'path';
import {cd, exec, set} from 'shelljs';
import {parse as parseYaml} from 'yaml';
interface GlobMatcher {
group: string;
glob: string;
matcher: IMinimatch;
matchCount: number;
}
export function verify() {
// Exit early on shelljs errors
set('-e');
// Regex Matcher for contains_any_globs conditions
const CONTAINS_ANY_GLOBS_REGEX = /^'([^']+)',?$/;
// Full path of the angular project directory
const ANGULAR_PROJECT_DIR = process.cwd();
// Change to the Angular project directory
cd(ANGULAR_PROJECT_DIR);
// Whether to log verbosely
const VERBOSE_MODE = process.argv.includes('-v');
// Full path to PullApprove config file
const PULL_APPROVE_YAML_PATH = path.resolve(ANGULAR_PROJECT_DIR, '.pullapprove.yml');
// All relative path file names in the git repo, this is retrieved using git rather
// that a glob so that we only get files that are checked in, ignoring things like
// node_modules, .bazelrc.user, etc
const ALL_FILES = exec('git ls-tree --full-tree -r --name-only HEAD', {silent: true})
.trim()
.split('\n')
.filter((_: string) => !!_);
if (!ALL_FILES.length) {
console.error(
`No files were found to be in the git tree, did you run this command from \n` +
`inside the angular repository?`);
process.exit(1);
}
/** Gets the glob matching information from each group's condition. */
function getGlobMatchersFromCondition(
groupName: string, condition: string): [GlobMatcher[], string[]] {
const trimmedCondition = condition.trim();
const globMatchers: GlobMatcher[] = [];
const badConditionLines: string[] = [];
// If the condition starts with contains_any_globs, evaluate all of the globs
if (trimmedCondition.startsWith('contains_any_globs')) {
trimmedCondition.split('\n')
.slice(1, -1)
.map(glob => {
const trimmedGlob = glob.trim();
const match = trimmedGlob.match(CONTAINS_ANY_GLOBS_REGEX);
if (!match) {
badConditionLines.push(trimmedGlob);
return '';
}
return match[1];
})
.filter(globString => !!globString)
.forEach(globString => globMatchers.push({
group: groupName,
glob: globString,
matcher: new Minimatch(globString, {dot: true}),
matchCount: 0,
}));
}
return [globMatchers, badConditionLines];
}
/** Create logs for each review group. */
function logGroups(groups: Map<string, Map<string, GlobMatcher>>) {
Array.from(groups.entries()).sort().forEach(([groupName, globs]) => {
console.groupCollapsed(groupName);
Array.from(globs.values())
.sort((a, b) => b.matchCount - a.matchCount)
.forEach(glob => console.info(`${glob.glob} - ${glob.matchCount}`));
console.groupEnd();
});
}
/** Logs a header within a text drawn box. */
function logHeader(...params: string[]) {
const totalWidth = 80;
const fillWidth = totalWidth - 2;
const headerText = params.join(' ').substr(0, fillWidth);
const leftSpace = Math.ceil((fillWidth - headerText.length) / 2);
const rightSpace = fillWidth - leftSpace - headerText.length;
const fill = (count: number, content: string) => content.repeat(count);
console.info(`${fill(fillWidth, '─')}`);
console.info(`${fill(leftSpace, ' ')}${headerText}${fill(rightSpace, ' ')}`);
console.info(`${fill(fillWidth, '─')}`);
}
/** Runs the pull approve verification check on provided files. */
function runVerification(files: string[]) {
// All of the globs created for each group's conditions.
const allGlobs: GlobMatcher[] = [];
// The pull approve config file.
const pullApprove = readFileSync(PULL_APPROVE_YAML_PATH, {encoding: 'utf8'});
// All of the PullApprove groups, parsed from the PullApprove yaml file.
const parsedPullApproveGroups =
parseYaml(pullApprove).groups as{[key: string]: {conditions: string}};
// All files which were found to match a condition in PullApprove.
const matchedFiles = new Set<string>();
// All files which were not found to match a condition in PullApprove.
const unmatchedFiles = new Set<string>();
// All PullApprove groups which matched at least one file.
const matchedGroups = new Map<string, Map<string, GlobMatcher>>();
// All PullApprove groups which did not match at least one file.
const unmatchedGroups = new Map<string, Map<string, GlobMatcher>>();
// All condition lines which were not able to be correctly parsed, by group.
const badConditionLinesByGroup = new Map<string, string[]>();
// Total number of condition lines which were not able to be correctly parsed.
let badConditionLineCount = 0;
// Get all of the globs from the PullApprove group conditions.
Object.entries(parsedPullApproveGroups).forEach(([groupName, group]) => {
for (const condition of group.conditions) {
const [matchers, badConditions] = getGlobMatchersFromCondition(groupName, condition);
if (badConditions.length) {
badConditionLinesByGroup.set(groupName, badConditions);
badConditionLineCount += badConditions.length;
}
allGlobs.push(...matchers);
}
});
if (badConditionLineCount) {
console.info(`Discovered ${badConditionLineCount} parsing errors in PullApprove conditions`);
console.info(`Attempted parsing using: ${CONTAINS_ANY_GLOBS_REGEX}`);
console.info();
console.info(`Unable to properly parse the following line(s) by group:`);
badConditionLinesByGroup.forEach((badConditionLines, groupName) => {
console.info(`- ${groupName}:`);
badConditionLines.forEach(line => console.info(` ${line}`));
});
console.info();
console.info(
`Please correct the invalid conditions, before PullApprove verification can be completed`);
process.exit(1);
}
// Check each file for if it is matched by a PullApprove condition.
for (let file of files) {
const matched = allGlobs.filter(glob => glob.matcher.match(file));
matched.length ? matchedFiles.add(file) : unmatchedFiles.add(file);
matched.forEach(glob => glob.matchCount++);
}
// Add each glob for each group to a map either matched or unmatched.
allGlobs.forEach(glob => {
const groups = glob.matchCount ? matchedGroups : unmatchedGroups;
const globs = groups.get(glob.group) || new Map<string, GlobMatcher>();
// Set the globs map in the groups map
groups.set(glob.group, globs);
// Set the glob in the globs map
globs.set(glob.glob, glob);
});
// PullApprove is considered verified if no files or groups are found to be unsed.
const verificationSucceeded = !(unmatchedFiles.size || unmatchedGroups.size);
/**
* Overall result
*/
logHeader('Result');
if (verificationSucceeded) {
console.info('PullApprove verification succeeded!');
} else {
console.info(`PullApprove verification failed.\n`);
console.info(`Please update '.pullapprove.yml' to ensure that all necessary`);
console.info(`files/directories have owners and all patterns that appear in`);
console.info(`the file correspond to actual files/directories in the repo.`);
}
/**
* File by file Summary
*/
logHeader('PullApprove file match results');
console.groupCollapsed(`Matched Files (${matchedFiles.size} files)`);
VERBOSE_MODE && matchedFiles.forEach(file => console.info(file));
console.groupEnd();
console.groupCollapsed(`Unmatched Files (${unmatchedFiles.size} files)`);
unmatchedFiles.forEach(file => console.info(file));
console.groupEnd();
/**
* Group by group Summary
*/
logHeader('PullApprove group matches');
console.groupCollapsed(`Matched Groups (${matchedGroups.size} groups)`);
VERBOSE_MODE && logGroups(matchedGroups);
console.groupEnd();
console.groupCollapsed(`Unmatched Groups (${unmatchedGroups.size} groups)`);
logGroups(unmatchedGroups);
console.groupEnd();
// Provide correct exit code based on verification success.
process.exit(verificationSucceeded ? 0 : 1);
}
runVerification(ALL_FILES);
}

View File

@ -0,0 +1,16 @@
const node = require('rollup-plugin-node-resolve');
const commonjs = require('rollup-plugin-commonjs');
module.exports = {
external: ['shelljs', 'minimatch', 'yaml'],
preferBuiltins: true,
output: {
banner: "#!/usr/bin/env node",
},
plugins: [
node({
mainFields: ['browser', 'es2015', 'module', 'jsnext:main', 'main'],
}),
commonjs(),
],
};

View File

@ -4,7 +4,7 @@ Currently all changes to Ivy are validated against the test suite of the
`angular/components` repository. In order to debug the `components-repo-unit-tests` CI `angular/components` repository. In order to debug the `components-repo-unit-tests` CI
job, the following steps can be used: job, the following steps can be used:
1\) Build the Ivy package output by running `node ./scripts/build-ivy-npm-packages.js` in 1\) Build the Ivy package output by running `node ./scripts/build/build-ivy-npm-packages.js` in
the `angular/angular` repo. the `angular/angular` repo.
2\) Clone the `angular/components` repository if not done yet ([quick link to repo](https://github.com/angular/components)). 2\) Clone the `angular/components` repository if not done yet ([quick link to repo](https://github.com/angular/components)).

View File

@ -69,7 +69,7 @@ yarn install
To build Angular run: To build Angular run:
```shell ```shell
node ./scripts/build-packages-dist.js node ./scripts/build/build-packages-dist.js
``` ```
* Results are put in the `dist/packages-dist` folder. * Results are put in the `dist/packages-dist` folder.
@ -129,7 +129,7 @@ where `$ANGULAR_PATH` is an environment variable of the absolute path of your An
You can check that your code is properly formatted and adheres to coding style by running: You can check that your code is properly formatted and adheres to coding style by running:
``` shell ``` shell
$ yarn gulp lint $ yarn lint
``` ```
## Publishing Snapshot Builds ## Publishing Snapshot Builds
@ -190,7 +190,7 @@ c. Some package managers (such as `pnpm` or `yarn pnp`) might not work correctly
### Publishing to GitHub repos ### Publishing to GitHub repos
You can also manually publish `*-builds` snapshots just like our CircleCI build does for upstream You can also manually publish `*-builds` snapshots just like our CircleCI build does for upstream
builds. Before being able to publish the packages, you need to build them locally by running the builds. Before being able to publish the packages, you need to build them locally by running the
`./scripts/build-packages-dist.js` script. `./scripts/build/build-packages-dist.js` script.
First time, you need to create the GitHub repositories: First time, you need to create the GitHub repositories:

View File

@ -21,6 +21,7 @@ The components have a clear piece of source code associated with it within the `
browser-platforms are very intertwined, we will be treating them as one browser-platforms are very intertwined, we will be treating them as one
* `comp: ivy` - a subset of core representing the new Ivy renderer. * `comp: ivy` - a subset of core representing the new Ivy renderer.
* `comp: ngcc` - a subset of ivy representing the [Angular Compatibility Compiler](../packages/compiler-cli/ngcc/README.md) * `comp: ngcc` - a subset of ivy representing the [Angular Compatibility Compiler](../packages/compiler-cli/ngcc/README.md)
* `comp: ve` - a subset of `core & compiler` representing changes specific to ViewEngine (legacy compiler/renderer).
* `comp: docs-infra` - the angular.io application and docs-related tooling * `comp: docs-infra` - the angular.io application and docs-related tooling
* `comp: elements` * `comp: elements`
* `comp: forms` * `comp: forms`

View File

@ -45,11 +45,9 @@ gulp.task('format:changed', ['format:untracked', 'format:diff']);
// Alias for `format:changed` that formerly formatted all files. // Alias for `format:changed` that formerly formatted all files.
gulp.task('format', ['format:changed']); gulp.task('format', ['format:changed']);
gulp.task('lint', ['format:enforce', 'validate-commit-messages', 'tslint']); gulp.task('lint', ['format:enforce', 'validate-commit-messages']);
gulp.task('tslint', ['tools:build'], loadTask('lint'));
gulp.task('validate-commit-messages', loadTask('validate-commit-message')); gulp.task('validate-commit-messages', loadTask('validate-commit-message'));
gulp.task('source-map-test', loadTask('source-map-test')); gulp.task('source-map-test', loadTask('source-map-test'));
gulp.task('tools:build', loadTask('tools-build'));
gulp.task('changelog', loadTask('changelog')); gulp.task('changelog', loadTask('changelog'));
gulp.task('changelog:zonejs', loadTask('changelog-zonejs')); gulp.task('changelog:zonejs', loadTask('changelog-zonejs'));
gulp.task('check-env', () => {/* this is a noop because the env test ran already above */}); gulp.task('check-env', () => {/* this is a noop because the env test ran already above */});

View File

@ -4,7 +4,7 @@ This directory contains end-to-end tests for Angular. Each directory is a self-c
that exactly mimics how a user might expect Angular to work, so they allow high-fidelity that exactly mimics how a user might expect Angular to work, so they allow high-fidelity
reproductions of real-world issues. reproductions of real-world issues.
For this to work, we first build the Angular distribution via `./scripts/build-packages-dist.js`, then For this to work, we first build the Angular distribution via `./scripts/build/build-packages-dist.js`, then
install the distribution into each app. install the distribution into each app.
To test Angular CLI applications, we use the `cli-hello-world-*` integration tests. To test Angular CLI applications, we use the `cli-hello-world-*` integration tests.

View File

@ -60,7 +60,7 @@
"uncompressed": { "uncompressed": {
"bundle": "TODO(i): temporarily increase the payload size limit from 105779 - this is due to a closure issue related to ESM reexports that still needs to be investigated", "bundle": "TODO(i): temporarily increase the payload size limit from 105779 - this is due to a closure issue related to ESM reexports that still needs to be investigated",
"bundle": "TODO(i): we should define ngDevMode to false in Closure, but --define only works in the global scope.", "bundle": "TODO(i): we should define ngDevMode to false in Closure, but --define only works in the global scope.",
"bundle": 175498 "bundle": 170618
} }
} }
} }

View File

@ -19,6 +19,7 @@
"@angular/router": "file:../../node_modules/@angular/router", "@angular/router": "file:../../node_modules/@angular/router",
"@bazel/bazel": "file:../../node_modules/@bazel/bazel", "@bazel/bazel": "file:../../node_modules/@bazel/bazel",
"@types/node": "file:../../node_modules/@types/node", "@types/node": "file:../../node_modules/@types/node",
"patch-package": "^6.2.1",
"protractor": "file:../../node_modules/protractor", "protractor": "file:../../node_modules/protractor",
"puppeteer": "file:../../node_modules/puppeteer", "puppeteer": "file:../../node_modules/puppeteer",
"typescript": "file:../../node_modules/typescript", "typescript": "file:../../node_modules/typescript",
@ -29,6 +30,7 @@
"**/webdriver-manager": "file:../../node_modules/webdriver-manager" "**/webdriver-manager": "file:../../node_modules/webdriver-manager"
}, },
"scripts": { "scripts": {
"test": "./test.sh" "test": "./test.sh",
"postinstall": "patch-package"
} }
} }

View File

@ -0,0 +1,25 @@
diff --git a/node_modules/@angular/bazel/src/builders/files/WORKSPACE.template b/node_modules/@angular/bazel/src/builders/files/WORKSPACE.template
index 9aad043..e767dc6 100755
--- a/node_modules/@angular/bazel/src/builders/files/WORKSPACE.template
+++ b/node_modules/@angular/bazel/src/builders/files/WORKSPACE.template
@@ -10,7 +10,7 @@
# imports also make sense when referencing the published package.
workspace(
name = "project",
- managed_directories = {"@npm": ["node_modules"]},
+ # managed_directories = {"@npm": ["node_modules"]},
)
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
@@ -67,6 +67,11 @@ node_repositories(
yarn_install(
name = "npm",
package_json = "//:package.json",
+ # Turn off symlink_node_modules here as it causes flakiness with missing
+ # files in node_modules.
+ # TODO: track down the root cause of the flakiness; current suspect is that
+ # it is an issue with managed_directories when resources are limited
+ symlink_node_modules = False,
yarn_lock = "//:yarn.lock",
)

View File

@ -38,7 +38,7 @@ function installLocalPackages() {
local_packages+=("puppeteer@file:${pwd}/../node_modules/puppeteer") local_packages+=("puppeteer@file:${pwd}/../node_modules/puppeteer")
local_packages+=("webdriver-manager@file:${pwd}/../node_modules/webdriver-manager") local_packages+=("webdriver-manager@file:${pwd}/../node_modules/webdriver-manager")
yarn add --ignore-scripts --silent "${local_packages[@]}" yarn add --ignore-scripts --silent "${local_packages[@]}" --cache-folder ./.yarn_local_cache
} }
function patchKarmaConf() { function patchKarmaConf() {
@ -58,6 +58,8 @@ function testBazel() {
# Create project # Create project
ng new demo --collection=@angular/bazel --routing --skip-git --skip-install --style=scss ng new demo --collection=@angular/bazel --routing --skip-git --skip-install --style=scss
cd demo cd demo
# Use a local yarn cache folder so we don't access the global yarn cache
mkdir .yarn_local_cache
patchKarmaConf patchKarmaConf
patchProtractorConf patchProtractorConf
installLocalPackages installLocalPackages
@ -79,7 +81,7 @@ function testNonBazel() {
# disable CLI's version check (if version is 0.0.0, then no version check happens) # disable CLI's version check (if version is 0.0.0, then no version check happens)
yarn --cwd node_modules/@angular/cli version --new-version 0.0.0 --no-git-tag-version yarn --cwd node_modules/@angular/cli version --new-version 0.0.0 --no-git-tag-version
# re-add build-angular # re-add build-angular
yarn add --dev file:../node_modules/@angular-devkit/build-angular yarn add --dev file:../node_modules/@angular-devkit/build-angular --cache-folder ./.yarn_local_cache
ng build --progress=false ng build --progress=false
ng test --progress=false --watch=false ng test --progress=false --watch=false
ng e2e --port 0 --configuration=production --webdriver-update=false ng e2e --port 0 --configuration=production --webdriver-update=false

View File

@ -2,26 +2,26 @@
# yarn lockfile v1 # yarn lockfile v1
"@angular-devkit/architect@0.900.0-rc.14": "@angular-devkit/architect@0.900.3":
version "0.900.0-rc.14" version "0.900.3"
resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.900.0-rc.14.tgz#cfdbee7899b9addfd9d43c638b0dbc21188f0a79" resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.900.3.tgz#9c396733abd12fbb1d5bbc4542b2ee52418adb02"
integrity sha512-dgEc/zYE0uzv+m8JTdv3FDc7bViJKbxs8FY3zdkArc6MXIXpoMzgvveEEHvhrpO0iu6njW/xRSZYtYnTIY4xlw== integrity sha512-4UHc58Dlc5XHY3eiYSX9gytLyPNYixGSRwLcc/LRwuPgrmUFKPzCN3nwgB+9kc03/HN89CsJ1rS1scid6N6vxQ==
dependencies: dependencies:
"@angular-devkit/core" "9.0.0-rc.14" "@angular-devkit/core" "9.0.3"
rxjs "6.5.3" rxjs "6.5.3"
"@angular-devkit/build-angular@file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/angular-devkit_build-angular_archive.tar.gz": "@angular-devkit/build-angular@file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/angular-devkit_build-angular_archive.tar.gz":
version "0.900.0-rc.14" version "0.900.3"
resolved "file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/angular-devkit_build-angular_archive.tar.gz#b50ff9c17fafb2539c951ea4f3ad1e15ca15b67d" resolved "file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/angular-devkit_build-angular_archive.tar.gz#41069993f7a6f44dca0a7707f0c3b5ce0ec253d1"
dependencies: dependencies:
"@angular-devkit/architect" "0.900.0-rc.14" "@angular-devkit/architect" "0.900.3"
"@angular-devkit/build-optimizer" "0.900.0-rc.14" "@angular-devkit/build-optimizer" "0.900.3"
"@angular-devkit/build-webpack" "0.900.0-rc.14" "@angular-devkit/build-webpack" "0.900.3"
"@angular-devkit/core" "9.0.0-rc.14" "@angular-devkit/core" "9.0.3"
"@babel/core" "7.7.7" "@babel/core" "7.7.7"
"@babel/generator" "7.7.7" "@babel/generator" "7.7.7"
"@babel/preset-env" "7.7.7" "@babel/preset-env" "7.7.7"
"@ngtools/webpack" "9.0.0-rc.14" "@ngtools/webpack" "9.0.3"
ajv "6.10.2" ajv "6.10.2"
autoprefixer "9.7.1" autoprefixer "9.7.1"
babel-loader "8.0.6" babel-loader "8.0.6"
@ -76,10 +76,10 @@
webpack-subresource-integrity "1.3.4" webpack-subresource-integrity "1.3.4"
worker-plugin "3.2.0" worker-plugin "3.2.0"
"@angular-devkit/build-optimizer@0.900.0-rc.14": "@angular-devkit/build-optimizer@0.900.3":
version "0.900.0-rc.14" version "0.900.3"
resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.900.0-rc.14.tgz#e90e955e1daf5689ad198a5253134187c99b7b5a" resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.900.3.tgz#91f90c56affb0be9f7910dfc1d414f16c21c2c3f"
integrity sha512-MA2g8N9/cvzMvudEEjeaNV6STwSr8NI/znpv+nU6sQa4PdegIotBbqxGUmHMKtLH5cOwDy9hI47ANN+XADbIbQ== integrity sha512-VLAWtAXpOzOoYUJrN6sT90UdIdvrVIipkzGz7nfI1kscDvxUFwVZnsNNHtFinaY2SfZAunHhYQOA/B9FJ8WPdQ==
dependencies: dependencies:
loader-utils "1.2.3" loader-utils "1.2.3"
source-map "0.7.3" source-map "0.7.3"
@ -87,19 +87,19 @@
typescript "3.6.4" typescript "3.6.4"
webpack-sources "1.4.3" webpack-sources "1.4.3"
"@angular-devkit/build-webpack@0.900.0-rc.14": "@angular-devkit/build-webpack@0.900.3":
version "0.900.0-rc.14" version "0.900.3"
resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.900.0-rc.14.tgz#b932148f14ed0056f1885c98c330411a80d31331" resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.900.3.tgz#4a2fd13cebe190c091606e18397a1f7cccfab6bb"
integrity sha512-HvrDapIKr4k2a7Tf7MdW0miGOUUzHxRkGyDIWJBDXLbfOIt9BnhKfFGxP/SyDlwJnLyat9yYZjcDu1AI0E1Dmw== integrity sha512-9gSTLWf7yq/XBOec0CtZcjNMsC7L8IuVDProBQHps2SvTfr982DtHfEge95J2lc9BjRbqidv+phImFsQ1J3mFA==
dependencies: dependencies:
"@angular-devkit/architect" "0.900.0-rc.14" "@angular-devkit/architect" "0.900.3"
"@angular-devkit/core" "9.0.0-rc.14" "@angular-devkit/core" "9.0.3"
rxjs "6.5.3" rxjs "6.5.3"
"@angular-devkit/core@9.0.0-rc.14": "@angular-devkit/core@9.0.3":
version "9.0.0-rc.14" version "9.0.3"
resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-9.0.0-rc.14.tgz#5cff058750c0b063a6f5fa1a2e830f1f48ffa56b" resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-9.0.3.tgz#a027862d2edd981afcc6245176e9f27768c631c9"
integrity sha512-hFiKoAPtnOqqYv97Y22OgyeTFxjNU/6WDhmuXkfbZDKychvuBLDOdgUhL43heEzavSfCCl23E0JmilwCUcepmw== integrity sha512-3+abmv9K9d+BVgUAolYgoOqlGAA2Jb1pWo2biapSDG6KjUZHUCJdnsKigLtLorCdv0SrjTp56FFplkcqKsFQgA==
dependencies: dependencies:
ajv "6.10.2" ajv "6.10.2"
fast-json-stable-stringify "2.0.0" fast-json-stable-stringify "2.0.0"
@ -107,36 +107,36 @@
rxjs "6.5.3" rxjs "6.5.3"
source-map "0.7.3" source-map "0.7.3"
"@angular-devkit/schematics@9.0.0-rc.14": "@angular-devkit/schematics@9.0.3":
version "9.0.0-rc.14" version "9.0.3"
resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-9.0.0-rc.14.tgz#4605b1ee9f18b772094697f9b35258fdac76d4b3" resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-9.0.3.tgz#e65fa1ce08a3d5ef0af594b623024439c1110a0d"
integrity sha512-i/XTxo7hTXTFKus51Qry3rRGHL2uS4SgufGqdvOcy2qZbjyh/wt0UDOGJu/w8dcA9pJm+vFBLAbnro5oFyIsVw== integrity sha512-BQnZtFQPLZZOijhuEndtzL6cOnhaE8nNxupkRHavWohOMStnLsRyvVJj6JVDkf37wvT5koqTNjHhbdMxcCRc6A==
dependencies: dependencies:
"@angular-devkit/core" "9.0.0-rc.14" "@angular-devkit/core" "9.0.3"
ora "4.0.2" ora "4.0.2"
rxjs "6.5.3" rxjs "6.5.3"
"@angular/animations@file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/animations/npm_package_archive.tar.gz": "@angular/animations@file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/animations/npm_package_archive.tar.gz":
version "0.0.0" version "0.0.0"
resolved "file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/animations/npm_package_archive.tar.gz#3adb32242698999cb769934abccedd9f5c590036" resolved "file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/animations/npm_package_archive.tar.gz#068a466222bb8cc3ad83f6621f81f5ba43dbc60c"
"@angular/bazel@file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/bazel/npm_package_archive.tar.gz": "@angular/bazel@file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/bazel/npm_package_archive.tar.gz":
version "0.0.0" version "0.0.0"
resolved "file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/bazel/npm_package_archive.tar.gz#06940dc70222aa4abb87ca6bac032a197a02d578" resolved "file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/bazel/npm_package_archive.tar.gz#9a47371cd27ce5317c07b4386407d6cb60933b2b"
dependencies: dependencies:
"@microsoft/api-extractor" "^7.3.9" "@microsoft/api-extractor" "^7.3.9"
shelljs "0.8.2" shelljs "0.8.2"
tsickle "^0.38.0" tsickle "^0.38.0"
"@angular/cli@file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/angular_cli_archive.tar.gz": "@angular/cli@file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/angular_cli_archive.tar.gz":
version "9.0.0-rc.14" version "9.0.3"
resolved "file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/angular_cli_archive.tar.gz#68c932f4ec0991ba979b45d4cbaf7eedc8973bb4" resolved "file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/angular_cli_archive.tar.gz#8f18034bdddd079d3bab8a4de43fe1d9dcca4142"
dependencies: dependencies:
"@angular-devkit/architect" "0.900.0-rc.14" "@angular-devkit/architect" "0.900.3"
"@angular-devkit/core" "9.0.0-rc.14" "@angular-devkit/core" "9.0.3"
"@angular-devkit/schematics" "9.0.0-rc.14" "@angular-devkit/schematics" "9.0.3"
"@schematics/angular" "9.0.0-rc.14" "@schematics/angular" "9.0.3"
"@schematics/update" "0.900.0-rc.14" "@schematics/update" "0.900.3"
"@yarnpkg/lockfile" "1.1.0" "@yarnpkg/lockfile" "1.1.0"
ansi-colors "4.1.1" ansi-colors "4.1.1"
debug "^4.1.1" debug "^4.1.1"
@ -153,13 +153,13 @@
universal-analytics "^0.4.20" universal-analytics "^0.4.20"
uuid "^3.3.2" uuid "^3.3.2"
"@angular/common@file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/common/npm_package_archive.tar.gz": "@angular/common@file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/common/npm_package_archive.tar.gz":
version "0.0.0" version "0.0.0"
resolved "file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/common/npm_package_archive.tar.gz#b44ef9973f04db69decb9978824ba0d99afe9286" resolved "file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/common/npm_package_archive.tar.gz#03477fd1f71901db1d9b75ae54edf68f0fe3bf28"
"@angular/compiler-cli@file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/compiler-cli/npm_package_archive.tar.gz": "@angular/compiler-cli@file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/compiler-cli/npm_package_archive.tar.gz":
version "0.0.0" version "0.0.0"
resolved "file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/compiler-cli/npm_package_archive.tar.gz#22a041574d15d4218d2f9d4d4bd1389ca8fbe101" resolved "file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/compiler-cli/npm_package_archive.tar.gz#bb573836de2ba33feaae6b029063751acf3b7c42"
dependencies: dependencies:
canonical-path "1.0.0" canonical-path "1.0.0"
chokidar "^3.0.0" chokidar "^3.0.0"
@ -171,35 +171,36 @@
reflect-metadata "^0.1.2" reflect-metadata "^0.1.2"
semver "^6.3.0" semver "^6.3.0"
source-map "^0.6.1" source-map "^0.6.1"
sourcemap-codec "^1.4.8"
yargs "13.1.0" yargs "13.1.0"
"@angular/compiler@file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/compiler/npm_package_archive.tar.gz": "@angular/compiler@file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/compiler/npm_package_archive.tar.gz":
version "0.0.0" version "0.0.0"
resolved "file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/compiler/npm_package_archive.tar.gz#8cb29b1656564a1105c8e806f5d6b3e1d8b17a2b" resolved "file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/compiler/npm_package_archive.tar.gz#4b4f62c748b436e7b162e9d8ebac615de7292639"
"@angular/core@file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/core/npm_package_archive.tar.gz": "@angular/core@file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/core/npm_package_archive.tar.gz":
version "0.0.0" version "0.0.0"
resolved "file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/core/npm_package_archive.tar.gz#679c803ef3d63562c9389916c1d5174b3754199f" resolved "file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/core/npm_package_archive.tar.gz#0b45c6408fc137a289213907bd96e01e4000f44d"
"@angular/forms@file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/forms/npm_package_archive.tar.gz": "@angular/forms@file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/forms/npm_package_archive.tar.gz":
version "0.0.0" version "0.0.0"
resolved "file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/forms/npm_package_archive.tar.gz#e46870871fc8aef7a57d022b90ad32f1fd64e7bf" resolved "file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/forms/npm_package_archive.tar.gz#bec4d3fd05ca98084dc085f54c2578661355f02b"
"@angular/language-service@file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/language-service/npm_package_archive.tar.gz": "@angular/language-service@file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/language-service/npm_package_archive.tar.gz":
version "0.0.0" version "0.0.0"
resolved "file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/language-service/npm_package_archive.tar.gz#6e913e6aa7d921d5c30a1ac6ca9646a220887d5b" resolved "file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/language-service/npm_package_archive.tar.gz#eb064eb2a69df356e5229bda3651eb90fca487d1"
"@angular/platform-browser-dynamic@file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/platform-browser-dynamic/npm_package_archive.tar.gz": "@angular/platform-browser-dynamic@file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/platform-browser-dynamic/npm_package_archive.tar.gz":
version "0.0.0" version "0.0.0"
resolved "file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/platform-browser-dynamic/npm_package_archive.tar.gz#db2804acfb8fc6fb2f3aa46e657e7c25d4d64314" resolved "file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/platform-browser-dynamic/npm_package_archive.tar.gz#3401f6226262090d852df825c62928e4d915f130"
"@angular/platform-browser@file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/platform-browser/npm_package_archive.tar.gz": "@angular/platform-browser@file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/platform-browser/npm_package_archive.tar.gz":
version "0.0.0" version "0.0.0"
resolved "file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/platform-browser/npm_package_archive.tar.gz#3d71864b3accd9834e49e8098c48ee4a15bd015c" resolved "file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/platform-browser/npm_package_archive.tar.gz#79f1e1c40976be097e6a43009e8c2c8cae690a0a"
"@angular/router@file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/router/npm_package_archive.tar.gz": "@angular/router@file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/router/npm_package_archive.tar.gz":
version "0.0.0" version "0.0.0"
resolved "file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/router/npm_package_archive.tar.gz#80aad793835f538439bb5c27e4db97d4113e6577" resolved "file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/angular/packages/router/npm_package_archive.tar.gz#819fa19157bf44601adc4e4462e646ab8e168523"
"@babel/code-frame@^7.5.5", "@babel/code-frame@^7.8.3": "@babel/code-frame@^7.5.5", "@babel/code-frame@^7.8.3":
version "7.8.3" version "7.8.3"
@ -896,9 +897,9 @@
resolved "https://registry.yarnpkg.com/@bazel/bazel-win32_x64/-/bazel-win32_x64-2.1.0.tgz#013960fe506ddb8dc08f5d54b52420c818eb4264" resolved "https://registry.yarnpkg.com/@bazel/bazel-win32_x64/-/bazel-win32_x64-2.1.0.tgz#013960fe506ddb8dc08f5d54b52420c818eb4264"
integrity sha512-Y6cs3frmCqoAsrDmEp0msyS8VYE13JvjVoyvdIXTOh5Cc4fOeWzSPb02VS08asaV1jCnOQbv15Ud286hcxAvxg== integrity sha512-Y6cs3frmCqoAsrDmEp0msyS8VYE13JvjVoyvdIXTOh5Cc4fOeWzSPb02VS08asaV1jCnOQbv15Ud286hcxAvxg==
"@bazel/bazel@file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/bazel_bazel_archive.tar.gz": "@bazel/bazel@file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/bazel_bazel_archive.tar.gz":
version "2.1.0" version "2.1.0"
resolved "file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/bazel_bazel_archive.tar.gz#23536a5d4ce19c68eeaef484c79782a79fd41d84" resolved "file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/bazel_bazel_archive.tar.gz#23536a5d4ce19c68eeaef484c79782a79fd41d84"
dependencies: dependencies:
"@bazel/hide-bazel-files" latest "@bazel/hide-bazel-files" latest
optionalDependencies: optionalDependencies:
@ -969,31 +970,31 @@
resolved "https://registry.yarnpkg.com/@microsoft/tsdoc/-/tsdoc-0.12.14.tgz#0e0810a0a174e50e22dfe8edb30599840712f22d" resolved "https://registry.yarnpkg.com/@microsoft/tsdoc/-/tsdoc-0.12.14.tgz#0e0810a0a174e50e22dfe8edb30599840712f22d"
integrity sha512-518yewjSga1jLdiLrcmpMFlaba5P+50b0TWNFUpC+SL9Yzf0kMi57qw+bMl+rQ08cGqH1vLx4eg9YFUbZXgZ0Q== integrity sha512-518yewjSga1jLdiLrcmpMFlaba5P+50b0TWNFUpC+SL9Yzf0kMi57qw+bMl+rQ08cGqH1vLx4eg9YFUbZXgZ0Q==
"@ngtools/webpack@9.0.0-rc.14": "@ngtools/webpack@9.0.3":
version "9.0.0-rc.14" version "9.0.3"
resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-9.0.0-rc.14.tgz#6a764138347d2ff3846753a141eaacdab3b0658c" resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-9.0.3.tgz#d05b5a15584909262a4db027919f03ccb074dc11"
integrity sha512-G98u14exE36kR4LflWB20ClJ6ql9B0qMcyokepjwpVAgaoDfpJRR7mKAZliMPd0KFXktdnct2QEyF6pbLevO7w== integrity sha512-pMIXfq1IJLbvwmkPonGs7nrpuBCXrlZTf9A4OYsMBZcfU8JMn0pRdx7G2+bC9Q/f+uSw2uvPSv76xJXLBOntmA==
dependencies: dependencies:
"@angular-devkit/core" "9.0.0-rc.14" "@angular-devkit/core" "9.0.3"
enhanced-resolve "4.1.1" enhanced-resolve "4.1.1"
rxjs "6.5.3" rxjs "6.5.3"
webpack-sources "1.4.3" webpack-sources "1.4.3"
"@schematics/angular@9.0.0-rc.14": "@schematics/angular@9.0.3":
version "9.0.0-rc.14" version "9.0.3"
resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-9.0.0-rc.14.tgz#4112aeb6c76144893d65cab9f53ca8422adc3bbb" resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-9.0.3.tgz#8b0fb91fa18dd909001ac0d888479a96810aa640"
integrity sha512-NWxDLym2Sst5lTvV7QYkVUjy3N0CfCohhdWC4DGRtjUyTD2eUepAg1PZCQcq8U2iRtd78Lm1n4obDWO1tW3pXQ== integrity sha512-6XSnPW4G7aoKXccg0FTpZ02y/yi9y/bj7swnSL9Z4RRPIvPVapDjB7uJPg8sm8+PTIpcMhEFQrchIqM3LXW4zA==
dependencies: dependencies:
"@angular-devkit/core" "9.0.0-rc.14" "@angular-devkit/core" "9.0.3"
"@angular-devkit/schematics" "9.0.0-rc.14" "@angular-devkit/schematics" "9.0.3"
"@schematics/update@0.900.0-rc.14": "@schematics/update@0.900.3":
version "0.900.0-rc.14" version "0.900.3"
resolved "https://registry.yarnpkg.com/@schematics/update/-/update-0.900.0-rc.14.tgz#1debea3eb90559d25838e7b256b48bac216e19d9" resolved "https://registry.yarnpkg.com/@schematics/update/-/update-0.900.3.tgz#9141ee2e1b6356e66f6269b92c284c86e4faf065"
integrity sha512-ZlsneHwpvrtpt0D10g4S8JftLaSFQtSO+kOD1uP26OxNMg9w54jrlr7xWSwAmT69/ETjNy8BFKXdcU9yvYixPA== integrity sha512-mlRsm3/HM1f/10Wdz4xMYA+mpW3EDCB+whlV5cJ7PGMhjUMaxA9DuWvoP06h05le6XmgnjIEoxL6NJ7CgesHcA==
dependencies: dependencies:
"@angular-devkit/core" "9.0.0-rc.14" "@angular-devkit/core" "9.0.3"
"@angular-devkit/schematics" "9.0.0-rc.14" "@angular-devkit/schematics" "9.0.3"
"@yarnpkg/lockfile" "1.1.0" "@yarnpkg/lockfile" "1.1.0"
ini "1.3.5" ini "1.3.5"
npm-package-arg "^7.0.0" npm-package-arg "^7.0.0"
@ -1058,9 +1059,9 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.5.8.tgz#92509422653f10e9c0ac18d87e0610b39f9821c7" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.5.8.tgz#92509422653f10e9c0ac18d87e0610b39f9821c7"
integrity sha512-8KmlRxwbKZfjUHFIt3q8TF5S2B+/E5BaAoo/3mgc5h6FJzqxXkCK/VMetO+IRDtwtU6HUvovHMBn+XRj7SV9Qg== integrity sha512-8KmlRxwbKZfjUHFIt3q8TF5S2B+/E5BaAoo/3mgc5h6FJzqxXkCK/VMetO+IRDtwtU6HUvovHMBn+XRj7SV9Qg==
"@types/node@file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/types_node_archive.tar.gz": "@types/node@file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/types_node_archive.tar.gz":
version "12.11.1" version "12.11.1"
resolved "file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/types_node_archive.tar.gz#5e661926d854590d3e9cec111d80feafdaf4ee78" resolved "file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/types_node_archive.tar.gz#5e661926d854590d3e9cec111d80feafdaf4ee78"
"@types/q@^0.0.32": "@types/q@^0.0.32":
version "0.0.32" version "0.0.32"
@ -1252,7 +1253,7 @@
resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d"
integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
"@yarnpkg/lockfile@1.1.0": "@yarnpkg/lockfile@1.1.0", "@yarnpkg/lockfile@^1.1.0":
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31"
integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==
@ -2056,6 +2057,11 @@ chrome-trace-event@^1.0.2:
dependencies: dependencies:
tslib "^1.9.0" tslib "^1.9.0"
ci-info@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46"
integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==
cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de"
@ -2400,7 +2406,7 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
safe-buffer "^5.0.1" safe-buffer "^5.0.1"
sha.js "^2.4.8" sha.js "^2.4.8"
cross-spawn@^6.0.0: cross-spawn@^6.0.0, cross-spawn@^6.0.5:
version "6.0.5" version "6.0.5"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
@ -3327,6 +3333,14 @@ find-up@^4.0.0:
locate-path "^5.0.0" locate-path "^5.0.0"
path-exists "^4.0.0" path-exists "^4.0.0"
find-yarn-workspace-root@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-1.2.1.tgz#40eb8e6e7c2502ddfaa2577c176f221422f860db"
integrity sha512-dVtfb0WuQG+8Ag2uWkbG79hOUzEsRrhBzgfn86g2sJPkzmcpGdghbNTfUKGTxymFrY/tLIodDzLoW9nOJ4FY8Q==
dependencies:
fs-extra "^4.0.3"
micromatch "^3.1.4"
flush-write-stream@^1.0.0: flush-write-stream@^1.0.0:
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8"
@ -3395,7 +3409,16 @@ fs-extra@4.0.2:
jsonfile "^4.0.0" jsonfile "^4.0.0"
universalify "^0.1.0" universalify "^0.1.0"
fs-extra@~7.0.1: fs-extra@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94"
integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==
dependencies:
graceful-fs "^4.1.2"
jsonfile "^4.0.0"
universalify "^0.1.0"
fs-extra@^7.0.1, fs-extra@~7.0.1:
version "7.0.1" version "7.0.1"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9"
integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==
@ -4123,6 +4146,13 @@ is-callable@^1.1.5:
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab"
integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==
is-ci@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c"
integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==
dependencies:
ci-info "^2.0.0"
is-color-stop@^1.0.0: is-color-stop@^1.0.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/is-color-stop/-/is-color-stop-1.1.0.tgz#cfff471aee4dd5c9e158598fbe12967b5cdad345" resolved "https://registry.yarnpkg.com/is-color-stop/-/is-color-stop-1.1.0.tgz#cfff471aee4dd5c9e158598fbe12967b5cdad345"
@ -4585,6 +4615,13 @@ kind-of@^6.0.0, kind-of@^6.0.2:
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
klaw-sync@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/klaw-sync/-/klaw-sync-6.0.0.tgz#1fd2cfd56ebb6250181114f0a581167099c2b28c"
integrity sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==
dependencies:
graceful-fs "^4.1.11"
lcid@^2.0.0: lcid@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf"
@ -5639,6 +5676,24 @@ pascalcase@^0.1.1:
resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14"
integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=
patch-package@^6.2.1:
version "6.2.1"
resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.2.1.tgz#e3c55cf09dffd3984dd300e30d842672b604307f"
integrity sha512-dfCtQor63PPij6DDYtCzBRoO5nNAcMSg7Cmh+DLhR+s3t0OLQBdvFxJksZHBe1J2MjsSWDjTF4+oQKFbdkssIg==
dependencies:
"@yarnpkg/lockfile" "^1.1.0"
chalk "^2.4.2"
cross-spawn "^6.0.5"
find-yarn-workspace-root "^1.2.1"
fs-extra "^7.0.1"
is-ci "^2.0.0"
klaw-sync "^6.0.0"
minimist "^1.2.0"
rimraf "^2.6.3"
semver "^5.6.0"
slash "^2.0.0"
tmp "^0.0.33"
path-browserify@0.0.1: path-browserify@0.0.1:
version "0.0.1" version "0.0.1"
resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a"
@ -6146,9 +6201,9 @@ protoduck@^5.0.1:
dependencies: dependencies:
genfun "^5.0.0" genfun "^5.0.0"
"protractor@file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/protractor_archive.tar.gz": "protractor@file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/protractor_archive.tar.gz":
version "5.4.3" version "5.4.3"
resolved "file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/protractor_archive.tar.gz#6dcc8c321fcde8864b4919f8e053be8ab94812b0" resolved "file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/protractor_archive.tar.gz#6dcc8c321fcde8864b4919f8e053be8ab94812b0"
dependencies: dependencies:
"@types/q" "^0.0.32" "@types/q" "^0.0.32"
"@types/selenium-webdriver" "^3.0.0" "@types/selenium-webdriver" "^3.0.0"
@ -6246,9 +6301,9 @@ punycode@^2.1.0, punycode@^2.1.1:
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
"puppeteer@file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/puppeteer_archive.tar.gz": "puppeteer@file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/puppeteer_archive.tar.gz":
version "2.1.1" version "2.1.1"
resolved "file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/puppeteer_archive.tar.gz#a34ddad83471c2b071467027c05f9aa635429431" resolved "file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/puppeteer_archive.tar.gz#a34ddad83471c2b071467027c05f9aa635429431"
dependencies: dependencies:
"@types/mime-types" "^2.1.0" "@types/mime-types" "^2.1.0"
debug "^4.1.0" debug "^4.1.0"
@ -6984,6 +7039,11 @@ slash@^1.0.0:
resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=
slash@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44"
integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==
smart-buffer@4.0.2: smart-buffer@4.0.2:
version "4.0.2" version "4.0.2"
resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.0.2.tgz#5207858c3815cc69110703c6b94e46c15634395d" resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.0.2.tgz#5207858c3815cc69110703c6b94e46c15634395d"
@ -7126,6 +7186,11 @@ sourcemap-codec@^1.4.4:
resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.4.tgz#c63ea927c029dd6bd9a2b7fa03b3fec02ad56e9f" resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.4.tgz#c63ea927c029dd6bd9a2b7fa03b3fec02ad56e9f"
integrity sha512-CYAPYdBu34781kLHkaW3m6b/uUSyMOC2R61gcYMWooeuaGtjof86ZA/8T+qVPPt7np1085CR9hmMGrySwEc8Xg== integrity sha512-CYAPYdBu34781kLHkaW3m6b/uUSyMOC2R61gcYMWooeuaGtjof86ZA/8T+qVPPt7np1085CR9hmMGrySwEc8Xg==
sourcemap-codec@^1.4.8:
version "1.4.8"
resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4"
integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==
spdx-correct@^3.0.0: spdx-correct@^3.0.0:
version "3.1.0" version "3.1.0"
resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4"
@ -7669,9 +7734,9 @@ tslib@^1.9.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==
"tslib@file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/tslib_archive.tar.gz": "tslib@file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/tslib_archive.tar.gz":
version "1.10.0" version "1.10.0"
resolved "file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/tslib_archive.tar.gz#8c9c2d89e039129330357b42a44c1d98ac5b029e" resolved "file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/tslib_archive.tar.gz#8c9c2d89e039129330357b42a44c1d98ac5b029e"
tty-browserify@0.0.0: tty-browserify@0.0.0:
version "0.0.0" version "0.0.0"
@ -7713,9 +7778,9 @@ typescript@3.6.4:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.6.4.tgz#b18752bb3792bc1a0281335f7f6ebf1bbfc5b91d" resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.6.4.tgz#b18752bb3792bc1a0281335f7f6ebf1bbfc5b91d"
integrity sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg== integrity sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==
"typescript@file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/typescript_archive.tar.gz": "typescript@file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/typescript_archive.tar.gz":
version "3.7.4" version "3.7.4"
resolved "file:../../../../../../private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/typescript_archive.tar.gz#6463332bce549a063d07063c0fe09416d4732f67" resolved "file:../../../../../../private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/typescript_archive.tar.gz#6463332bce549a063d07063c0fe09416d4732f67"
typescript@~3.5.3: typescript@~3.5.3:
version "3.5.3" version "3.5.3"
@ -7975,9 +8040,9 @@ webdriver-js-extender@2.1.0:
"@types/selenium-webdriver" "^3.0.0" "@types/selenium-webdriver" "^3.0.0"
selenium-webdriver "^3.0.1" selenium-webdriver "^3.0.1"
webdriver-manager@^12.0.6, "webdriver-manager@file:/private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/webdriver-manager_archive.tar.gz": webdriver-manager@^12.0.6, "webdriver-manager@file:/private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/webdriver-manager_archive.tar.gz":
version "12.1.7" version "12.1.7"
resolved "file:/private/var/tmp/_bazel_greg/5e8f8a9cd1c6fbc1afd11e37ee1fe2e5/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/webdriver-manager_archive.tar.gz#1de5c677e825cd6964bf398686af67120305b17e" resolved "file:/private/var/tmp/_bazel_greg/0fd61ed550651b87aabc580a0eb4c09f/execroot/angular/bazel-out/darwin-fastbuild/bin/integration/bazel-schematics_test.debug.sh.runfiles/npm/webdriver-manager_archive.tar.gz#f1a1a624b461810bab9993e9822f9726fe46c877"
dependencies: dependencies:
adm-zip "^0.4.9" adm-zip "^0.4.9"
chalk "^1.1.1" chalk "^1.1.1"

View File

@ -1,7 +1,4 @@
workspace( workspace(name = "bazel_integration_test")
name = "bazel_integration_test",
managed_directories = {"@npm": ["node_modules"]},
)
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
@ -57,6 +54,11 @@ node_repositories(
yarn_install( yarn_install(
name = "npm", name = "npm",
package_json = "//:package.json", package_json = "//:package.json",
# Turn off symlink_node_modules here as it causes flakiness with missing
# files in node_modules.
# TODO: track down the root cause of the flakiness; current suspect is that
# it is an issue with managed_directories when resources are limited
symlink_node_modules = False,
yarn_lock = "//:yarn.lock", yarn_lock = "//:yarn.lock",
) )

View File

@ -11,7 +11,7 @@ set -u -e -o pipefail
cd "$(dirname "$0")" cd "$(dirname "$0")"
node $(pwd)/../../scripts/build-packages-dist.js node $(pwd)/../../scripts/build/build-packages-dist.js
# Workaround https://github.com/yarnpkg/yarn/issues/2165 # Workaround https://github.com/yarnpkg/yarn/issues/2165
# Yarn will cache file://dist URIs and not update Angular code # Yarn will cache file://dist URIs and not update Angular code

View File

@ -11,7 +11,7 @@ set -u -e -o pipefail
cd "$(dirname "$0")" cd "$(dirname "$0")"
node $(pwd)/../../scripts/build-packages-dist.js node $(pwd)/../../scripts/build/build-packages-dist.js
# Workaround https://github.com/yarnpkg/yarn/issues/2165 # Workaround https://github.com/yarnpkg/yarn/issues/2165
# Yarn will cache file://dist URIs and not update Angular code # Yarn will cache file://dist URIs and not update Angular code

View File

@ -11,7 +11,7 @@ set -u -e -o pipefail
cd "$(dirname "$0")" cd "$(dirname "$0")"
node $(pwd)/../../scripts/build-packages-dist.js node $(pwd)/../../scripts/build/build-packages-dist.js
# Workaround https://github.com/yarnpkg/yarn/issues/2165 # Workaround https://github.com/yarnpkg/yarn/issues/2165
# Yarn will cache file://dist URIs and not update Angular code # Yarn will cache file://dist URIs and not update Angular code

View File

@ -13,7 +13,7 @@
}, },
"scripts": { "scripts": {
"build": "tsc -p tsconfig.json", "build": "tsc -p tsconfig.json",
"build-dist": "node ../../scripts/build-packages-dist.js && yarn install --check-files", "build-dist": "node ../../scripts/build/build-packages-dist.js && yarn install --check-files",
"cleanup": "rm -rf ti-*.log tsserver.log", "cleanup": "rm -rf ti-*.log tsserver.log",
"golden": "yarn build && node generate.js", "golden": "yarn build && node generate.js",
"test": "yarn cleanup && yarn build && jasmine test.js" "test": "yarn cleanup && yarn build && jasmine test.js"

View File

@ -11,7 +11,7 @@
}, },
"scripts": { "scripts": {
"build": "tsc -p tsconfig.json", "build": "tsc -p tsconfig.json",
"build-dist": "node ../../scripts/build-packages-dist.js && yarn install --check-files", "build-dist": "node ../../scripts/build/build-packages-dist.js && yarn install --check-files",
"test": "yarn build && node test.js" "test": "yarn build && node test.js"
} }
} }

View File

@ -53,11 +53,13 @@ rm('-rf', `demo`);
exec('ng version'); exec('ng version');
exec('ng new demo --skip-git --skip-install --style=css --no-interactive'); exec('ng new demo --skip-git --skip-install --style=css --no-interactive');
cd('demo'); cd('demo');
// Use a local yarn cache folder so we don't access the global yarn cache
exec('mkdir .yarn_local_cache');
// Install Angular packages that are built locally from HEAD and npm packages // Install Angular packages that are built locally from HEAD and npm packages
// from root node modules that are to be kept in sync // from root node modules that are to be kept in sync
const packageList = Object.keys(packages).map(p => `${p}@${packages[p]}`).join(' '); const packageList = Object.keys(packages).map(p => `${p}@${packages[p]}`).join(' ');
exec(`yarn add --ignore-scripts --silent ${packageList}`); exec(`yarn add --ignore-scripts --silent ${packageList} --cache-folder ./.yarn_local_cache`);
// Add @angular/elements // Add @angular/elements
exec(bazelMappings ? `ng add "${bazelMappings['@angular/elements']}"` : `ng add "${__dirname}/../../dist/packages-dist/elements"`); exec(bazelMappings ? `ng add "${bazelMappings['@angular/elements']}"` : `ng add "${__dirname}/../../dist/packages-dist/elements"`);

View File

@ -11,7 +11,7 @@ set -u -e -o pipefail
cd "$(dirname "$0")" cd "$(dirname "$0")"
node $(pwd)/../../scripts/build-packages-dist.js node $(pwd)/../../scripts/build/build-packages-dist.js
# Workaround https://github.com/yarnpkg/yarn/issues/2165 # Workaround https://github.com/yarnpkg/yarn/issues/2165
# Yarn will cache file://dist URIs and not update Angular code # Yarn will cache file://dist URIs and not update Angular code

View File

@ -34,7 +34,7 @@ if $CI; then
else else
# Not on CircleCI so let's build the packages-dist directory. # Not on CircleCI so let's build the packages-dist directory.
# This should be fast on incremental re-build. # This should be fast on incremental re-build.
node ${basedir}/scripts/build-packages-dist.js node ${basedir}/scripts/build/build-packages-dist.js
# If we aren't running on CircleCI, we do not shard tests because this would be the job of # If we aren't running on CircleCI, we do not shard tests because this would be the job of
# Bazel eventually. For now, we just run all tests sequentially when running locally. # Bazel eventually. For now, we just run all tests sequentially when running locally.

View File

@ -1,6 +0,0 @@
# How to run the benchmarks_external locally
$ cp -r ./modules/benchmarks_external ./dist/all/
$ ./node_modules/.bin/tsc -p modules --emitDecoratorMetadata -w
$ gulp serve
$ open http://localhost:8000/all/benchmarks_external/src/tree/index.html?bundles=false

View File

@ -1,37 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {runClickBenchmark, verifyNoBrowserErrors} from '@angular/testing/src/perf_util';
describe('ng1.x compiler benchmark', function() {
const URL = 'benchmarks_external/src/compiler/compiler_benchmark.html';
afterEach(verifyNoBrowserErrors);
it('should log withBinding stats', function(done) {
runClickBenchmark({
url: URL,
buttons: ['#compileWithBindings'],
id: 'ng1.compile.withBindings',
params: [{name: 'elements', value: 150, scale: 'linear'}],
waitForAngular2: false
}).then(done, done.fail);
});
it('should log noBindings stats', function(done) {
runClickBenchmark({
url: URL,
buttons: ['#compileNoBindings'],
id: 'ng1.compile.noBindings',
params: [{name: 'elements', value: 150, scale: 'linear'}],
waitForAngular2: false
}).then(done, done.fail);
});
});

View File

@ -1,33 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {runClickBenchmark, verifyNoBrowserErrors} from '@angular/testing/src/perf_util';
describe('ng1.x largetable benchmark', function() {
const URL = 'benchmarks_external/src/largetable/largetable_benchmark.html';
afterEach(verifyNoBrowserErrors);
['baselineBinding', 'baselineInterpolation', 'ngBind', 'ngBindOnce', 'interpolation',
'interpolationAttr', 'ngBindFn', 'interpolationFn', 'ngBindFilter', 'interpolationFilter']
.forEach(function(benchmarkType) {
it('should log the stats with: ' + benchmarkType, function(done) {
runClickBenchmark({
url: URL,
buttons: ['#destroyDom', '#createDom'],
id: 'ng1.largetable.' + benchmarkType,
params: [
{name: 'columns', value: 100, scale: 'sqrt'},
{name: 'rows', value: 20, scale: 'sqrt'},
{name: 'benchmarkType', value: benchmarkType}
],
waitForAngular2: false
}).then(done, done.fail);
});
});
});

View File

@ -1,41 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {runBenchmark, verifyNoBrowserErrors} from '@angular/testing/src/perf_util';
describe('ng-dart1.x naive infinite scroll benchmark', function() {
const URL = 'benchmarks_external/src/naive_infinite_scroll/index.html';
afterEach(verifyNoBrowserErrors);
[1, 2, 4].forEach(function(appSize) {
it('should run scroll benchmark and collect stats for appSize = ' + appSize, function(done) {
runBenchmark({
url: URL,
id: 'ng1-dart1.x.naive_infinite_scroll',
work: function() {
$('#reset-btn').click();
$('#run-btn').click();
let s = 1000;
if (appSize > 4) {
s = s + appSize * 100;
}
browser.sleep(s);
},
params: [
{name: 'appSize', value: appSize},
{name: 'iterationCount', value: 20, scale: 'linear'},
{name: 'scrollIncrement', value: 40}
],
waitForAngular2: false
}).then(done, done.fail);
});
});
});

View File

@ -1,37 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {runClickBenchmark, verifyNoBrowserErrors} from '@angular/testing/src/perf_util';
describe('react tree benchmark', function() {
const URL = 'benchmarks_external/src/tree/react/index.html';
afterEach(verifyNoBrowserErrors);
it('should log the stats (create)', function(done) {
runClickBenchmark({
url: URL,
buttons: ['#destroyDom', '#createDom'],
id: 'react.tree.create',
params: [{name: 'depth', value: 9, scale: 'log2'}],
waitForAngular2: false
}).then(done, done.fail);
});
it('should log the stats (update)', function(done) {
runClickBenchmark({
url: URL,
buttons: ['#createDom'],
id: 'react.tree.update',
params: [{name: 'depth', value: 9, scale: 'log2'}],
waitForAngular2: false
}).then(done, done.fail);
});
});

View File

@ -1,37 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {runClickBenchmark, verifyNoBrowserErrors} from '@angular/testing/src/perf_util';
describe('ng1.x tree benchmark', function() {
const URL = 'benchmarks_external/src/static_tree/tree_benchmark.html';
afterEach(verifyNoBrowserErrors);
it('should log the stats (create)', function(done) {
runClickBenchmark({
url: URL,
buttons: ['#destroyDom', '#createDom'],
id: 'ng1.static.tree.create',
params: [],
waitForAngular2: false
}).then(done, done.fail);
});
it('should log the stats (update)', function(done) {
runClickBenchmark({
url: URL,
buttons: ['#createDom'],
id: 'ng1.static.tree.update',
params: [],
waitForAngular2: false
}).then(done, done.fail);
});
});

View File

@ -1,37 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {runClickBenchmark, verifyNoBrowserErrors} from '@angular/testing/src/perf_util';
describe('ng1.x tree benchmark', function() {
const URL = 'benchmarks_external/src/tree/tree_benchmark.html';
afterEach(verifyNoBrowserErrors);
it('should log the stats (create)', function(done) {
runClickBenchmark({
url: URL,
buttons: ['#destroyDom', '#createDom'],
id: 'ng1.tree.create',
params: [{name: 'depth', value: 9, scale: 'log2'}],
waitForAngular2: false
}).then(done, done.fail);
});
it('should log the stats (update)', function(done) {
runClickBenchmark({
url: URL,
buttons: ['#createDom'],
id: 'ng1.tree.update',
params: [{name: 'depth', value: 9, scale: 'log2'}],
waitForAngular2: false
}).then(done, done.fail);
});
});

View File

@ -1,91 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
(function(global: any /** TODO #9100 */) {
writeScriptTag('/all/benchmarks/vendor/core.js');
writeScriptTag('/all/benchmarks/vendor/zone.js');
writeScriptTag('/all/benchmarks/vendor/long-stack-trace-zone.js');
writeScriptTag('/all/benchmarks/vendor/system.src.js');
writeScriptTag('/all/benchmarks/vendor/Reflect.js', 'benchmarksBootstrap()');
(<any>global).benchmarksBootstrap = benchmarksBootstrap;
function benchmarksBootstrap() {
// check query param
const useBundles = location.search.indexOf('bundles=false') == -1;
if (useBundles) {
System.config({
map: {
'index': 'index.js',
'@angular/core': '/packages-dist/core/bundles/core.umd.js',
'@angular/common': '/packages-dist/common/bundles/common.umd.js',
'@angular/forms': '/packages-dist/forms/bundles/forms.umd.js',
'@angular/compiler': '/packages-dist/compiler/bundles/compiler.umd.js',
'@angular/platform-browser':
'/packages-dist/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic':
'/packages-dist/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/http': '/packages-dist/http/bundles/http.umd.js',
'@angular/upgrade': '/packages-dist/upgrade/bundles/upgrade.umd.js',
'@angular/router': '/packages-dist/router/bundles/router.umd.js',
'@angular/core/src/facade': '/all/@angular/core/src/facade',
'rxjs': 'node_modules/rxjs',
},
packages: {
'app': {defaultExtension: 'js'},
'@angular/core/src/facade': {defaultExtension: 'js'},
'rxjs/ajax': {main: 'index.js', defaultExtension: 'js' },
'rxjs/operators': {main: 'index.js', defaultExtension: 'js' },
'rxjs/testing': {main: 'index.js', defaultExtension: 'js' },
'rxjs/websocket': {main: 'index.js', defaultExtension: 'js' },
'rxjs': { main: 'index.js', defaultExtension: 'js' },
}
});
} else {
console.warn(
'Not using the Angular bundles. Don\'t use this configuration for e2e/performance tests!');
System.config({
map: {
'index': 'index.js',
'@angular': '/all/@angular',
'rxjs': 'node_modules/rxjs',
},
packages: {
'app': {defaultExtension: 'js'},
'@angular/core': {main: 'index.js', defaultExtension: 'js'},
'@angular/compiler': {main: 'index.js', defaultExtension: 'js'},
'@angular/router': {main: 'index.js', defaultExtension: 'js'},
'@angular/common': {main: 'index.js', defaultExtension: 'js'},
'@angular/forms': {main: 'index.js', defaultExtension: 'js'},
'@angular/platform-browser': {main: 'index.js', defaultExtension: 'js'},
'@angular/platform-browser-dynamic': {main: 'index.js', defaultExtension: 'js'},
'@angular/upgrade': {main: 'index.js', defaultExtension: 'js'},
'rxjs/ajax': {main: 'index.js', defaultExtension: 'js' },
'rxjs/operators': {main: 'index.js', defaultExtension: 'js' },
'rxjs/testing': {main: 'index.js', defaultExtension: 'js' },
'rxjs/websocket': {main: 'index.js', defaultExtension: 'js' },
'rxjs': { main: 'index.js', defaultExtension: 'js' },
}
});
}
// BOOTSTRAP the app!
System.import('index').then(function(m: any /** TODO #9100 */) {
m.main();
}, console.error.bind(console));
}
function writeScriptTag(scriptUrl: any /** TODO #9100 */, onload?: any /** TODO #9100 */) {
document.write(`<script src="${scriptUrl}" onload="${onload}"></script>`);
}
}(window));

View File

@ -1,53 +0,0 @@
<!doctype html>
<html>
<body>
<h2>Params</h2>
<form>
Elements:
<input type="number" name="elements" placeholder="elements" value="150">
<br>
<button>Apply</button>
</form>
<h2>Actions</h2>
<p>
<button id="compileWithBindings">CompileWithBindings</button>
<button id="compileNoBindings">CompileNoBindings</button>
</p>
<template id="templateNoBindings">
<div class="class0 class1 class2 class3 class4 " nodir0="" attr0="value0" nodir1="" attr1="value1" nodir2="" attr2="value2" nodir3="" attr3="value3" nodir4="" attr4="value4">
<div class="class0 class1 class2 class3 class4 " nodir0="" attr0="value0" nodir1="" attr1="value1" nodir2="" attr2="value2" nodir3="" attr3="value3" nodir4="" attr4="value4">
<div class="class0 class1 class2 class3 class4 " nodir0="" attr0="value0" nodir1="" attr1="value1" nodir2="" attr2="value2" nodir3="" attr3="value3" nodir4="" attr4="value4">
<div class="class0 class1 class2 class3 class4 " nodir0="" attr0="value0" nodir1="" attr1="value1" nodir2="" attr2="value2" nodir3="" attr3="value3" nodir4="" attr4="value4">
<div class="class0 class1 class2 class3 class4 " nodir0="" attr0="value0" nodir1="" attr1="value1" nodir2="" attr2="value2" nodir3="" attr3="value3" nodir4="" attr4="value4">
</div>
</div>
</div>
</div>
</div>
</template>
<template id="templateWithBindings">
<div class="class0 class1 class2 class3 class4 " dir0="" [attr0]="value0" dir1="" [attr1]="value1" dir2="" [attr2]="value2" dir3="" [attr3]="value3" dir4="" [attr4]="value4">
{{inter0}}{{inter1}}{{inter2}}{{inter3}}{{inter4}}
<div class="class0 class1 class2 class3 class4 " dir0="" [attr0]="value0" dir1="" [attr1]="value1" dir2="" [attr2]="value2" dir3="" [attr3]="value3" dir4="" [attr4]="value4">
{{inter0}}{{inter1}}{{inter2}}{{inter3}}{{inter4}}
<div class="class0 class1 class2 class3 class4 " dir0="" [attr0]="value0" dir1="" [attr1]="value1" dir2="" [attr2]="value2" dir3="" [attr3]="value3" dir4="" [attr4]="value4">
{{inter0}}{{inter1}}{{inter2}}{{inter3}}{{inter4}}
<div class="class0 class1 class2 class3 class4 " dir0="" [attr0]="value0" dir1="" [attr1]="value1" dir2="" [attr2]="value2" dir3="" [attr3]="value3" dir4="" [attr4]="value4">
{{inter0}}{{inter1}}{{inter2}}{{inter3}}{{inter4}}
<div class="class0 class1 class2 class3 class4 " dir0="" [attr0]="value0" dir1="" [attr1]="value1" dir2="" [attr2]="value2" dir3="" [attr3]="value3" dir4="" [attr4]="value4">
{{inter0}}{{inter1}}{{inter2}}{{inter3}}{{inter4}}
</div>
</div>
</div>
</div>
</div>
</template>
$SCRIPTS$
</body>
</html>

View File

@ -1,117 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
// compiler benchmark in AngularJS 1.x
import {getIntParameter, bindAction} from '@angular/testing/src/benchmark_util';
declare var angular: any;
export function main() {
const ngEl = document.createElement('div');
angular.bootstrap(ngEl, ['app']);
}
function loadTemplate(templateId, repeatCount) {
const template = document.querySelectorAll(`#${templateId}`)[0];
const content = (<HTMLElement>template).innerHTML;
let result = '';
for (let i = 0; i < repeatCount; i++) {
result += content;
}
// replace [] binding syntax
result = result.replace(/[\[\]]/g, '');
// Use a DIV as container as Angular 1.3 does not know <template> elements...
const div = document.createElement('div');
div.innerHTML = result;
return div;
}
angular.module('app', [])
.directive('dir0',
[
'$parse',
function($parse) {
return {
compile: function($element, $attrs) {
const expr = $parse($attrs.attr0);
return ($scope) => $scope.$watch(expr, angular.noop);
}
};
}
])
.directive('dir1',
[
'$parse',
function($parse) {
return {
compile: function($element, $attrs) {
const expr = $parse($attrs.attr1);
return ($scope) => $scope.$watch(expr, angular.noop);
}
};
}
])
.directive('dir2',
[
'$parse',
function($parse) {
return {
compile: function($element, $attrs) {
const expr = $parse($attrs.attr2);
return ($scope) => $scope.$watch(expr, angular.noop);
}
};
}
])
.directive('dir3',
[
'$parse',
function($parse) {
return {
compile: function($element, $attrs) {
const expr = $parse($attrs.attr3);
return ($scope) => $scope.$watch(expr, angular.noop);
}
};
}
])
.directive('dir4',
[
'$parse',
function($parse) {
return {
compile: function($element, $attrs) {
const expr = $parse($attrs.attr4);
return ($scope) => $scope.$watch(expr, angular.noop);
}
};
}
])
.run([
'$compile',
function($compile) {
const count = getIntParameter('elements');
const templateNoBindings = loadTemplate('templateNoBindings', count);
const templateWithBindings = loadTemplate('templateWithBindings', count);
bindAction('#compileWithBindings', compileWithBindings);
bindAction('#compileNoBindings', compileNoBindings);
function compileNoBindings() {
// Need to clone every time as the compiler might modify the template!
const cloned = templateNoBindings.cloneNode(true);
$compile(cloned);
}
function compileWithBindings() {
// Need to clone every time as the compiler might modify the template!
const cloned = templateWithBindings.cloneNode(true);
$compile(cloned);
}
}
]);

View File

@ -1,26 +0,0 @@
<!doctype html>
<html>
<body>
<ul>
<li>
<a href="compiler/compiler_benchmark.html">Compiler benchmark</a>
</li>
<li>
<a href="tree/tree_benchmark.html">Tree benchmark</a>
</li>
<li>
<a href="static_tree/tree_benchmark.html">Static tree benchmark</a>
</li>
<li>
<a href="tree/react/index.html">React Tree benchmark</a>
</li>
<li>
<a href="largetable/largetable_benchmark.html">Largetable benchmark</a>
</li>
<li>
<a href="naive_infinite_scroll/index.html">Naive infinite scroll benchmark</a>
</li>
</ul>
</body>
</html>

View File

@ -1,58 +0,0 @@
<ng-switch on="benchmarkType">
<baseline-binding-table ng-switch-when="baselineBinding">
</baseline-binding-table>
<baseline-interpolation-table ng-switch-when="baselineInterpolation">
</baseline-interpolation-table>
<div ng-switch-when="ngBind">
<h2>baseline binding</h2>
<div ng-repeat="row in data">
<span ng-repeat="column in row">
<span ng-bind="column.i"></span>:<span ng-bind="column.j"></span>|
</span>
</div>
</div>
<div ng-switch-when="ngBindOnce">
<h2>baseline binding once</h2>
<div ng-repeat="row in data">
<span ng-repeat="column in ::row">
<span ng-bind="::column.i"></span>:<span ng-bind="::column.j"></span>|
</span>
</div>
</div>
<div ng-switch-when="interpolation">
<h2>baseline interpolation</h2>
<div ng-repeat="row in data">
<span ng-repeat="column in row">{{column.i}}:{{column.j}}|</span>
</div>
</div>
<div ng-switch-when="interpolationAttr">
<h2>attribute interpolation</h2>
<div ng-repeat="row in data">
<span ng-repeat="column in row" i="{{column.i}}" j="{{column.j}}">i,j attrs</span>
</div>
</div>
<div ng-switch-when="ngBindFn">
<h2>bindings with functions</h2>
<div ng-repeat="row in data">
<span ng-repeat="column in row"><span ng-bind="column.iFn()"></span>:<span ng-bind="column.jFn()"></span>|</span>
</div>
</div>
<div ng-switch-when="interpolationFn">
<h2>interpolation with functions</h2>
<div ng-repeat="row in data">
<span ng-repeat="column in row">{{column.iFn()}}:{{column.jFn()}}|</span>
</div>
</div>
<div ng-switch-when="ngBindFilter">
<h2>bindings with filter</h2>
<div ng-repeat="row in data">
<span ng-repeat="column in row"><span ng-bind="column.i | noop"></span>:<span ng-bind="column.j | noop"></span>|</span>
</div>
</div>
<div ng-switch-when="interpolationFilter">
<h2>interpolation with filter</h2>
<div ng-repeat="row in data">
<span ng-repeat="column in row">{{column.i | noop}}:{{column.j | noop}}|</span>
</div>
</div>
</ng-switch>

View File

@ -1,98 +0,0 @@
<!doctype html>
<html>
<body>
<h2>AngularJS/Dart 1.x largetable benchmark</h2>
<form>
<div>
rows:
<input type="number" name="rows" value="100">
columns:
<input type="number" name="columns" value="20">
</div>
<div>
baseline binding:
<input type="radio"
name="benchmarkType"
value="baselineBinding"
id="baselineBinding"
checked>
</div>
<div>
baseline interpolation:
<input type="radio"
name="benchmarkType"
value="baselineInterpolation"
id="baselineInterpolation">
</div>
<div>
ngBind:
<input type="radio"
name="benchmarkType"
value="ngBind"
id="ngBind">
</div>
<div>
ngBindOnce:
<input type="radio"
name="benchmarkType"
value="ngBindOnce"
id="ngBindOnce">
</div>
<div>
interpolation:
<input type="radio"
name="benchmarkType"
value="interpolation"
id="interpolation">
</div>
<div>
attribute interpolation:
<input type="radio"
name="benchmarkType"
value="interpolationAttr"
id="interpolationAttr">
</div>
<div>
ngBind + fnInvocation:
<input type="radio"
name="benchmarkType"
value="ngBindFn"
id="ngBindFn">
</div>
<div>
interpolation + fnInvocation:
<input type="radio"
name="benchmarkType"
value="interpolationFn"
id="interpolationFn">
</div>
<div>
ngBind + filter:
<input type="radio"
name="benchmarkType"
value="ngBindFilter"
id="ngBindFilter">
</div>
<div>
interpolation + filter:
<input type="radio"
name="benchmarkType"
value="interpolationFilter"
id="interpolationFilter">
</div>
<button>Apply</button>
</form>
<p>
<button id="destroyDom">destroyDom</button>
<button id="createDom">createDom</button>
</p>
<div>
<largetable></largetable>
</div>
$SCRIPTS$
</body>
</html>

View File

@ -1,119 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {getIntParameter, getStringParameter, bindAction} from '@angular/testing/src/benchmark_util';
declare var angular: any;
const totalRows = getIntParameter('rows');
const totalColumns = getIntParameter('columns');
const benchmarkType = getStringParameter('benchmarkType');
export function main() {
angular.bootstrap(document.querySelector('largetable'), ['app']);
}
angular.module('app', [])
.config(function($compileProvider) {
if ($compileProvider.debugInfoEnabled) {
$compileProvider.debugInfoEnabled(false);
}
})
.filter('noop', function() { return function(input) { return input; }; })
.directive('largetable',
function() {
return {
restrict: 'E',
templateUrl: 'largetable-js-template.html',
controller: 'DataController'
};
})
.controller('DataController',
function($scope) {
bindAction('#destroyDom', destroyDom);
bindAction('#createDom', createDom);
function destroyDom() {
$scope.$apply(function() { $scope.benchmarkType = 'none'; });
}
function createDom() {
$scope.$apply(function() { $scope.benchmarkType = benchmarkType; });
}
const data = $scope.data = [];
function iGetter() { return this.i; }
function jGetter() { return this.j; }
for (let i = 0; i < totalRows; i++) {
data[i] = [];
for (let j = 0; j < totalColumns; j++) {
data[i][j] = {i: i, j: j, iFn: iGetter, jFn: jGetter};
}
}
})
.directive('baselineBindingTable',
function() {
return {
restrict: 'E',
link: function($scope, $element) {
let i, j, row, cell, comment;
const template = document.createElement('span');
template.setAttribute('ng-repeat', 'foo in foos');
template.classList.add('ng-scope');
template.appendChild(document.createElement('span'));
template.appendChild(document.createTextNode(':'));
template.appendChild(document.createElement('span'));
template.appendChild(document.createTextNode('|'));
for (i = 0; i < totalRows; i++) {
row = document.createElement('div');
$element[0].appendChild(row);
for (j = 0; j < totalColumns; j++) {
cell = template.cloneNode(true);
row.appendChild(cell);
cell.childNodes[0].textContent = i;
cell.childNodes[2].textContent = j;
cell.ng3992 = 'xxx';
comment = document.createComment('ngRepeat end: bar in foo');
row.appendChild(comment);
}
comment = document.createComment('ngRepeat end: foo in foos');
$element[0].appendChild(comment);
}
}
};
})
.directive('baselineInterpolationTable', function() {
return {
restrict: 'E',
link: function($scope, $element) {
let i, j, row, cell, comment;
const template = document.createElement('span');
template.setAttribute('ng-repeat', 'foo in foos');
template.classList.add('ng-scope');
for (i = 0; i < totalRows; i++) {
row = document.createElement('div');
$element[0].appendChild(row);
for (j = 0; j < totalColumns; j++) {
cell = template.cloneNode(true);
row.appendChild(cell);
cell.textContent = '' + i + ':' + j + '|';
cell.ng3992 = 'xxx';
comment = document.createComment('ngRepeat end: bar in foo');
row.appendChild(comment);
}
comment = document.createComment('ngRepeat end: foo in foos');
$element[0].appendChild(comment);
}
}
};
});

View File

@ -1,20 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>AngularDart Scrolling Benchmark</title>
</head>
<body>
<form>
App size: <input type="text" name="appSize" value="1"><br>
Iteration count: <input type="text" name="iterationCount" value="1"><br>
Scroll increment: <input type="text" name="scrollIncrement" value="1"><br>
</form>
<div>
<button id="run-btn">Run</button>
<button id="reset-btn">Reset</button>
</div>
<scroll-app></scroll-app>
$SCRIPTS$
</body>
</html>

View File

@ -1,13 +0,0 @@
<div>
<div id="scrollDiv"
ng-style="scrollDivStyle"
ng-scroll="onScroll()">
<div ng-style="paddingStyle"></div>
<div ng-style="innerStyle">
<scroll-item
ng-repeat="item in visibleItems"
offering="item">
</scroll-item>
</div>
</div>
</div>

View File

@ -1,45 +0,0 @@
<div ng-style="itemStyle">
<company-name company="offering.company"
cell-width="companyNameWidth">
</company-name>
<opportunity-name opportunity="offering.opportunity"
cell-width="opportunityNameWidth">
</opportunity-name>
<offering-name offering="offering"
cell-width="offeringNameWidth">
</offering-name>
<account-cell account="offering.account"
cell-width="accountCellWidth">
</account-cell>
<formatted-cell value="offering.basePoints"
cell-width="basePointsWidth">
</formatted-cell>
<formatted-cell value="offering.kickerPoints"
cell-width="kickerPointsWidth">
</formatted-cell>
<stage-buttons offering="offering"
cell-width="stageButtonsWidth">
</stage-buttons>
<formatted-cell value="offering.bundles"
cell-width="bundlesWidth">
</formatted-cell>
<formatted-cell value="offering.dueDate"
cell-width="dueDateWidth">
</formatted-cell>
<formatted-cell value="offering.endDate"
cell-width="endDateWidth">
</formatted-cell>
<formatted-cell value="offering.aatStatus"
cell-width="aatStatusWidth">
</formatted-cell>
</div>

View File

@ -1,17 +0,0 @@
<!doctype html>
<html>
<body>
<h2>AngularJS/Dart 1.x static tree benchmark (depth 10)</h2>
<p>
<button id="destroyDom">destroyDom</button>
<button id="createDom">createDom</button>
</p>
<div>
<tree9 data="initData" ng-if="initData != null" class="app"></tree9>
</div>
$SCRIPTS$
</body>
</html>

View File

@ -1,77 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
// static tree benchmark in AngularJS 1.x
import {getIntParameter, bindAction} from '@angular/testing/src/benchmark_util';
declare var angular: any;
const MAX_DEPTH = 10;
export function main() {
angular.bootstrap(document.querySelector('.app'), ['app']);
}
function addTreeDirective(module, level: number) {
let template;
if (level <= 0) {
template = `<span> {{data.value}}</span>`;
} else {
template = `<span> {{data.value}} <tree${level-1} data='data.right'></tree${level-1}><tree${level-1} data='data.left'></tree${level-1}></span>`;
}
module.directive(`tree${level}`, function() { return {scope: {data: '='}, template: template}; });
}
const module = angular.module('app', []);
for (let depth = 0; depth < MAX_DEPTH; depth++) {
addTreeDirective(module, depth);
}
module.config([
'$compileProvider',
function($compileProvider) { $compileProvider.debugInfoEnabled(false); }
])
.run([
'$rootScope',
function($rootScope) {
let count = 0;
$rootScope.initData = null;
bindAction('#destroyDom', destroyDom);
bindAction('#createDom', createDom);
function createData(): TreeNode {
const values = count++ % 2 == 0 ? ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*'] :
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', '-'];
return buildTree(MAX_DEPTH, values, 0);
}
function destroyDom() {
$rootScope.$apply(function() { $rootScope.initData = null; });
}
function createDom() {
$rootScope.$apply(function() { $rootScope.initData = createData(); });
}
}
]);
class TreeNode {
value: string;
left: TreeNode;
right: TreeNode;
constructor(value, left, right) {
this.value = value;
this.left = left;
this.right = right;
}
}
function buildTree(maxDepth, values, curDepth) {
if (maxDepth === curDepth) return new TreeNode('', null, null);
return new TreeNode(values[curDepth], buildTree(maxDepth, values, curDepth + 1),
buildTree(maxDepth, values, curDepth + 1));
}

View File

@ -1,23 +0,0 @@
<!doctype html>
<html>
<head>
</head>
<body>
<h2>Params</h2>
<form>
Depth:
<input type="number" name="depth" placeholder="depth" value="9">
<br>
<button>Apply</button>
</form>
<button id="destroyDom">destroyDom</button>
<button id="createDom">createDom</button>
<h2>React Tree Benchmark</h2>
<root-tree id="rootTree"></root-tree>
$SCRIPTS$
</body>
</html>

View File

@ -1,73 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
// tree benchmark in React
import {getIntParameter, bindAction} from '@angular/testing/src/benchmark_util';
import * as React from './react.min';
const TreeComponent = React.createClass({
displayName: 'TreeComponent',
render: function() {
const treeNode = this.props.treeNode;
let left = null;
if (treeNode.left) {
left = React.createElement(
"span", {}, [React.createElement(TreeComponent, {treeNode: treeNode.left}, "")]);
}
let right = null;
if (treeNode.right) {
right = React.createElement(
"span", {}, [React.createElement(TreeComponent, {treeNode: treeNode.right}, "")]);
}
const span = React.createElement("span", {}, [" " + treeNode.value, left, right]);
return (React.createElement("tree", {}, [span]));
}
});
export function main() {
let count = 0;
const maxDepth = getIntParameter('depth');
bindAction('#destroyDom', destroyDom);
bindAction('#createDom', createDom);
const empty = new TreeNode(0, null, null);
const rootComponent = React.render(React.createElement(TreeComponent, {treeNode: empty}, ""),
document.getElementById('rootTree'));
function destroyDom() { rootComponent.setProps({treeNode: empty}); }
function createDom() {
const values = count++ % 2 == 0 ? ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*'] :
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', '-'];
rootComponent.setProps({treeNode: buildTree(maxDepth, values, 0)});
}
}
class TreeNode {
value: string;
left: TreeNode;
right: TreeNode;
constructor(value, left, right) {
this.value = value;
this.left = left;
this.right = right;
}
}
function buildTree(maxDepth, values, curDepth) {
if (maxDepth === curDepth) return new TreeNode('', null, null);
return new TreeNode(values[curDepth], buildTree(maxDepth, values, curDepth + 1),
buildTree(maxDepth, values, curDepth + 1));
}

View File

@ -1,3 +0,0 @@
export var createElement: Function;
export var render: Function;
export var createClass: Function;

View File

@ -1,25 +0,0 @@
<!doctype html>
<html>
<body>
<h2>Params</h2>
<form>
Depth:
<input type="number" name="depth" placeholder="depth" value="9">
<br>
<button>Apply</button>
</form>
<h2>AngularJS/Dart 1.x tree benchmark</h2>
<p>
<button id="destroyDom">destroyDom</button>
<button id="createDom">createDom</button>
</p>
<div>
<tree data="initData"></tree>
</div>
$SCRIPTS$
</body>
</html>

View File

@ -1,107 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
// tree benchmark in AngularJS 1.x
import {getIntParameter, bindAction} from '@angular/testing/src/benchmark_util';
declare var angular: any;
export function main() {
angular.bootstrap(document.querySelector('tree'), ['app']);
}
angular.module('app', [])
.directive('tree',
function() {
return {
scope: {data: '='},
template: '<span> {{data.value}}' +
' <span tree-if="data.left"></span>' +
' <span tree-if="data.right"></span>' +
'</span>'
};
})
// special directive for "if" as angular 1.3 does not support
// recursive components.
.directive('treeIf',
[
'$compile',
'$parse',
function($compile, $parse) {
const transcludeFn;
return {
compile: function(element, attrs) {
const expr = $parse('!!' + attrs.treeIf);
const template = '<tree data="' + attrs.treeIf + '"></tree>';
let transclude;
return function($scope, $element, $attrs) {
if (!transclude) {
transclude = $compile(template);
}
let childScope;
let childElement;
$scope.$watch(expr, function(newValue) {
if (childScope) {
childScope.$destroy();
childElement.remove();
childScope = null;
childElement = null;
}
if (newValue) {
childScope = $scope.$new();
childElement = transclude(childScope,
function(clone) { $element.append(clone); });
}
});
};
}
};
}
])
.config([
'$compileProvider',
function($compileProvider) { $compileProvider.debugInfoEnabled(false); }
])
.run([
'$rootScope',
function($rootScope) {
let count = 0;
const maxDepth = getIntParameter('depth');
bindAction('#destroyDom', destroyDom);
bindAction('#createDom', createDom);
function destroyDom() {
$rootScope.$apply(function() { $rootScope.initData = new TreeNode('', null, null); });
}
function createDom() {
const values = count++ % 2 == 0 ? ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*'] :
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', '-'];
$rootScope.$apply(function() { $rootScope.initData = buildTree(maxDepth, values, 0); });
}
}
]);
class TreeNode {
value: string;
left: TreeNode;
right: TreeNode;
constructor(value, left, right) {
this.value = value;
this.left = left;
this.right = right;
}
}
function buildTree(maxDepth, values, curDepth) {
if (maxDepth === curDepth) return new TreeNode('', null, null);
return new TreeNode(values[curDepth], buildTree(maxDepth, values, curDepth + 1),
buildTree(maxDepth, values, curDepth + 1));
}

8
modules/system.d.ts vendored
View File

@ -1,4 +1,10 @@
/** /**
* Dummy typings for systemjs. * @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/ */
/** Dummy typings for systemjs. */
declare var System: any; declare var System: any;

View File

@ -1,6 +1,6 @@
{ {
"name": "angular-srcs", "name": "angular-srcs",
"version": "9.0.3", "version": "9.0.6",
"private": true, "private": true,
"description": "Angular - a web framework for modern web apps", "description": "Angular - a web framework for modern web apps",
"homepage": "https://github.com/angular/angular", "homepage": "https://github.com/angular/angular",
@ -30,7 +30,9 @@
"bazel": "bazel", "bazel": "bazel",
"//circleci-win-comment": "See the test-win circleci job for why these are needed. If they are not needed anymore, remove them.", "//circleci-win-comment": "See the test-win circleci job for why these are needed. If they are not needed anymore, remove them.",
"circleci-win-ve": "bazel test --build_tag_filters=-ivy-only --test_tag_filters=-ivy-only,-browser:chromium-local //packages/compiler-cli/... //tools/ts-api-guardian/...", "circleci-win-ve": "bazel test --build_tag_filters=-ivy-only --test_tag_filters=-ivy-only,-browser:chromium-local //packages/compiler-cli/... //tools/ts-api-guardian/...",
"circleci-win-ivy": "bazel test --config=ivy --build_tag_filters=-no-ivy-aot,-fixme-ivy-aot --test_tag_filters=-no-ivy-aot,-fixme-ivy-aot,-browser:chromium-local //packages/compiler-cli/... //tools/ts-api-guardian/..." "circleci-win-ivy": "bazel test --config=ivy --build_tag_filters=-no-ivy-aot,-fixme-ivy-aot --test_tag_filters=-no-ivy-aot,-fixme-ivy-aot,-browser:chromium-local //packages/compiler-cli/... //tools/ts-api-guardian/...",
"lint": "yarn -s tslint && yarn gulp lint",
"tslint": "tsc -p tools/tsconfig.json && tslint -c tslint.json \"+(packages|modules|scripts|tools)/**/*.+(js|ts)\""
}, },
"// 1": "dependencies are used locally and by bazel", "// 1": "dependencies are used locally and by bazel",
"dependencies": { "dependencies": {
@ -40,8 +42,11 @@
"@angular-devkit/core": "9.0.3", "@angular-devkit/core": "9.0.3",
"@angular-devkit/schematics": "9.0.3", "@angular-devkit/schematics": "9.0.3",
"@angular/bazel": "file:./tools/npm/@angular_bazel", "@angular/bazel": "file:./tools/npm/@angular_bazel",
"@babel/core": "7.8.3", "@babel/core": "^7.8.6",
"@babel/generator": "7.8.3", "@babel/generator": "^7.8.6",
"@babel/template": "^7.8.6",
"@babel/traverse": "^7.8.6",
"@babel/types": "^7.8.6",
"@bazel/jasmine": "1.3.0", "@bazel/jasmine": "1.3.0",
"@bazel/karma": "1.3.0", "@bazel/karma": "1.3.0",
"@bazel/protractor": "1.3.0", "@bazel/protractor": "1.3.0",
@ -51,8 +56,10 @@
"@microsoft/api-extractor": "^7.3.9", "@microsoft/api-extractor": "^7.3.9",
"@schematics/angular": "9.0.3", "@schematics/angular": "9.0.3",
"@types/angular": "^1.6.47", "@types/angular": "^1.6.47",
"@types/babel__core": "^7.1.3", "@types/babel__core": "^7.1.6",
"@types/babel__generator": "^7.6.1", "@types/babel__generator": "^7.6.1",
"@types/babel__template": "^7.0.2",
"@types/babel__traverse": "^7.0.9",
"@types/base64-js": "1.2.5", "@types/base64-js": "1.2.5",
"@types/bluebird": "^3.5.27", "@types/bluebird": "^3.5.27",
"@types/chai": "^4.1.2", "@types/chai": "^4.1.2",
@ -71,7 +78,7 @@
"@types/systemjs": "0.19.32", "@types/systemjs": "0.19.32",
"@types/yaml": "^1.2.0", "@types/yaml": "^1.2.0",
"@types/yargs": "^11.1.1", "@types/yargs": "^11.1.1",
"@webcomponents/custom-elements": "^1.0.4", "@webcomponents/custom-elements": "^1.1.0",
"angular": "npm:angular@1.7", "angular": "npm:angular@1.7",
"angular-1.5": "npm:angular@1.5", "angular-1.5": "npm:angular@1.5",
"angular-1.6": "npm:angular@1.6", "angular-1.6": "npm:angular@1.6",
@ -127,7 +134,7 @@
"terser": "^4.4.0", "terser": "^4.4.0",
"tsickle": "0.38.0", "tsickle": "0.38.0",
"tslib": "^1.10.0", "tslib": "^1.10.0",
"tslint": "5.7.0", "tslint": "6.0.0",
"typescript": "~3.7.4", "typescript": "~3.7.4",
"xhr2": "0.1.4", "xhr2": "0.1.4",
"yaml": "^1.7.2", "yaml": "^1.7.2",
@ -140,6 +147,7 @@
"@bazel/bazel": "2.1.0", "@bazel/bazel": "2.1.0",
"@bazel/buildifier": "^0.29.0", "@bazel/buildifier": "^0.29.0",
"@bazel/ibazel": "^0.11.1", "@bazel/ibazel": "^0.11.1",
"@octokit/graphql": "^4.3.1",
"@types/minimist": "^1.2.0", "@types/minimist": "^1.2.0",
"@yarnpkg/lockfile": "^1.1.0", "@yarnpkg/lockfile": "^1.1.0",
"browserstacktunnel-wrapper": "2.0.1", "browserstacktunnel-wrapper": "2.0.1",
@ -168,9 +176,11 @@
"rewire": "2.5.2", "rewire": "2.5.2",
"sauce-connect": "https://saucelabs.com/downloads/sc-4.5.1-linux.tar.gz", "sauce-connect": "https://saucelabs.com/downloads/sc-4.5.1-linux.tar.gz",
"semver": "^6.3.0", "semver": "^6.3.0",
"tslint-eslint-rules": "4.1.1", "ts-node": "^8.6.2",
"tslint-eslint-rules": "5.4.0",
"tslint-no-toplevel-property-access": "0.0.2", "tslint-no-toplevel-property-access": "0.0.2",
"tsutils": "2.27.2", "tsutils": "2.27.2",
"typed-graphqlify": "^2.3.0",
"universal-analytics": "0.4.15", "universal-analytics": "0.4.15",
"vlq": "0.2.2", "vlq": "0.2.2",
"vrsource-tslint-rules": "5.1.1" "vrsource-tslint-rules": "5.1.1"

View File

@ -1,9 +1,10 @@
/**
// THIS FILE IS AUTOMATICALLY GENERATED. TO UPDATE THIS FILE YOU NEED TO CHANGE THE * @license
// CORRESPONDING JSON SCHEMA FILE, THEN RUN devkit-admin build (or bazel build ...). * Copyright Google Inc. All Rights Reserved.
*
// tslint:disable:no-global-tslint-disable * Use of this source code is governed by an MIT-style license that can be
// tslint:disable * found in the LICENSE file at https://angular.io/license
*/
/** /**
* Options for Bazel Builder * Options for Bazel Builder

View File

@ -318,7 +318,12 @@ def _ngc_tsconfig(ctx, files, srcs, **kwargs):
"createExternalSymbolFactoryReexports": (not _is_bazel()), "createExternalSymbolFactoryReexports": (not _is_bazel()),
# FIXME: wrong place to de-dupe # FIXME: wrong place to de-dupe
"expectedOut": depset([o.path for o in expected_outs]).to_list(), "expectedOut": depset([o.path for o in expected_outs]).to_list(),
# We instruct the compiler to use the host for import generation in Blaze. By default,
# module names between source files of the same compilation unit are relative paths. This
# is not desired in google3 where the generated module names are used as qualified names
# for aliased exports. We disable relative paths and always use manifest paths in google3.
"_useHostForImportGeneration": (not _is_bazel()), "_useHostForImportGeneration": (not _is_bazel()),
"_useManifestPathsAsModuleName": (not _is_bazel()),
} }
if _should_produce_flat_module_outs(ctx): if _should_produce_flat_module_outs(ctx):

View File

@ -77,7 +77,7 @@ def _convert_dash_case_to_camel_case(s):
parts = s.split("-") parts = s.split("-")
# First letter in the result is always unchanged # First letter in the result is always unchanged
return s[0] + "".join([p.title() for p in parts])[1:] return s[0] + "".join([p.capitalize() for p in parts])[1:]
# Convert from a package name on npm to an identifier that's a legal global symbol # Convert from a package name on npm to an identifier that's a legal global symbol
# @angular/core -> ng.core # @angular/core -> ng.core
@ -640,7 +640,7 @@ _NG_PACKAGE_ATTRS = dict(PKG_NPM_ATTRS, **{
"entry_point": attr.label( "entry_point": attr.label(
doc = """The starting point of the application, passed as the `--input` flag to rollup. doc = """The starting point of the application, passed as the `--input` flag to rollup.
If the entry JavaScript file belongs to the same package (as the BUILD file), If the entry JavaScript file belongs to the same package (as the BUILD file),
you can simply reference it by its relative name to the package directory: you can simply reference it by its relative name to the package directory:
``` ```
@ -668,7 +668,7 @@ _NG_PACKAGE_ATTRS = dict(PKG_NPM_ATTRS, **{
The rule will use the corresponding `.js` output of the ts_library rule as the entry point. The rule will use the corresponding `.js` output of the ts_library rule as the entry point.
If the entry point target is a rule, it should produce a single JavaScript entry file that will be passed to the nodejs_binary rule. If the entry point target is a rule, it should produce a single JavaScript entry file that will be passed to the nodejs_binary rule.
For example: For example:
``` ```

View File

@ -113,19 +113,17 @@ export function runOneBuild(args: string[], inputs?: {[path: string]: string}):
} }
} }
const expectedOuts = config['angularCompilerOptions']['expectedOut']; // These are options passed through from the `ng_module` rule which aren't supported
// by the `@angular/compiler-cli` and are only intended for `ngc-wrapped`.
const {expectedOut, _useManifestPathsAsModuleName} = config['angularCompilerOptions'];
const {basePath} = ng.calcProjectFileAndBasePath(project); const {basePath} = ng.calcProjectFileAndBasePath(project);
const compilerOpts = ng.createNgCompilerOptions(basePath, config, tsOptions); const compilerOpts = ng.createNgCompilerOptions(basePath, config, tsOptions);
const tsHost = ts.createCompilerHost(compilerOpts, true); const tsHost = ts.createCompilerHost(compilerOpts, true);
const {diagnostics} = compile({ const {diagnostics} = compile({
allDepsCompiledWithBazel: ALL_DEPS_COMPILED_WITH_BAZEL, allDepsCompiledWithBazel: ALL_DEPS_COMPILED_WITH_BAZEL,
compilerOpts, useManifestPathsAsModuleName: _useManifestPathsAsModuleName,
tsHost, expectedOuts: expectedOut, compilerOpts, tsHost, bazelOpts, files, inputs,
bazelOpts,
files,
inputs,
expectedOuts
}); });
if (diagnostics.length) { if (diagnostics.length) {
console.error(ng.formatDiagnostics(diagnostics)); console.error(ng.formatDiagnostics(diagnostics));
@ -144,9 +142,11 @@ export function relativeToRootDirs(filePath: string, rootDirs: string[]): string
return filePath; return filePath;
} }
export function compile({allDepsCompiledWithBazel = true, compilerOpts, tsHost, bazelOpts, files, export function compile({allDepsCompiledWithBazel = true, useManifestPathsAsModuleName,
inputs, expectedOuts, gatherDiagnostics, bazelHost}: { compilerOpts, tsHost, bazelOpts, files, inputs, expectedOuts,
gatherDiagnostics, bazelHost}: {
allDepsCompiledWithBazel?: boolean, allDepsCompiledWithBazel?: boolean,
useManifestPathsAsModuleName?: boolean,
compilerOpts: ng.CompilerOptions, compilerOpts: ng.CompilerOptions,
tsHost: ts.CompilerHost, inputs?: {[path: string]: string}, tsHost: ts.CompilerHost, inputs?: {[path: string]: string},
bazelOpts: BazelOptions, bazelOpts: BazelOptions,
@ -199,13 +199,14 @@ export function compile({allDepsCompiledWithBazel = true, compilerOpts, tsHost,
throw new Error(`Couldn't find bazel bin in the rootDirs: ${compilerOpts.rootDirs}`); throw new Error(`Couldn't find bazel bin in the rootDirs: ${compilerOpts.rootDirs}`);
} }
const expectedOutsSet = new Set(expectedOuts.map(p => p.replace(/\\/g, '/'))); const expectedOutsSet = new Set(expectedOuts.map(p => convertToForwardSlashPath(p)));
const originalWriteFile = tsHost.writeFile.bind(tsHost); const originalWriteFile = tsHost.writeFile.bind(tsHost);
tsHost.writeFile = tsHost.writeFile =
(fileName: string, content: string, writeByteOrderMark: boolean, (fileName: string, content: string, writeByteOrderMark: boolean,
onError?: (message: string) => void, sourceFiles?: ts.SourceFile[]) => { onError?: (message: string) => void, sourceFiles?: ts.SourceFile[]) => {
const relative = relativeToRootDirs(fileName.replace(/\\/g, '/'), [compilerOpts.rootDir]); const relative =
relativeToRootDirs(convertToForwardSlashPath(fileName), [compilerOpts.rootDir]);
if (expectedOutsSet.has(relative)) { if (expectedOutsSet.has(relative)) {
expectedOutsSet.delete(relative); expectedOutsSet.delete(relative);
originalWriteFile(fileName, content, writeByteOrderMark, onError, sourceFiles); originalWriteFile(fileName, content, writeByteOrderMark, onError, sourceFiles);
@ -290,20 +291,32 @@ export function compile({allDepsCompiledWithBazel = true, compilerOpts, tsHost,
const ngHost = ng.createCompilerHost({options: compilerOpts, tsHost: bazelHost}); const ngHost = ng.createCompilerHost({options: compilerOpts, tsHost: bazelHost});
const fileNameToModuleNameCache = new Map<string, string>(); const fileNameToModuleNameCache = new Map<string, string>();
ngHost.fileNameToModuleName = (importedFilePath: string, containingFilePath: string) => { ngHost.fileNameToModuleName = (importedFilePath: string, containingFilePath?: string) => {
const cacheKey = `${importedFilePath}:${containingFilePath}`;
// Memoize this lookup to avoid expensive re-parses of the same file // Memoize this lookup to avoid expensive re-parses of the same file
// When run as a worker, the actual ts.SourceFile is cached // When run as a worker, the actual ts.SourceFile is cached
// but when we don't run as a worker, there is no cache. // but when we don't run as a worker, there is no cache.
// For one example target in g3, we saw a cache hit rate of 7590/7695 // For one example target in g3, we saw a cache hit rate of 7590/7695
if (fileNameToModuleNameCache.has(importedFilePath)) { if (fileNameToModuleNameCache.has(cacheKey)) {
return fileNameToModuleNameCache.get(importedFilePath); return fileNameToModuleNameCache.get(cacheKey);
} }
const result = doFileNameToModuleName(importedFilePath); const result = doFileNameToModuleName(importedFilePath, containingFilePath);
fileNameToModuleNameCache.set(importedFilePath, result); fileNameToModuleNameCache.set(cacheKey, result);
return result; return result;
}; };
function doFileNameToModuleName(importedFilePath: string): string { function doFileNameToModuleName(importedFilePath: string, containingFilePath?: string): string {
const relativeTargetPath =
relativeToRootDirs(importedFilePath, compilerOpts.rootDirs).replace(EXT, '');
const manifestTargetPath = `${bazelOpts.workspaceName}/${relativeTargetPath}`;
if (useManifestPathsAsModuleName === true) {
return manifestTargetPath;
}
// Unless manifest paths are explicitly enforced, we initially check if a module name is
// set for the given source file. The compiler host from `@bazel/typescript` sets source
// file module names if the compilation targets either UMD or AMD. To ensure that the AMD
// module names match, we first consider those.
try { try {
const sourceFile = ngHost.getSourceFile(importedFilePath, ts.ScriptTarget.Latest); const sourceFile = ngHost.getSourceFile(importedFilePath, ts.ScriptTarget.Latest);
if (sourceFile && sourceFile.moduleName) { if (sourceFile && sourceFile.moduleName) {
@ -342,11 +355,31 @@ export function compile({allDepsCompiledWithBazel = true, compilerOpts, tsHost,
ngHost.amdModuleName) { ngHost.amdModuleName) {
return ngHost.amdModuleName({ fileName: importedFilePath } as ts.SourceFile); return ngHost.amdModuleName({ fileName: importedFilePath } as ts.SourceFile);
} }
const result = relativeToRootDirs(importedFilePath, compilerOpts.rootDirs).replace(EXT, '');
if (result.startsWith(NODE_MODULES)) { // If no AMD module name has been set for the source file by the `@bazel/typescript` compiler
return result.substr(NODE_MODULES.length); // host, and the target file is not part of a flat module node module package, we use the
// following rules (in order):
// 1. If target file is part of `node_modules/`, we use the package module name.
// 2. If no containing file is specified, or the target file is part of a different
// compilation unit, we use a Bazel manifest path. Relative paths are not possible
// since we don't have a containing file, and the target file could be located in the
// output directory, or in an external Bazel repository.
// 3. If both rules above didn't match, we compute a relative path between the source files
// since they are part of the same compilation unit.
// Note that we don't want to always use (2) because it could mean that compilation outputs
// are always leaking Bazel-specific paths, and the output is not self-contained. This could
// break `esm2015` or `esm5` output for Angular package release output
// Omit the `node_modules` prefix if the module name of an NPM package is requested.
if (relativeTargetPath.startsWith(NODE_MODULES)) {
return relativeTargetPath.substr(NODE_MODULES.length);
} else if (
containingFilePath == null || !bazelOpts.compilationTargetSrc.includes(importedFilePath)) {
return manifestTargetPath;
} }
return bazelOpts.workspaceName + '/' + result; const containingFileDir =
path.dirname(relativeToRootDirs(containingFilePath, compilerOpts.rootDirs));
const relativeImportPath = path.posix.relative(containingFileDir, relativeTargetPath);
return relativeImportPath.startsWith('.') ? relativeImportPath : `./${relativeImportPath}`;
} }
ngHost.toSummaryFileName = (fileName: string, referringSrcFileName: string) => path.posix.join( ngHost.toSummaryFileName = (fileName: string, referringSrcFileName: string) => path.posix.join(
@ -464,6 +497,10 @@ function isCompilationTarget(bazelOpts: BazelOptions, sf: ts.SourceFile): boolea
(bazelOpts.compilationTargetSrc.indexOf(sf.fileName) !== -1); (bazelOpts.compilationTargetSrc.indexOf(sf.fileName) !== -1);
} }
function convertToForwardSlashPath(filePath: string): string {
return filePath.replace(/\\/g, '/');
}
function gatherDiagnosticsForInputsOnly( function gatherDiagnosticsForInputsOnly(
options: ng.CompilerOptions, bazelOpts: BazelOptions, options: ng.CompilerOptions, bazelOpts: BazelOptions,
ngProgram: ng.Program): (ng.Diagnostic | ts.Diagnostic)[] { ngProgram: ng.Program): (ng.Diagnostic | ts.Diagnostic)[] {

View File

@ -1,9 +1,10 @@
/**
// THIS FILE IS AUTOMATICALLY GENERATED. TO UPDATE THIS FILE YOU NEED TO CHANGE THE * @license
// CORRESPONDING JSON SCHEMA FILE, THEN RUN devkit-admin build (or bazel build ...). * Copyright Google Inc. All Rights Reserved.
*
// tslint:disable:no-global-tslint-disable * Use of this source code is governed by an MIT-style license that can be
// tslint:disable * found in the LICENSE file at https://angular.io/license
*/
export interface Schema { export interface Schema {
/** /**

View File

@ -1,8 +1,11 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
// THIS FILE IS AUTOMATICALLY GENERATED. TO UPDATE THIS FILE YOU NEED TO CHANGE THE
// CORRESPONDING JSON SCHEMA FILE, THEN RUN devkit-admin build (or bazel build ...).
// tslint:disable
export interface Schema { export interface Schema {
/** /**
* Initial git repository commit information. * Initial git repository commit information.

View File

@ -31,6 +31,8 @@ ng_package(
], ],
deps = [ deps = [
":example", ":example",
"//packages/bazel/test/ng_package/example/a11y",
"//packages/bazel/test/ng_package/example/imports",
"//packages/bazel/test/ng_package/example/secondary", "//packages/bazel/test/ng_package/example/secondary",
], ],
) )

View File

@ -0,0 +1,12 @@
load("//tools:defaults.bzl", "ng_module")
package(default_visibility = ["//packages/bazel/test:__subpackages__"])
ng_module(
name = "a11y",
srcs = glob(["*.ts"]),
module_name = "example/a11y",
deps = [
"//packages/core",
],
)

View File

@ -0,0 +1,9 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
export * from './public-api';

View File

@ -0,0 +1,13 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {NgModule} from '@angular/core';
@NgModule({})
export class A11yModule {
}

View File

@ -0,0 +1,12 @@
load("//tools:defaults.bzl", "ng_module")
package(default_visibility = ["//packages/bazel/test:__subpackages__"])
ng_module(
name = "imports",
srcs = glob(["*.ts"]),
module_name = "example/imports",
deps = [
"//packages/core",
],
)

View File

@ -0,0 +1,9 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
export * from './public-api';

View File

@ -0,0 +1,15 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {Injectable} from '@angular/core';
import {MySecondService} from './second';
@Injectable({providedIn: 'root'})
export class MyService {
constructor(public secondService: MySecondService) {}
}

View File

@ -0,0 +1,13 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {Injectable} from '@angular/core';
@Injectable({providedIn: 'root'})
export class MySecondService {
}

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More