Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions goldens/public-api/angular/build/index.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ export type UnitTestBuilderOptions = {
outputFile?: string;
progress?: boolean;
providersFile?: string;
quiet?: boolean;
reporters?: SchemaReporter[];
runner?: Runner;
runnerConfig?: RunnerConfig;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ export async function executeBuild(
);
}

if (!jsonLogs) {
if (!jsonLogs && !options.quiet) {
const changedFiles =
rebuildState && executionResult.findChangedFiles(rebuildState.previousOutputInfo);
executionResult.addLog(
Expand Down
6 changes: 6 additions & 0 deletions packages/angular/build/src/builders/application/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@ interface InternalOptions {
* Used exclusively for tests and shouldn't be used for other kinds of builds.
*/
instrumentForCoverage?: (filename: string) => boolean;

/**
* Suppress build summary and stats table.
*/
quiet?: boolean;
}

/** Full set of options for `application` builder. */
Expand Down Expand Up @@ -502,6 +507,7 @@ export async function normalizeOptions(
plugins: extensions?.codePlugins?.length ? extensions?.codePlugins : undefined,
loaderExtensions,
jsonLogs: useJSONBuildLogs,
quiet: options.quiet,
colors: supportColor(),
clearScreen,
define,
Expand Down
1 change: 1 addition & 0 deletions packages/angular/build/src/builders/unit-test/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ export async function* execute(
...runnerBuildOptions,
watch: normalizedOptions.watch,
progress: normalizedOptions.buildProgress ?? buildTargetOptions.progress,
quiet: normalizedOptions.quiet,
...(normalizedOptions.tsConfig ? { tsConfig: normalizedOptions.tsConfig } : {}),
} satisfies ApplicationBuilderInternalOptions;

Expand Down
1 change: 1 addition & 0 deletions packages/angular/build/src/builders/unit-test/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ export async function normalizeOptions(
watch,
debug: options.debug ?? false,
ui: process.env['CI'] ? false : ui,
quiet: options.quiet ?? (process.env['CI'] ? false : true),
providersFile: options.providersFile && path.join(workspaceRoot, options.providersFile),
setupFiles: options.setupFiles
? options.setupFiles.map((setupFile) => path.join(workspaceRoot, setupFile))
Expand Down
4 changes: 4 additions & 0 deletions packages/angular/build/src/builders/unit-test/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@
"type": "boolean",
"description": "Enables the Vitest UI for interactive test execution. This option is only available for the Vitest runner."
},
"quiet": {
"type": "boolean",
"description": "Suppresses the verbose build summary and stats table on each rebuild. Defaults to `true` locally and `false` in CI environments."
},
"coverage": {
"type": "boolean",
"description": "Enables coverage reporting for tests. If not specified, the coverage configuration from a runner configuration file will be used if present. Otherwise, coverage is disabled by default."
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/**
* @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.dev/license
*/

import { execute } from '../../index';
import {
BASE_OPTIONS,
describeBuilder,
UNIT_TEST_BUILDER_INFO,
setupApplicationTarget,
expectLog,
expectNoLog,
} from '../setup';

describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => {
describe('Option: "quiet"', () => {
let originalCI: string | undefined;

beforeEach(async () => {
setupApplicationTarget(harness);
originalCI = process.env['CI'];
});

afterEach(() => {
if (originalCI !== undefined) {
process.env['CI'] = originalCI;
} else {
delete process.env['CI'];
}
});

it('should default to true (quiet) when CI is not set', async () => {
delete process.env['CI'];

harness.useTarget('test', {
...BASE_OPTIONS,
});

const { result, logs } = await harness.executeOnce();
expect(result?.success).toBeTrue();
// Should not contain the stats table headers
expectNoLog(logs, /Initial chunk files/);
});

it('should default to false (verbose) when CI is set', async () => {
process.env['CI'] = 'true';

harness.useTarget('test', {
...BASE_OPTIONS,
});

const { result, logs } = await harness.executeOnce();
expect(result?.success).toBeTrue();
// Should contain the stats table headers or file listing
expectLog(logs, /Application bundle generation complete/);
});

it('should respect quiet: true explicitly', async () => {
process.env['CI'] = 'false'; // Ensure CI doesn't interfere if it defaults to false

harness.useTarget('test', {
...BASE_OPTIONS,
quiet: true,
});

const { result, logs } = await harness.executeOnce();
expect(result?.success).toBeTrue();
expectNoLog(logs, /Initial chunk files/);
});

it('should respect quiet: false explicitly', async () => {
harness.useTarget('test', {
...BASE_OPTIONS,
quiet: false,
});

const { result, logs } = await harness.executeOnce();
expect(result?.success).toBeTrue();
// On initial build, it should print the file list
expectLog(logs, /Initial/);
});
});
});
Loading