diff --git a/.circleci/config.yml b/.circleci/config.yml index f364b2fd7ecb..139118fd9ae2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -29,7 +29,7 @@ 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 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- # Workspace initially persisted by the `setup` job, and then enhanced by `build-npm-packages` and @@ -465,12 +465,14 @@ jobs: - when: condition: << parameters.ivy >> steps: - # Rename the Ivy packages dist folder to "dist/packages-dist" as the AIO - # package installer picks up the locally built packages from that location. + # Rename the "dist/*-dist-ivy-aot" packages directories (persisted to the workspace by + # 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 # two different folders of Angular distributions in the future, we should keep # the packages installer unchanged. - 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. # 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. @@ -552,6 +554,7 @@ jobs: root: *workspace_location paths: - 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 # payload size. diff --git a/.circleci/env.sh b/.circleci/env.sh index 717a4c8f0150..9a9f5bf3d09e 100755 --- a/.circleci/env.sh +++ b/.circleci/env.sh @@ -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_BRANCH "master" # **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" #################################################################################################### diff --git a/.pullapprove.yml b/.pullapprove.yml index dac9bb08c9e0..d4d03bcd3a41 100644 --- a/.pullapprove.yml +++ b/.pullapprove.yml @@ -546,7 +546,6 @@ groups: conditions: - > contains_any_globs(files, [ - 'modules/benchmarks_external/**', 'modules/benchmarks/**' ]) reviewers: @@ -928,6 +927,7 @@ groups: '.github/**', '.vscode/**', '.yarn/**', + 'dev-infra/**', 'docs/BAZEL.md', 'docs/CARETAKER.md', 'docs/COMMITTER.md', @@ -952,6 +952,7 @@ groups: 'tools/browsers/**', 'tools/build/**', 'tools/circular_dependency_test/**', + 'tools/contributing-stats/**', 'tools/gulp-tasks/**', 'tools/ng_rollup_bundle/**', 'tools/ngcontainer/**', diff --git a/CHANGELOG.md b/CHANGELOG.md index 78ced8b9018d..453db71f1a86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,31 @@ + +## [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 `` 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) + + + ## [9.0.5](https://github.com/angular/angular/compare/9.0.4...9.0.5) (2020-03-04) diff --git a/aio/content/examples/dependency-injection/src/app/providers.component.ts b/aio/content/examples/dependency-injection/src/app/providers.component.ts index 6679fe5ec6ec..1467ec07b6a0 100644 --- a/aio/content/examples/dependency-injection/src/app/providers.component.ts +++ b/aio/content/examples/dependency-injection/src/app/providers.component.ts @@ -158,11 +158,11 @@ export class Provider6bComponent { // #docregion silent-logger // 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"'], - log: SilentLoggerFn + log: silentLoggerFn }; // #enddocregion silent-logger @@ -171,7 +171,7 @@ const silentLogger = { template: template, providers: // #docregion providers-7 - [{ provide: Logger, useValue: silentLogger }] + [{ provide: Logger, useValue: SilentLogger }] // #enddocregion providers-7 }) export class Provider7Component { diff --git a/aio/content/guide/http.md b/aio/content/guide/http.md index 75c52cf7cc72..1949597c0d84 100644 --- a/aio/content/guide/http.md +++ b/aio/content/guide/http.md @@ -185,7 +185,7 @@ searchHeroes(term: string): Observable { let heroesURL = `${this.heroesURL}?${term}`; return this.http.jsonp(heroesUrl, 'callback').pipe( - catchError(this.handleError('searchHeroes', []) // then handle the error + catchError(this.handleError('searchHeroes', [])) // then handle the error ); }; ``` diff --git a/aio/content/guide/zone.md b/aio/content/guide/zone.md index e5f033544e54..430ea0b7c5c5 100644 --- a/aio/content/guide/zone.md +++ b/aio/content/guide/zone.md @@ -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. 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. @@ -303,7 +303,7 @@ This service creates a zone named `angular` to automatically trigger change dete ### 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). 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 { constructor(private ngZone: NgZone) {} ngOnInit() { - // new async API is not handled by Zone, so you need to - // use ngZone.run to make the asynchronous operation in angular zone - // and trigger change detection automatically + // New async API is not handled by Zone, so you need to + // use ngZone.run() to make the asynchronous operation in the angular zone + // and trigger change detection automatically. this.ngZone.run(() => { 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 { constructor(private ngZone: NgZone) {} ngOnInit() { - // you know no data will be updated - // you don't want to do change detection in this - // specified operation, you can call runOutsideAngular + // You know no data will be updated, + // so you don't want to trigger change detection in this + // specified operation. Instead, call ngZone.runOutsideAngular() this.ngZone.runOutsideAngular(() => { 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. If you are using the Angular CLI, this step is done automatically, and you will see the following line in the `src/polyfills.ts`: diff --git a/aio/content/marketing/events.html b/aio/content/marketing/events.html index 7cfac7715312..25b3b82eefed 100755 --- a/aio/content/marketing/events.html +++ b/aio/content/marketing/events.html @@ -13,12 +13,6 @@

