Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(benchpress): create component_benchmark macro #35692

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .pullapprove.yml
Expand Up @@ -952,6 +952,7 @@ groups:
'tools/build/**',
'tools/circular_dependency_test/**',
'tools/contributing-stats/**',
'tools/components/**'
'tools/gulp-tasks/**',
'tools/ng_rollup_bundle/**',
'tools/ngcontainer/**',
Expand Down
65 changes: 20 additions & 45 deletions modules/benchmarks/src/class_bindings/BUILD.bazel
@@ -1,56 +1,31 @@
package(default_visibility = ["//modules/benchmarks:__subpackages__"])

load("//tools:defaults.bzl", "ng_module", "ng_rollup_bundle", "ts_devserver", "ts_library")
load("//modules/benchmarks:benchmark_test.bzl", "benchmark_test")
load("@io_bazel_rules_sass//sass:sass.bzl", "sass_binary")
load("//tools/components:component_benchmark.bzl", "component_benchmark")

ng_module(
name = "application_lib",
srcs = glob(
["**/*.ts"],
exclude = ["**/*.perf-spec.ts"],
),
generate_ve_shims = True,
deps = [
"//packages:types",
"//packages/common",
"//packages/core",
"//packages/platform-browser",
"@npm//rxjs",
],
sass_binary(
name = "class_bindings_styles",
src = ":styles.scss",
)

ts_library(
name = "perf_lib",
testonly = 1,
srcs = ["class_bindings.perf-spec.ts"],
tsconfig = "//modules/benchmarks:tsconfig-e2e.json",
deps = [
component_benchmark(
name = "benchmark",
driver = ":class_bindings.perf-spec.ts",
driver_deps = [
"//modules/e2e_util",
"@npm//protractor",
],
)

ng_rollup_bundle(
name = "bundle",
entry_point = ":index_aot.ts",
deps = [
":application_lib",
ng_deps = [
"//packages:types",
"//packages/common",
"//packages/core",
"//packages/platform-browser",
"@npm//rxjs",
],
)

ts_devserver(
name = "prodserver",
bootstrap = ["//packages/zone.js/dist:zone.js"],
port = 4200,
static_files = ["index.html"],
deps = [":bundle.min_debug.es2015.js"],
)

benchmark_test(
name = "perf",
server = ":prodserver",
deps = [
":perf_lib",
],
ng_srcs = glob(
["**/*.ts"],
exclude = ["**/*.perf-spec.ts"],
),
prefix = "",
styles = [":class_bindings_styles"],
)
4 changes: 2 additions & 2 deletions modules/benchmarks/src/class_bindings/app.component.ts
Expand Up @@ -8,7 +8,7 @@
import {Component} from '@angular/core';

@Component({
selector: 'app-component',
selector: 'app-root',
template: `
<button id="create" (click)="create()">Create</button>
<button id="update" (click)="update()">Update</button>
Expand All @@ -35,4 +35,4 @@ export class AppComponent {
}

destroy() { this.show = false; }
}
}
27 changes: 0 additions & 27 deletions modules/benchmarks/src/class_bindings/index.html

This file was deleted.

7 changes: 7 additions & 0 deletions modules/benchmarks/src/class_bindings/styles.scss
@@ -0,0 +1,7 @@
.hello {
color: red;
}

.bye {
color: blue;
}
4 changes: 4 additions & 0 deletions tools/components/BUILD.bazel
@@ -0,0 +1,4 @@
# This BUILD file exists to mark //tools/components as a package.
#
# Without this, using component_benchmark.bzl would throw an error saying:
# Label '//tools/components:component_benchmark.bzl' is invalid because 'tools/components' is not a package
141 changes: 141 additions & 0 deletions tools/components/component_benchmark.bzl
@@ -0,0 +1,141 @@
load("//tools:defaults.bzl", "ng_module", "ng_rollup_bundle", "ts_devserver", "ts_library")
load("//modules/benchmarks:benchmark_test.bzl", "benchmark_test")

def copy_default_file(origin, destination):
"""
Copies a file from tools/components/defaults to the destination.

Args:
origin: The name of a file in benchpress/defaults to be copied.
destination: Where the original file will be clopied to.
"""
native.genrule(
name = "copy_default_" + origin + "_file_genrule",
srcs = ["//tools/components/defaults:" + origin],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit (for follow-up): It's more idiomatic to use substitutions. e.g.

"//tools/components/defaults:%s" % origin

Same could be done for all string concatenations in the file.

outs = [destination],
cmd = "cat $(SRCS) >> $@",
)

def component_benchmark(
name,
prefix,
driver,
driver_deps,
ng_srcs,
ng_deps,
assets = None,
styles = None,
entry_point = None,
entry_point_deps = [
"//packages/core",
"//packages/platform-browser",
]):
"""
Runs a benchmark test against the given angular app using the given driver.

This rule was created with the intention of reducing the amount of
duplicate/boilderplate code, while also allowing you to be as verbose with
your app as you'd like. The goal being that if you just want to test a
simple component, the only thing you'd need to provide are the component
(via ng_srcs) and driver.

** USAGE NOTES **

(assets/styles): The default index.html imports a stylesheet named
"styles.css". This allows the use of the default index.html with a custom
stylesheet through the styles arg by providing either a styles.css in the
prefix directory or by providing a css binary named styles.css.

(assets): The default index.html expects that the root selector for
the benchmark app is "app-root".

(entry_point): The default entry_point expects a file named "app.module" to export
the root NgModule for the benchmark application. It also expects that the
root NgModule is named "AppModule".

TIP: The server is named `name + "_server"` so that you can view/debug the
app.

Args:
name: The name of the benchmark_test to be run
prefix: The relative path to the root directory of the benchmark app
driver: The ts driver for running the benchmark
driver_deps: Driver's dependencies
ng_srcs: All of the ts srcs for the angular app
ng_deps: Dependencies for the angular app
assets: Static files
styles: Stylesheets
entry_point: Main entry point for the angular app
entry_point_deps: Entry point's dependencies
"""
app_lib = name + "_app_lib"
app_main = name + "_app_main"
benchmark_driver = name + "_driver"
server = name + "_server"

# If the user doesn't provide assets, entry_point, or styles, we use a
# default version.
# Note that we copy the default files to the same directory as what is used
# by the app for three reasons:
# 1. To avoid having the entry point be defined in a different package from
# where this macro is called.
# 2. So that we can use relative paths for imports in entry point.
# 3. To make using default static files as seamless as possible.

if not entry_point:
entry_point = prefix + "default_index.ts"
ng_srcs.append(entry_point)
copy_default_file("index.ts", entry_point)

if not assets:
html = prefix + "index.html"
assets = [html]
copy_default_file("index.html", html)

if not styles:
css = prefix + "styles.css"
styles = [css]
copy_default_file("styles.css", css)

# Bootstraps the application and creates
# additional files to be imported by the entry_point file.
ng_module(
name = app_lib,
srcs = ng_srcs,
# Creates ngFactory and ngSummary to be imported by the app's entry point.
generate_ve_shims = True,
deps = ng_deps,
)

# Bundle the application (needed by ts_devserver).
ng_rollup_bundle(
name = app_main,
entry_point = entry_point,
deps = [":" + app_lib] + entry_point_deps,
)

# The ts_library for the driver that runs tests against the benchmark app.
ts_library(
name = benchmark_driver,
tsconfig = "//modules/benchmarks:tsconfig-e2e.json",
testonly = True,
srcs = [driver],
deps = driver_deps,
)

# The server for our application.
ts_devserver(
name = server,
bootstrap = ["//packages/zone.js/dist:zone.js"],
port = 4200,
static_files = assets + styles,
deps = [":" + app_main + ".min_debug.es2015.js"],
additional_root_paths = ["tools/components/defaults"],
)

# Runs a protractor test that's set up to use @angular/benchpress.
benchmark_test(
name = name,
server = ":" + server,
deps = [":" + benchmark_driver],
)
7 changes: 7 additions & 0 deletions tools/components/defaults/BUILD.bazel
@@ -0,0 +1,7 @@
package(default_visibility = ["//visibility:public"])

exports_files([
"index.html",
"index.ts",
"styles.css",
])
14 changes: 14 additions & 0 deletions tools/components/defaults/index.html
@@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Benchmark Test</title>
<!-- Prevent favicon.ico requests -->
<link rel="icon" href="data:,">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<app-root id="root">Loading...</app-root>
<script src="/app_bundle.js"></script>
</body>
</html>
Expand Up @@ -5,11 +5,15 @@
* 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
*/

// @ts-ignore Cannot find module
import {enableProdMode} from '@angular/core';

// @ts-ignore Cannot find module
import {platformBrowser} from '@angular/platform-browser';

// @ts-ignore Cannot find module
import {AppModuleNgFactory} from './app.module.ngfactory';

enableProdMode();

platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);
7 changes: 7 additions & 0 deletions tools/components/defaults/styles.css
@@ -0,0 +1,7 @@
/*
* This file exists so that if the default index.html is used a 404 will not
* throw.
*
* We leave an import for "styles.css" in the default index.html for the case
* where someone wants to use index.html and provide their own styles.
*/