diff --git a/.eslintrc.json b/.eslintrc.json index 6988582250d2..52aefec666f7 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -15,6 +15,7 @@ "bazel-out", "dist-schema", "goldens/public-api", + "modules/testing/builder/projects", "packages/angular_devkit/build_angular/src/babel-bazel.d.ts", "packages/angular_devkit/build_angular/test", "packages/angular_devkit/build_webpack/test", diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d269cba7c4d0..e1bf2304e131 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -103,7 +103,9 @@ jobs: uses: angular/dev-infra/github-actions/bazel/configure-remote@f8b2efa171f4ebec4d0cb3d5c5d4f7cb680f2af9 - name: Install node modules run: yarn install --frozen-lockfile - - name: Run tests + - name: Run module tests + run: yarn bazel test //modules/... + - name: Run package tests run: yarn bazel test //packages/... e2e: diff --git a/.prettierignore b/.prettierignore index 20472fa0fa4a..c78211cd0633 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,6 +2,7 @@ /docs/design/analytics.md /dist-schema/ /goldens/public-api +/modules/testing/builder/projects/ /packages/angular_devkit/build_angular/test/ /packages/angular_devkit/core/src/workspace/json/test/ /packages/angular_devkit/schematics_cli/blank/project-files/ diff --git a/modules/testing/builder/BUILD.bazel b/modules/testing/builder/BUILD.bazel new file mode 100644 index 000000000000..bcc6d347cbec --- /dev/null +++ b/modules/testing/builder/BUILD.bazel @@ -0,0 +1,45 @@ +load("@npm//@bazel/jasmine:index.bzl", "jasmine_node_test") +load("//tools:defaults.bzl", "ts_library") + +package(default_visibility = ["//visibility:public"]) + +ts_library( + name = "builder", + testonly = True, + srcs = glob( + include = [ + "src/**/*.ts", + ], + exclude = [ + "src/**/*_spec.ts", + ], + ), + data = glob(["projects/**/*"]), + deps = [ + "//packages/angular_devkit/architect", + "//packages/angular_devkit/architect/node", + "//packages/angular_devkit/architect/testing", + "//packages/angular_devkit/core", + "//packages/angular_devkit/core/node", + "@npm//rxjs", + ], +) + +ts_library( + name = "unit_test_lib", + testonly = True, + srcs = glob( + include = [ + "src/**/*_spec.ts", + ], + ), + deps = [ + ":builder", + "//packages/angular_devkit/architect/testing", + ], +) + +jasmine_node_test( + name = "unit_test", + srcs = [":unit_test_lib"], +) diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/.browserslistrc b/modules/testing/builder/projects/hello-world-app/.browserslistrc similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/.browserslistrc rename to modules/testing/builder/projects/hello-world-app/.browserslistrc diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/.editorconfig b/modules/testing/builder/projects/hello-world-app/.editorconfig similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/.editorconfig rename to modules/testing/builder/projects/hello-world-app/.editorconfig diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/.gitignore b/modules/testing/builder/projects/hello-world-app/.gitignore similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/.gitignore rename to modules/testing/builder/projects/hello-world-app/.gitignore diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/README.md b/modules/testing/builder/projects/hello-world-app/README.md similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/README.md rename to modules/testing/builder/projects/hello-world-app/README.md diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/angular.json b/modules/testing/builder/projects/hello-world-app/angular.json similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/angular.json rename to modules/testing/builder/projects/hello-world-app/angular.json diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/e2e/app.e2e-spec.ts b/modules/testing/builder/projects/hello-world-app/e2e/app.e2e-spec.ts similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/e2e/app.e2e-spec.ts rename to modules/testing/builder/projects/hello-world-app/e2e/app.e2e-spec.ts diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/e2e/app.po.ts b/modules/testing/builder/projects/hello-world-app/e2e/app.po.ts similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/e2e/app.po.ts rename to modules/testing/builder/projects/hello-world-app/e2e/app.po.ts diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/e2e/tsconfig.e2e.json b/modules/testing/builder/projects/hello-world-app/e2e/tsconfig.e2e.json similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/e2e/tsconfig.e2e.json rename to modules/testing/builder/projects/hello-world-app/e2e/tsconfig.e2e.json diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/karma.conf.js b/modules/testing/builder/projects/hello-world-app/karma.conf.js similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/karma.conf.js rename to modules/testing/builder/projects/hello-world-app/karma.conf.js diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/protractor.conf.js b/modules/testing/builder/projects/hello-world-app/protractor.conf.js similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/protractor.conf.js rename to modules/testing/builder/projects/hello-world-app/protractor.conf.js diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/src/app/app.component.css b/modules/testing/builder/projects/hello-world-app/src/app/app.component.css similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/src/app/app.component.css rename to modules/testing/builder/projects/hello-world-app/src/app/app.component.css diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/src/app/app.component.html b/modules/testing/builder/projects/hello-world-app/src/app/app.component.html similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/src/app/app.component.html rename to modules/testing/builder/projects/hello-world-app/src/app/app.component.html diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/src/app/app.component.spec.ts b/modules/testing/builder/projects/hello-world-app/src/app/app.component.spec.ts similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/src/app/app.component.spec.ts rename to modules/testing/builder/projects/hello-world-app/src/app/app.component.spec.ts diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/src/app/app.component.ts b/modules/testing/builder/projects/hello-world-app/src/app/app.component.ts similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/src/app/app.component.ts rename to modules/testing/builder/projects/hello-world-app/src/app/app.component.ts diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/src/app/app.module.server.ts b/modules/testing/builder/projects/hello-world-app/src/app/app.module.server.ts similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/src/app/app.module.server.ts rename to modules/testing/builder/projects/hello-world-app/src/app/app.module.server.ts diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/src/app/app.module.ts b/modules/testing/builder/projects/hello-world-app/src/app/app.module.ts similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/src/app/app.module.ts rename to modules/testing/builder/projects/hello-world-app/src/app/app.module.ts diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/src/assets/.gitkeep b/modules/testing/builder/projects/hello-world-app/src/assets/.gitkeep similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/src/assets/.gitkeep rename to modules/testing/builder/projects/hello-world-app/src/assets/.gitkeep diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/src/favicon.ico b/modules/testing/builder/projects/hello-world-app/src/favicon.ico similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/src/favicon.ico rename to modules/testing/builder/projects/hello-world-app/src/favicon.ico diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/src/index.html b/modules/testing/builder/projects/hello-world-app/src/index.html similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/src/index.html rename to modules/testing/builder/projects/hello-world-app/src/index.html diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/src/locale/messages.xlf b/modules/testing/builder/projects/hello-world-app/src/locale/messages.xlf similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/src/locale/messages.xlf rename to modules/testing/builder/projects/hello-world-app/src/locale/messages.xlf diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/src/main.server.ts b/modules/testing/builder/projects/hello-world-app/src/main.server.ts similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/src/main.server.ts rename to modules/testing/builder/projects/hello-world-app/src/main.server.ts diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/src/main.ts b/modules/testing/builder/projects/hello-world-app/src/main.ts similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/src/main.ts rename to modules/testing/builder/projects/hello-world-app/src/main.ts diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/src/ngsw-config.json b/modules/testing/builder/projects/hello-world-app/src/ngsw-config.json similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/src/ngsw-config.json rename to modules/testing/builder/projects/hello-world-app/src/ngsw-config.json diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/src/polyfills.ts b/modules/testing/builder/projects/hello-world-app/src/polyfills.ts similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/src/polyfills.ts rename to modules/testing/builder/projects/hello-world-app/src/polyfills.ts diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/src/spectrum.png b/modules/testing/builder/projects/hello-world-app/src/spectrum.png similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/src/spectrum.png rename to modules/testing/builder/projects/hello-world-app/src/spectrum.png diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/src/styles.css b/modules/testing/builder/projects/hello-world-app/src/styles.css similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/src/styles.css rename to modules/testing/builder/projects/hello-world-app/src/styles.css diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/src/tsconfig.app.json b/modules/testing/builder/projects/hello-world-app/src/tsconfig.app.json similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/src/tsconfig.app.json rename to modules/testing/builder/projects/hello-world-app/src/tsconfig.app.json diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/src/tsconfig.server.json b/modules/testing/builder/projects/hello-world-app/src/tsconfig.server.json similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/src/tsconfig.server.json rename to modules/testing/builder/projects/hello-world-app/src/tsconfig.server.json diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/src/tsconfig.spec.json b/modules/testing/builder/projects/hello-world-app/src/tsconfig.spec.json similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/src/tsconfig.spec.json rename to modules/testing/builder/projects/hello-world-app/src/tsconfig.spec.json diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/src/typings.d.ts b/modules/testing/builder/projects/hello-world-app/src/typings.d.ts similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/src/typings.d.ts rename to modules/testing/builder/projects/hello-world-app/src/typings.d.ts diff --git a/packages/angular_devkit/build_angular/test/hello-world-app/tsconfig.json b/modules/testing/builder/projects/hello-world-app/tsconfig.json similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-app/tsconfig.json rename to modules/testing/builder/projects/hello-world-app/tsconfig.json diff --git a/packages/angular_devkit/build_angular/src/testing/builder-harness.ts b/modules/testing/builder/src/builder-harness.ts similarity index 99% rename from packages/angular_devkit/build_angular/src/testing/builder-harness.ts rename to modules/testing/builder/src/builder-harness.ts index 05ba0d5d2df5..504b973dd9dc 100644 --- a/packages/angular_devkit/build_angular/src/testing/builder-harness.ts +++ b/modules/testing/builder/src/builder-harness.ts @@ -6,6 +6,8 @@ * found in the LICENSE file at https://angular.io/license */ +/* eslint-disable import/no-extraneous-dependencies */ + import { BuilderContext, BuilderHandlerFn, diff --git a/packages/angular_devkit/build_angular/src/testing/builder-harness_spec.ts b/modules/testing/builder/src/builder-harness_spec.ts similarity index 98% rename from packages/angular_devkit/build_angular/src/testing/builder-harness_spec.ts rename to modules/testing/builder/src/builder-harness_spec.ts index 86d22e1808a7..98a4cc368a1f 100644 --- a/packages/angular_devkit/build_angular/src/testing/builder-harness_spec.ts +++ b/modules/testing/builder/src/builder-harness_spec.ts @@ -6,6 +6,8 @@ * found in the LICENSE file at https://angular.io/license */ +/* eslint-disable import/no-extraneous-dependencies */ + import { TestProjectHost } from '@angular-devkit/architect/testing'; import { BuilderHarness } from './builder-harness'; diff --git a/packages/angular_devkit/build_angular/src/testing/file-watching.ts b/modules/testing/builder/src/file-watching.ts similarity index 80% rename from packages/angular_devkit/build_angular/src/testing/file-watching.ts rename to modules/testing/builder/src/file-watching.ts index 8263fb874ef6..7aad21c7ac97 100644 --- a/packages/angular_devkit/build_angular/src/testing/file-watching.ts +++ b/modules/testing/builder/src/file-watching.ts @@ -6,10 +6,17 @@ * found in the LICENSE file at https://angular.io/license */ -import { - BuilderWatcherCallback, - BuilderWatcherFactory, -} from '../tools/webpack/plugins/builder-watch-plugin'; +type BuilderWatcherCallback = ( + events: Array<{ path: string; type: 'created' | 'modified' | 'deleted'; time?: number }>, +) => void; + +interface BuilderWatcherFactory { + watch( + files: Iterable, + directories: Iterable, + callback: BuilderWatcherCallback, + ): { close(): void }; +} class WatcherDescriptor { constructor( diff --git a/modules/testing/builder/src/index.ts b/modules/testing/builder/src/index.ts new file mode 100644 index 000000000000..9de773e1c456 --- /dev/null +++ b/modules/testing/builder/src/index.ts @@ -0,0 +1,15 @@ +/** + * @license + * Copyright Google LLC 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 { + BuilderHarness, + BuilderHarnessExecutionOptions, + BuilderHarnessExecutionResult, +} from './builder-harness'; +export { HarnessFileMatchers, JasmineBuilderHarness, describeBuilder } from './jasmine-helpers'; +export * from './test-utils'; diff --git a/packages/angular_devkit/build_angular/src/testing/jasmine-helpers.ts b/modules/testing/builder/src/jasmine-helpers.ts similarity index 100% rename from packages/angular_devkit/build_angular/src/testing/jasmine-helpers.ts rename to modules/testing/builder/src/jasmine-helpers.ts diff --git a/modules/testing/builder/src/test-utils.ts b/modules/testing/builder/src/test-utils.ts new file mode 100644 index 000000000000..a710c2b6b1e6 --- /dev/null +++ b/modules/testing/builder/src/test-utils.ts @@ -0,0 +1,176 @@ +/** + * @license + * Copyright Google LLC 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 + */ + +/* eslint-disable import/no-extraneous-dependencies */ + +import { Architect, BuilderOutput, ScheduleOptions, Target } from '@angular-devkit/architect'; +import { WorkspaceNodeModulesArchitectHost } from '@angular-devkit/architect/node'; +import { TestProjectHost, TestingArchitectHost } from '@angular-devkit/architect/testing'; +import { + Path, + getSystemPath, + join, + json, + normalize, + schema, + virtualFs, + workspaces, +} from '@angular-devkit/core'; +import { firstValueFrom } from 'rxjs'; + +// Default timeout for large specs is 2.5 minutes. +jasmine.DEFAULT_TIMEOUT_INTERVAL = 150000; + +export const workspaceRoot = join(normalize(__dirname), `../projects/hello-world-app/`); +export const host = new TestProjectHost(workspaceRoot); +export const outputPath: Path = normalize('dist'); + +export const browserTargetSpec = { project: 'app', target: 'build' }; +export const devServerTargetSpec = { project: 'app', target: 'serve' }; +export const extractI18nTargetSpec = { project: 'app', target: 'extract-i18n' }; +export const karmaTargetSpec = { project: 'app', target: 'test' }; +export const tslintTargetSpec = { project: 'app', target: 'lint' }; +export const protractorTargetSpec = { project: 'app-e2e', target: 'e2e' }; + +export async function createArchitect(workspaceRoot: Path) { + const registry = new schema.CoreSchemaRegistry(); + registry.addPostTransform(schema.transforms.addUndefinedDefaults); + const workspaceSysPath = getSystemPath(workspaceRoot); + + const { workspace } = await workspaces.readWorkspace( + workspaceSysPath, + workspaces.createWorkspaceHost(host), + ); + const architectHost = new TestingArchitectHost( + workspaceSysPath, + workspaceSysPath, + new WorkspaceNodeModulesArchitectHost(workspace, workspaceSysPath), + ); + const architect = new Architect(architectHost, registry); + + return { + workspace, + architectHost, + architect, + }; +} + +export interface BrowserBuildOutput { + output: BuilderOutput; + files: { [file: string]: Promise }; +} + +export async function browserBuild( + architect: Architect, + host: virtualFs.Host, + target: Target, + overrides?: json.JsonObject, + scheduleOptions?: ScheduleOptions, +): Promise { + const run = await architect.scheduleTarget(target, overrides, scheduleOptions); + const output = (await run.result) as BuilderOutput & { outputs: { path: string }[] }; + expect(output.success).toBe(true); + + if (!output.success) { + await run.stop(); + + return { + output, + files: {}, + }; + } + + const [{ path }] = output.outputs; + expect(path).toBeTruthy(); + const outputPath = normalize(path); + + const fileNames = await firstValueFrom(host.list(outputPath)); + const files = fileNames.reduce((acc: { [name: string]: Promise }, path) => { + let cache: Promise | null = null; + Object.defineProperty(acc, path, { + enumerable: true, + get() { + if (cache) { + return cache; + } + if (!fileNames.includes(path)) { + return Promise.reject('No file named ' + path); + } + cache = firstValueFrom(host.read(join(outputPath, path))).then((content) => + virtualFs.fileBufferToString(content), + ); + + return cache; + }, + }); + + return acc; + }, {}); + + await run.stop(); + + return { + output, + files, + }; +} + +export const lazyModuleFiles: { [path: string]: string } = { + 'src/app/lazy/lazy-routing.module.ts': ` + import { NgModule } from '@angular/core'; + import { Routes, RouterModule } from '@angular/router'; + + const routes: Routes = []; + + @NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] + }) + export class LazyRoutingModule { } + `, + 'src/app/lazy/lazy.module.ts': ` + import { NgModule } from '@angular/core'; + import { CommonModule } from '@angular/common'; + + import { LazyRoutingModule } from './lazy-routing.module'; + + @NgModule({ + imports: [ + CommonModule, + LazyRoutingModule + ], + declarations: [] + }) + export class LazyModule { } + `, +}; + +export const lazyModuleFnImport: { [path: string]: string } = { + 'src/app/app.module.ts': ` + import { BrowserModule } from '@angular/platform-browser'; + import { NgModule } from '@angular/core'; + + import { AppComponent } from './app.component'; + import { RouterModule } from '@angular/router'; + + @NgModule({ + declarations: [ + AppComponent + ], + imports: [ + BrowserModule, + RouterModule.forRoot([ + { path: 'lazy', loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule) } + ]) + ], + providers: [], + bootstrap: [AppComponent] + }) + export class AppModule { } +`, +}; diff --git a/packages/angular_devkit/build_angular/BUILD.bazel b/packages/angular_devkit/build_angular/BUILD.bazel index f220ff5bfad3..db6ea2d6481b 100644 --- a/packages/angular_devkit/build_angular/BUILD.bazel +++ b/packages/angular_devkit/build_angular/BUILD.bazel @@ -3,10 +3,10 @@ # 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 +load("@npm//@angular/build-tooling/bazel/api-golden:index.bzl", "api_golden_test_npm_package") load("@npm//@bazel/jasmine:index.bzl", "jasmine_node_test") load("//tools:defaults.bzl", "pkg_npm", "ts_library") load("//tools:ts_json_schema.bzl", "ts_json_schema") -load("@npm//@angular/build-tooling/bazel/api-golden:index.bzl", "api_golden_test_npm_package") licenses(["notice"]) @@ -285,7 +285,6 @@ ts_library( testonly = True, srcs = glob( include = [ - "src/test-utils.ts", "src/testing/**/*.ts", "src/**/tests/*.ts", ], @@ -297,6 +296,7 @@ ts_library( tsconfig = "//:tsconfig-test.json", deps = [ ":build_angular", + "//modules/testing/builder", "//packages/angular_devkit/architect", "//packages/angular_devkit/architect/node", "//packages/angular_devkit/architect/testing", @@ -394,6 +394,7 @@ LARGE_SPECS = { # Dependencies needed to compile and run the specs themselves. ":build_angular", ":build_angular_test_utils", + "//modules/testing/builder", "//packages/angular_devkit/architect", "//packages/angular_devkit/architect/node", "//packages/angular_devkit/architect/testing", diff --git a/packages/angular_devkit/build_angular/src/builders/browser/tests/options/named-chunks_spec.ts b/packages/angular_devkit/build_angular/src/builders/browser/tests/options/named-chunks_spec.ts index 62a69fa1d0a1..72a58ed1f237 100644 --- a/packages/angular_devkit/build_angular/src/builders/browser/tests/options/named-chunks_spec.ts +++ b/packages/angular_devkit/build_angular/src/builders/browser/tests/options/named-chunks_spec.ts @@ -11,7 +11,7 @@ import { BASE_OPTIONS, BROWSER_BUILDER_INFO, describeBuilder } from '../setup'; const MAIN_OUTPUT = 'dist/main.js'; const NAMED_LAZY_OUTPUT = 'dist/src_lazy-module_ts.js'; -const UNNAMED_LAZY_OUTPUT = 'dist/28.js'; +const UNNAMED_LAZY_OUTPUT = 'dist/358.js'; describeBuilder(buildWebpackBrowser, BROWSER_BUILDER_INFO, (harness) => { describe('Option: "namedChunks"', () => { @@ -61,7 +61,7 @@ describeBuilder(buildWebpackBrowser, BROWSER_BUILDER_INFO, (harness) => { const { result } = await harness.executeOnce(); expect(result?.success).toBe(true); - + debugger; harness.expectFile(MAIN_OUTPUT).toExist(); harness.expectFile(NAMED_LAZY_OUTPUT).toNotExist(); harness.expectFile(UNNAMED_LAZY_OUTPUT).toExist(); diff --git a/packages/angular_devkit/build_angular/src/builders/dev-server/tests/execute-fetch.ts b/packages/angular_devkit/build_angular/src/builders/dev-server/tests/execute-fetch.ts index ae928b3dbc8d..eb6d1e029793 100644 --- a/packages/angular_devkit/build_angular/src/builders/dev-server/tests/execute-fetch.ts +++ b/packages/angular_devkit/build_angular/src/builders/dev-server/tests/execute-fetch.ts @@ -12,7 +12,7 @@ import { BuilderHarness, BuilderHarnessExecutionOptions, BuilderHarnessExecutionResult, -} from '../../../testing/builder-harness'; +} from '../../../testing'; export async function executeOnceAndFetch( harness: BuilderHarness, diff --git a/packages/angular_devkit/build_angular/src/builders/dev-server/tests/jasmine-helpers.ts b/packages/angular_devkit/build_angular/src/builders/dev-server/tests/jasmine-helpers.ts index 3bb4438a79df..139fd76c1996 100644 --- a/packages/angular_devkit/build_angular/src/builders/dev-server/tests/jasmine-helpers.ts +++ b/packages/angular_devkit/build_angular/src/builders/dev-server/tests/jasmine-helpers.ts @@ -9,7 +9,7 @@ import { BuilderHandlerFn } from '@angular-devkit/architect'; import { json } from '@angular-devkit/core'; import { readFileSync } from 'fs'; -import { JasmineBuilderHarness } from '../../../testing/jasmine-helpers'; +import { JasmineBuilderHarness } from '../../../testing'; import { host } from '../../../testing/test-utils'; import { setupApplicationTarget, setupBrowserTarget } from './setup'; diff --git a/packages/angular_devkit/build_angular/src/builders/dev-server/tests/options/proxy-config_spec.ts b/packages/angular_devkit/build_angular/src/builders/dev-server/tests/options/proxy-config_spec.ts index d21507e48f93..f1425104f452 100644 --- a/packages/angular_devkit/build_angular/src/builders/dev-server/tests/options/proxy-config_spec.ts +++ b/packages/angular_devkit/build_angular/src/builders/dev-server/tests/options/proxy-config_spec.ts @@ -7,7 +7,7 @@ */ import { createServer } from 'node:http'; -import { JasmineBuilderHarness } from '../../../../testing/jasmine-helpers'; +import { BuilderHarness } from '../../../../testing'; import { executeDevServer } from '../../index'; import { executeOnceAndFetch } from '../execute-fetch'; import { describeServeBuilder } from '../jasmine-helpers'; @@ -275,7 +275,7 @@ async function createProxyServer() { /** * Vite specific tests */ -function viteOnlyTests(harness: JasmineBuilderHarness): void { +function viteOnlyTests(harness: BuilderHarness): void { it('proxies support regexp as context', async () => { harness.useTarget('serve', { ...BASE_OPTIONS, diff --git a/packages/angular_devkit/build_angular/src/builders/dev-server/tests/setup.ts b/packages/angular_devkit/build_angular/src/builders/dev-server/tests/setup.ts index 20d0cdba7287..024372bd3e97 100644 --- a/packages/angular_devkit/build_angular/src/builders/dev-server/tests/setup.ts +++ b/packages/angular_devkit/build_angular/src/builders/dev-server/tests/setup.ts @@ -8,7 +8,7 @@ import { json } from '@angular-devkit/core'; import { readFileSync } from 'fs'; -import { BuilderHarness } from '../../../testing/builder-harness'; +import { BuilderHarness } from '../../../testing'; import { buildApplication } from '../../application'; import { Schema as AppilicationSchema } from '../../application/schema'; import { diff --git a/packages/angular_devkit/build_angular/src/testing/index.ts b/packages/angular_devkit/build_angular/src/testing/index.ts index 51bcba582bbc..d945d4a5018f 100644 --- a/packages/angular_devkit/build_angular/src/testing/index.ts +++ b/packages/angular_devkit/build_angular/src/testing/index.ts @@ -6,5 +6,6 @@ * found in the LICENSE file at https://angular.io/license */ -export { BuilderHarnessExecutionOptions, BuilderHarnessExecutionResult } from './builder-harness'; -export { HarnessFileMatchers, describeBuilder } from './jasmine-helpers'; +// TODO: Consider using package.json imports field instead of relative path +// after the switch to rules_js. +export * from '../../../../../modules/testing/builder/src'; diff --git a/packages/angular_devkit/build_angular/src/testing/test-utils.ts b/packages/angular_devkit/build_angular/src/testing/test-utils.ts index 6ad88f9dce0e..6dca5fb3b5d1 100644 --- a/packages/angular_devkit/build_angular/src/testing/test-utils.ts +++ b/packages/angular_devkit/build_angular/src/testing/test-utils.ts @@ -6,170 +6,4 @@ * found in the LICENSE file at https://angular.io/license */ -import { Architect, BuilderOutput, ScheduleOptions, Target } from '@angular-devkit/architect'; -import { WorkspaceNodeModulesArchitectHost } from '@angular-devkit/architect/node'; -import { TestProjectHost, TestingArchitectHost } from '@angular-devkit/architect/testing'; -import { BrowserBuilderOutput } from '@angular-devkit/build-angular'; -import { - Path, - getSystemPath, - join, - json, - normalize, - schema, - virtualFs, - workspaces, -} from '@angular-devkit/core'; -import { firstValueFrom } from 'rxjs'; - -// Default timeout for large specs is 2.5 minutes. -jasmine.DEFAULT_TIMEOUT_INTERVAL = 150000; - -export const workspaceRoot = join(normalize(__dirname), `../../test/hello-world-app/`); -export const host = new TestProjectHost(workspaceRoot); -export const outputPath: Path = normalize('dist'); - -export const browserTargetSpec = { project: 'app', target: 'build' }; -export const devServerTargetSpec = { project: 'app', target: 'serve' }; -export const extractI18nTargetSpec = { project: 'app', target: 'extract-i18n' }; -export const karmaTargetSpec = { project: 'app', target: 'test' }; -export const tslintTargetSpec = { project: 'app', target: 'lint' }; -export const protractorTargetSpec = { project: 'app-e2e', target: 'e2e' }; - -export async function createArchitect(workspaceRoot: Path) { - const registry = new schema.CoreSchemaRegistry(); - registry.addPostTransform(schema.transforms.addUndefinedDefaults); - const workspaceSysPath = getSystemPath(workspaceRoot); - - const { workspace } = await workspaces.readWorkspace( - workspaceSysPath, - workspaces.createWorkspaceHost(host), - ); - const architectHost = new TestingArchitectHost( - workspaceSysPath, - workspaceSysPath, - new WorkspaceNodeModulesArchitectHost(workspace, workspaceSysPath), - ); - const architect = new Architect(architectHost, registry); - - return { - workspace, - architectHost, - architect, - }; -} - -export interface BrowserBuildOutput { - output: BuilderOutput; - files: { [file: string]: Promise }; -} - -export async function browserBuild( - architect: Architect, - host: virtualFs.Host, - target: Target, - overrides?: json.JsonObject, - scheduleOptions?: ScheduleOptions, -): Promise { - const run = await architect.scheduleTarget(target, overrides, scheduleOptions); - const output = (await run.result) as BrowserBuilderOutput; - expect(output.success).toBe(true); - - if (!output.success) { - await run.stop(); - - return { - output, - files: {}, - }; - } - - const [{ path }] = output.outputs; - expect(path).toBeTruthy(); - const outputPath = normalize(path); - - const fileNames = await firstValueFrom(host.list(outputPath)); - const files = fileNames.reduce((acc: { [name: string]: Promise }, path) => { - let cache: Promise | null = null; - Object.defineProperty(acc, path, { - enumerable: true, - get() { - if (cache) { - return cache; - } - if (!fileNames.includes(path)) { - return Promise.reject('No file named ' + path); - } - cache = firstValueFrom(host.read(join(outputPath, path))).then((content) => - virtualFs.fileBufferToString(content), - ); - - return cache; - }, - }); - - return acc; - }, {}); - - await run.stop(); - - return { - output, - files, - }; -} - -export const lazyModuleFiles: { [path: string]: string } = { - 'src/app/lazy/lazy-routing.module.ts': ` - import { NgModule } from '@angular/core'; - import { Routes, RouterModule } from '@angular/router'; - - const routes: Routes = []; - - @NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] - }) - export class LazyRoutingModule { } - `, - 'src/app/lazy/lazy.module.ts': ` - import { NgModule } from '@angular/core'; - import { CommonModule } from '@angular/common'; - - import { LazyRoutingModule } from './lazy-routing.module'; - - @NgModule({ - imports: [ - CommonModule, - LazyRoutingModule - ], - declarations: [] - }) - export class LazyModule { } - `, -}; - -export const lazyModuleFnImport: { [path: string]: string } = { - 'src/app/app.module.ts': ` - import { BrowserModule } from '@angular/platform-browser'; - import { NgModule } from '@angular/core'; - - import { AppComponent } from './app.component'; - import { RouterModule } from '@angular/router'; - - @NgModule({ - declarations: [ - AppComponent - ], - imports: [ - BrowserModule, - RouterModule.forRoot([ - { path: 'lazy', loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule) } - ]) - ], - providers: [], - bootstrap: [AppComponent] - }) - export class AppModule { } -`, -}; +export * from '../../../../../modules/testing/builder/src';