Events

- - - ngIndia - Delhi, India - Feb 29, 2020 - ng-conf @@ -38,6 +32,12 @@

Events

+ + + ngIndia + Delhi, India + Feb 29, 2020 + ReactiveConf diff --git a/aio/src/styles/2-modules/_search-results.scss b/aio/src/styles/2-modules/_search-results.scss index 4eaee444a806..f6357629e38b 100644 --- a/aio/src/styles/2-modules/_search-results.scss +++ b/aio/src/styles/2-modules/_search-results.scss @@ -106,7 +106,7 @@ aio-search-results { } } - .not-found { + .no-results { color: $darkgray; } diff --git a/aio/tools/ng-packages-installer/index.js b/aio/tools/ng-packages-installer/index.js index 46249c18ad42..b76d4abd4b01 100644 --- a/aio/tools/ng-packages-installer/index.js +++ b/aio/tools/ng-packages-installer/index.js @@ -14,11 +14,12 @@ const LOCAL_MARKER_PATH = 'node_modules/_local_.json'; const ANGULAR_ROOT_DIR = path.resolve(__dirname, '../../..'); const ANGULAR_DIST_PACKAGES_DIR = path.join(ANGULAR_ROOT_DIR, 'dist/packages-dist'); +const ZONEJS_DIST_PACKAGES_DIR = path.join(ANGULAR_ROOT_DIR, 'dist/zone.js-dist'); 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. * * This tool is used to change dependencies of the `aio` application and the example @@ -33,7 +34,7 @@ class NgPackagesInstaller { * @param {object} options - a hash of options for the install: * * `debug` (`boolean`) - whether to display debug messages. * * `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.) * * `ignorePackages` (`string[]`) - a collection of names of packages that should not be copied over. */ @@ -52,7 +53,7 @@ class NgPackagesInstaller { /** * 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. */ checkDependencies() { @@ -62,8 +63,8 @@ class NgPackagesInstaller { } /** - * Install locally built Angular dependencies, overriding the dependencies in the package.json - * This will also write a "marker" file (`_local_.json`), which contains the overridden 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` * contents and acts as an indicator that dependencies have been overridden. */ installLocalDependencies() { @@ -86,13 +87,13 @@ class NgPackagesInstaller { // Prevent accidental publishing of the package, if something goes wrong. 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 => { const deps = tmpConfig[prop] || {}; Object.keys(deps).forEach(key2 => { const pkg2 = packages[key2]; if (pkg2) { - // point the core Angular packages at the distributable folder + // point the local packages at the distributable folder deps[key2] = `file:${pkg2.packageDir}`; this._log(`Overriding dependency of local ${key} with local package: ${key2}: ${deps[key2]}`); } @@ -125,8 +126,8 @@ class NgPackagesInstaller { fs.writeFileSync(pathToPackageConfig, packageConfigFile); } } finally { - // Restore local Angular packages dependencies to other Angular packages. - this._log(`Restoring original ${PACKAGE_JSON} for local Angular packages.`); + // Restore local Angular/Zone.js packages dependencies to other Angular packages. + this._log(`Restoring original ${PACKAGE_JSON} for local packages.`); Object.keys(packages).forEach(key => { const pkg = packages[key]; fs.writeFileSync(pkg.packageJsonPath, JSON.stringify(pkg.config, null, 2)); @@ -167,7 +168,7 @@ class NgPackagesInstaller { } /** - * Build the local Angular packages. + * Build the local Angular/Zone.js packages. * * NOTE: * Building the packages is currently not supported on Windows, so a message is printed instead, prompting the user to @@ -177,14 +178,14 @@ class NgPackagesInstaller { const canBuild = process.platform !== 'win32'; if (canBuild) { - this._log(`Building the Angular packages with: ${DIST_PACKAGES_BUILD_SCRIPT}`); + this._log(`Building the local packages with: ${DIST_PACKAGES_BUILD_SCRIPT}`); shelljs.exec(DIST_PACKAGES_BUILD_CMD); } else { this._warn([ - 'Automatically building the local Angular packages is currently not supported on Windows.', - `Please, ensure '${ANGULAR_DIST_PACKAGES_DIR}' exists and is up-to-date (e.g. by running ` + - `'${DIST_PACKAGES_BUILD_SCRIPT}' in Git Bash for Windows, Windows Subsystem for Linux or a Linux docker ` + - 'container or VM).', + 'Automatically building the local Angular/Zone.js packages is currently not supported on Windows.', + `Please, ensure '${ANGULAR_DIST_PACKAGES_DIR}' and '${ZONEJS_DIST_PACKAGES_DIR}' exist and are up-to-date ` + + `(e.g. by running '${DIST_PACKAGES_BUILD_SCRIPT}' in Git Bash for Windows, Windows Subsystem for Linux or ` + + 'a Linux docker container or VM).', '', 'Proceeding anyway...', ].join('\n')); @@ -204,7 +205,7 @@ class NgPackagesInstaller { // grab peer dependencies const sourcePackagePeerDeps = sourcePackage.config.peerDependencies || {}; 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]) .forEach(key => peerDependencies[key] = sourcePackagePeerDeps[key]); } @@ -214,11 +215,13 @@ class NgPackagesInstaller { } /** - * A hash of Angular package configs. - * (Detected as directories in '/dist/packages-dist/' that contain a top-level 'package.json' file.) + * A hash of Angular/Zone.js package configs. + * (Detected as directories in '/dist/packages-dist/' and '/dist/zone.js-dist/' that contain a top-level + * 'package.json' file.) */ _getDistPackages() { this._log(`Angular distributable directory: ${ANGULAR_DIST_PACKAGES_DIR}.`); + this._log(`Zone.js distributable directory: ${ZONEJS_DIST_PACKAGES_DIR}.`); if (this.buildPackages) { this._buildDistPackages(); @@ -254,7 +257,10 @@ class NgPackagesInstaller { return packages; }; - const packageConfigs = collectPackages(ANGULAR_DIST_PACKAGES_DIR); + 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}`)); return packageConfigs; @@ -343,7 +349,7 @@ class NgPackagesInstaller { // Log a warning. 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:', '', @@ -396,10 +402,10 @@ function main() { .option('debug', { describe: 'Print additional debug information.', 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('ignore-packages', { describe: 'List of Angular packages that should not be used in local mode.', default: [], array: true }) + .option('build-packages', { describe: 'Build the local Angular/Zone.js packages, before using them.', default: false }) + .option('ignore-packages', { describe: 'List of Angular/Zone.js packages that should not be used in local mode.', default: [], array: true }) - .command('overwrite [--force] [--debug] [--ignore-packages package1 package2]', 'Install dependencies from the locally built Angular distributables.', () => {}, argv => { + .command('overwrite [--force] [--debug] [--ignore-packages package1 package2]', 'Install dependencies from the locally built Angular/Zone.js distributables.', () => {}, argv => { createInstaller(argv).installLocalDependencies(); }) .command('restore [--debug]', 'Install dependencies from the npm registry.', () => {}, argv => { diff --git a/aio/tools/ng-packages-installer/index.spec.js b/aio/tools/ng-packages-installer/index.spec.js index 3878859d3c1f..d54153f177c5 100644 --- a/aio/tools/ng-packages-installer/index.spec.js +++ b/aio/tools/ng-packages-installer/index.spec.js @@ -15,6 +15,7 @@ describe('NgPackagesInstaller', () => { const yarnLockPath = path.resolve(absoluteProjectDir, 'yarn.lock'); const ngRootDir = path.resolve(__dirname, '../../..'); 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'); let installer; @@ -51,7 +52,7 @@ describe('NgPackagesInstaller', () => { describe('installLocalDependencies()', () => { const copyJsonObj = obj => JSON.parse(JSON.stringify(obj)); - let dummyNgPackages, dummyPackage, dummyPackageJson, expectedModifiedPackage, expectedModifiedPackageJson; + let dummyLocalPackages, dummyPackage, dummyPackageJson, expectedModifiedPackage, expectedModifiedPackageJson; beforeEach(() => { spyOn(installer, '_checkLocalMarker'); @@ -60,17 +61,18 @@ describe('NgPackagesInstaller', () => { spyOn(installer, '_parseLockfile').and.returnValue({ '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 - dummyNgPackages = { + dummyLocalPackages = { '@angular/core': { packageDir: `${packagesDir}/core`, packageJsonPath: `${packagesDir}/core/package.json`, config: { peerDependencies: { 'rxjs': '^6.4.0', + 'rxjs-dev': '^6.4.0', 'some-package': '5.0.1', 'zone.js': '~0.8.26' } @@ -101,32 +103,40 @@ describe('NgPackagesInstaller', () => { devDependencies: { '@angular/common': '4.4.4-1ab23cd4' }, 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 dummyPackage = { dependencies: { '@angular/core': '4.4.1', '@angular/common': '4.4.1', - rxjs: '^6.3.0' + rxjs: '^6.3.0', + 'zone.js': '^0.8.26' }, devDependencies: { '@angular/compiler-cli': '4.4.1', - 'zone.js': '^0.8.26' + 'rxjs-dev': '^6.3.0' } }; dummyPackageJson = JSON.stringify(dummyPackage); fs.readFileSync.and.returnValue(dummyPackageJson); // 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 - // And that the peerDependencies from `dummyNgPackages` have been updated or added as + // Note that the Angular/Zone.js (dev)dependencies have been modified to use a "file:" path + // and that the peerDependencies from `dummyLocalPackages` have been updated or added as // (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 - // `@angular/core`), thus `zone.js: ^0.8.26` (from original `package.json`) is retained. + // For example, `rxjs-dev@6.4.2` (from lockfile) satisfies `rxjs-dev@^6.4.0` (from + // `@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 // `@angular/core`), thus `rxjs: ^6.3.0` (from original `package.json`) is replaced with // `rxjs: ^6.4.0` (from `@angular/core`). @@ -134,11 +144,12 @@ describe('NgPackagesInstaller', () => { dependencies: { '@angular/core': `file:${packagesDir}/core`, '@angular/common': `file:${packagesDir}/common`, - 'rxjs': '^6.4.0' + 'rxjs': '^6.4.0', + 'zone.js': `file:${zoneJsDir}/zone.js`, }, devDependencies: { '@angular/compiler-cli': `file:${toolsDir}/compiler-cli`, - 'zone.js': '^0.8.26', + 'rxjs-dev': '^6.3.0', 'some-package': '5.0.1', typescript: '^2.4.2' }, @@ -182,31 +193,56 @@ describe('NgPackagesInstaller', () => { }); it('should temporarily overwrite the package.json files of local Angular packages', () => { - const pkgJsonFor = pkgName => dummyNgPackages[`@angular/${pkgName}`].packageJsonPath; - const pkgConfigFor = pkgName => copyJsonObj(dummyNgPackages[`@angular/${pkgName}`].config); + const pkgJsonPathFor = pkgName => dummyLocalPackages[pkgName].packageJsonPath; + const pkgConfigFor = pkgName => copyJsonObj(dummyLocalPackages[pkgName].config); const overwriteConfigFor = (pkgName, newProps) => Object.assign(pkgConfigFor(pkgName), newProps); const stringifyConfig = config => JSON.stringify(config, null, 2); const allArgs = fs.writeFileSync.calls.allArgs(); - const firstFiveArgs = allArgs.slice(0, 5); - const lastFiveArgs = allArgs.slice(-5); - - expect(firstFiveArgs).toEqual([ - [pkgJsonFor('core'), stringifyConfig(overwriteConfigFor('core', {private: true}))], - [pkgJsonFor('common'), stringifyConfig(overwriteConfigFor('common', {private: true}))], - [pkgJsonFor('compiler'), stringifyConfig(overwriteConfigFor('compiler', {private: true}))], - [pkgJsonFor('compiler-cli'), stringifyConfig(overwriteConfigFor('compiler-cli', { - private: true, - dependencies: { '@angular/tsc-wrapped': `file:${toolsDir}/tsc-wrapped` } - }))], - [pkgJsonFor('tsc-wrapped'), stringifyConfig(overwriteConfigFor('tsc-wrapped', { - private: true, - devDependencies: { '@angular/common': `file:${packagesDir}/common` } - }))], + const firstSixArgs = allArgs.slice(0, 6); + const lastSixArgs = allArgs.slice(-6); + + expect(firstSixArgs).toEqual([ + [ + pkgJsonPathFor('@angular/core'), + stringifyConfig(overwriteConfigFor('@angular/core', {private: true})), + ], + [ + pkgJsonPathFor('@angular/common'), + stringifyConfig(overwriteConfigFor('@angular/common', {private: true})), + ], + [ + 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'] - .map(pkgName => [pkgJsonFor(pkgName), stringifyConfig(pkgConfigFor(pkgName))])); + expect(lastSixArgs).toEqual([ + '@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', () => { @@ -280,7 +316,7 @@ describe('NgPackagesInstaller', () => { expect(shelljs.exec).not.toHaveBeenCalled(); 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('Windows Subsystem for Linux'); expect(warning).toContain('Linux docker container or VM'); @@ -309,8 +345,8 @@ describe('NgPackagesInstaller', () => { expect(installer._buildDistPackages).not.toHaveBeenCalled(); }); - it('should include top level Angular packages', () => { - const ngPackages = installer._getDistPackages(); + it('should include top level Angular and Zone.js packages', () => { + const localPackages = installer._getDistPackages(); const expectedValue = jasmine.objectContaining({ packageDir: jasmine.any(String), packageJsonPath: jasmine.any(String), @@ -318,28 +354,30 @@ describe('NgPackagesInstaller', () => { }); // For example... - expect(ngPackages['@angular/common']).toEqual(expectedValue); - expect(ngPackages['@angular/core']).toEqual(expectedValue); - expect(ngPackages['@angular/router']).toEqual(expectedValue); - expect(ngPackages['@angular/upgrade']).toEqual(expectedValue); + expect(localPackages['@angular/common']).toEqual(expectedValue); + expect(localPackages['@angular/core']).toEqual(expectedValue); + expect(localPackages['@angular/router']).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 directory', () => { - const ngPackages = installer._getDistPackages(); + const localPackages = installer._getDistPackages(); // For example... - expect(ngPackages['@angular/core'].packageDir).toBe(path.join(packagesDir, 'core')); - expect(ngPackages['@angular/router'].packageDir).toBe(path.join(packagesDir, 'router')); + expect(localPackages['@angular/core'].packageDir).toBe(path.join(packagesDir, 'core')); + 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', () => { installer = new NgPackagesInstaller(projectDir, { ignorePackages: ['@angular/router'] }); - const ngPackages = installer._getDistPackages(); + const localPackages = installer._getDistPackages(); - expect(ngPackages['@angular/common']).toBeDefined(); - expect(ngPackages['@angular/router']).toBeUndefined(); + expect(localPackages['@angular/common']).toBeDefined(); + expect(localPackages['@angular/router']).toBeUndefined(); }); }); @@ -480,7 +518,7 @@ describe('NgPackagesInstaller', () => { describe('_printWarning()', () => { it('should mention the message passed in the warning', () => { 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', () => { diff --git a/dev-infra/BUILD.bazel b/dev-infra/BUILD.bazel new file mode 100644 index 000000000000..11e9640a56ac --- /dev/null +++ b/dev-infra/BUILD.bazel @@ -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", + ], +) diff --git a/dev-infra/cli.ts b/dev-infra/cli.ts new file mode 100644 index 000000000000..2d7086b568a1 --- /dev/null +++ b/dev-infra/cli.ts @@ -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'); +} diff --git a/dev-infra/package.json b/dev-infra/package.json new file mode 100644 index 000000000000..6c14408cc8d7 --- /dev/null +++ b/dev-infra/package.json @@ -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" + } +} diff --git a/dev-infra/pullapprove/BUILD.bazel b/dev-infra/pullapprove/BUILD.bazel new file mode 100644 index 000000000000..7da7be148474 --- /dev/null +++ b/dev-infra/pullapprove/BUILD.bazel @@ -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", + ], +) diff --git a/dev-infra/pullapprove/verify.ts b/dev-infra/pullapprove/verify.ts new file mode 100644 index 000000000000..e43c4f8287ed --- /dev/null +++ b/dev-infra/pullapprove/verify.ts @@ -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>) { + 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(); + // All files which were not found to match a condition in PullApprove. + const unmatchedFiles = new Set(); + // All PullApprove groups which matched at least one file. + const matchedGroups = new Map>(); + // All PullApprove groups which did not match at least one file. + const unmatchedGroups = new Map>(); + // All condition lines which were not able to be correctly parsed, by group. + const badConditionLinesByGroup = new Map(); + // 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(); + // 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); +} diff --git a/dev-infra/rollup.config.js b/dev-infra/rollup.config.js new file mode 100644 index 000000000000..8c8713475f21 --- /dev/null +++ b/dev-infra/rollup.config.js @@ -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(), + ], +}; diff --git a/integration/_payload-limits.json b/integration/_payload-limits.json index 8441e070c9c0..21cb9fbcb1a7 100644 --- a/integration/_payload-limits.json +++ b/integration/_payload-limits.json @@ -60,7 +60,7 @@ "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): we should define ngDevMode to false in Closure, but --define only works in the global scope.", - "bundle": 175498 + "bundle": 170618 } } } diff --git a/integration/bazel-schematics/test.sh b/integration/bazel-schematics/test.sh index 5728be5f5f5d..0a138dc0cdf3 100755 --- a/integration/bazel-schematics/test.sh +++ b/integration/bazel-schematics/test.sh @@ -38,7 +38,7 @@ function installLocalPackages() { local_packages+=("puppeteer@file:${pwd}/../node_modules/puppeteer") 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() { @@ -58,6 +58,8 @@ function testBazel() { # Create project ng new demo --collection=@angular/bazel --routing --skip-git --skip-install --style=scss cd demo + # Use a local yarn cache folder so we don't access the global yarn cache + mkdir .yarn_local_cache patchKarmaConf patchProtractorConf installLocalPackages @@ -79,7 +81,7 @@ function testNonBazel() { # 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 # 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 test --progress=false --watch=false ng e2e --port 0 --configuration=production --webdriver-update=false diff --git a/integration/ng_elements_schematics/test.ts b/integration/ng_elements_schematics/test.ts index 8e2c7b07d820..75c0a84e951b 100644 --- a/integration/ng_elements_schematics/test.ts +++ b/integration/ng_elements_schematics/test.ts @@ -53,11 +53,13 @@ rm('-rf', `demo`); exec('ng version'); exec('ng new demo --skip-git --skip-install --style=css --no-interactive'); 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 // from root node modules that are to be kept in sync 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 exec(bazelMappings ? `ng add "${bazelMappings['@angular/elements']}"` : `ng add "${__dirname}/../../dist/packages-dist/elements"`); diff --git a/modules/benchmarks_external/README.md b/modules/benchmarks_external/README.md deleted file mode 100644 index 9479c5cd49e0..000000000000 --- a/modules/benchmarks_external/README.md +++ /dev/null @@ -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 diff --git a/modules/benchmarks_external/e2e_test/compiler_perf.ts b/modules/benchmarks_external/e2e_test/compiler_perf.ts deleted file mode 100644 index 50efb856bee7..000000000000 --- a/modules/benchmarks_external/e2e_test/compiler_perf.ts +++ /dev/null @@ -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); - }); - -}); diff --git a/modules/benchmarks_external/e2e_test/largetable_perf.ts b/modules/benchmarks_external/e2e_test/largetable_perf.ts deleted file mode 100644 index c62d19abfaca..000000000000 --- a/modules/benchmarks_external/e2e_test/largetable_perf.ts +++ /dev/null @@ -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); - }); - }); -}); diff --git a/modules/benchmarks_external/e2e_test/naive_infinite_scroll_perf.ts b/modules/benchmarks_external/e2e_test/naive_infinite_scroll_perf.ts deleted file mode 100644 index 7f1e02dfe573..000000000000 --- a/modules/benchmarks_external/e2e_test/naive_infinite_scroll_perf.ts +++ /dev/null @@ -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); - }); - }); - -}); diff --git a/modules/benchmarks_external/e2e_test/react_tree_perf.ts b/modules/benchmarks_external/e2e_test/react_tree_perf.ts deleted file mode 100644 index 3313250616b1..000000000000 --- a/modules/benchmarks_external/e2e_test/react_tree_perf.ts +++ /dev/null @@ -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); - }); - -}); diff --git a/modules/benchmarks_external/e2e_test/static_tree_perf.ts b/modules/benchmarks_external/e2e_test/static_tree_perf.ts deleted file mode 100644 index 6d26c0cd90f2..000000000000 --- a/modules/benchmarks_external/e2e_test/static_tree_perf.ts +++ /dev/null @@ -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); - }); - -}); diff --git a/modules/benchmarks_external/e2e_test/tree_perf.ts b/modules/benchmarks_external/e2e_test/tree_perf.ts deleted file mode 100644 index 54e0f94536ba..000000000000 --- a/modules/benchmarks_external/e2e_test/tree_perf.ts +++ /dev/null @@ -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); - }); - -}); diff --git a/modules/benchmarks_external/src/bootstrap.ts b/modules/benchmarks_external/src/bootstrap.ts deleted file mode 100644 index 20fef436da72..000000000000 --- a/modules/benchmarks_external/src/bootstrap.ts +++ /dev/null @@ -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()'); - - (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(``); - } -}(window)); diff --git a/modules/benchmarks_external/src/compiler/compiler_benchmark.html b/modules/benchmarks_external/src/compiler/compiler_benchmark.html deleted file mode 100644 index 30929d447842..000000000000 --- a/modules/benchmarks_external/src/compiler/compiler_benchmark.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - -

Params

-
- Elements: - -
- -
- -

Actions

-

- - -

- - - - - -$SCRIPTS$ - - - \ No newline at end of file diff --git a/modules/benchmarks_external/src/compiler/compiler_benchmark.ts b/modules/benchmarks_external/src/compiler/compiler_benchmark.ts deleted file mode 100644 index fddeca1e35c8..000000000000 --- a/modules/benchmarks_external/src/compiler/compiler_benchmark.ts +++ /dev/null @@ -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 = (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