angular/packages/compiler-cli/test/ngtsc/debug_transform_spec.ts
Doug Parker 05d022d5e6 fix(compiler-cli): ignore generated ngDevMode signal branch for code coverage
The Angular compiler unconditionally adds a debug name transform for signals
which generates a conditional on `ngDevMode` (e.g., `ngDevMode ? { debugName: "xyz" } : []`).
During testing, `ngDevMode` is true, so the true branch executes but the
false branch is never executed. Consequently, coverage tools report the
false branch as an untested line/branch, preventing 100% test coverage.

This commit adds a synthetic `/* istanbul ignore next */` comment to the
generated false branch so that Istanbul ignores it. We only include the
istanbul comment (instead of additionally including c8) to focus on the
established standard for Angular CLI/Karma coverage while maintaining
compatibility with modern Vitest setups, since @vitest/coverage-v8 now
natively respects the fallback istanbul comment.

Fixes #64583

(cherry picked from commit dc4cf649b6)
2026-03-04 22:42:57 +00:00

2971 lines
103 KiB
TypeScript

/**
* @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 {runInEachFileSystem} from '../../src/ngtsc/file_system/testing';
import {loadStandardTestFiles} from '../../src/ngtsc/testing';
import * as esbuild from 'esbuild';
import {NgtscTestEnvironment} from './env';
const testFiles = loadStandardTestFiles({
fakeCommon: true,
});
const minifiedDevBuildOptions = {
minifySyntax: true,
treeShaking: true,
keepNames: true,
define: {ngDevMode: 'true'},
};
const minifiedProdBuildOptions = {
minifySyntax: true,
treeShaking: true,
keepNames: true,
define: {ngDevMode: 'false'},
};
function cleanNewLines(contents: string) {
return contents.replace(/\n/g, ' ').replace(/\s+/g, ' ');
}
runInEachFileSystem(() => {
describe('Debug Info Typescript tranformation', () => {
let env!: NgtscTestEnvironment;
beforeEach(() => {
env = NgtscTestEnvironment.setup(testFiles);
env.tsconfig({}, {target: 'es2018'});
});
describe('signal', () => {
it('should not insert debug info into signal function if not imported from angular core', () => {
env.write(
'test.ts',
`
declare function signal(value: any): any;
const testSignal = signal('Hello World');
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).not.toContain('debugName');
});
it('should insert debug info into signal function if imported from angular core', () => {
env.write(
'test.ts',
`
import {signal} from '@angular/core';
const testSignal = signal('Hello World');
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).toContain(
`signal('Hello World', ...(ngDevMode ? [{ debugName: "testSignal" }] : /* istanbul ignore next */ []))`,
);
});
describe('Variable Declaration Case', () => {
it('should tree-shake away debug info if in prod mode', async () => {
env.write(
'test.ts',
`
import {signal} from '@angular/core';
const testSignal = signal('Hello World');
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).not.toContain('debugName');
expect(builtContent).toContain('signal("Hello World")');
});
it('should not tree-shake away debug info if in dev mode', async () => {
env.write(
'test.ts',
`
import {signal} from '@angular/core';
const testSignal = signal('Hello World');
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(`signal("Hello World", { debugName: "testSignal" });`);
});
it('should insert debug info into signal function that already has custom options', async () => {
env.write(
'test.ts',
`
import {signal} from '@angular/core';
const testSignal = signal('Hello World', { equal: () => true });
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).toContain(
`signal('Hello World', { ...(ngDevMode ? { debugName: "testSignal" } : /* istanbul ignore next */ {}), equal: () => true })`,
);
});
it('should tree-shake away debug info if in prod mode for signal function that has custom options', async () => {
env.write(
'test.ts',
`
import {signal} from '@angular/core';
declare function equal(): boolean;
const testSignal = signal('Hello World', { equal });
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).toContain(`signal("Hello World", { equal });`);
expect(builtContent).not.toContain('ngDevMode');
expect(builtContent).not.toContain('debugName');
});
});
describe('Property Declaration Case', () => {
it('should insert debug info into signal function', () => {
env.write(
'test.ts',
`
import {signal, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent
{
testSignal = signal('Hello World');
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).toContain(
`signal('Hello World', ...(ngDevMode ? [{ debugName: "testSignal" }] : /* istanbul ignore next */ [])`,
);
});
it('should tree-shake away debug info if in prod mode', async () => {
env.write(
'test.ts',
`
import {signal, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent
{
testSignal = signal('Hello World');
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).not.toContain('debugName');
expect(builtContent).toContain('signal("Hello World")');
});
it('should not tree-shake away debug info if in dev mode', async () => {
env.write(
'test.ts',
`
import {signal, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent
{
testSignal = signal('Hello World');
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(`signal("Hello World", { debugName: "testSignal" });`);
});
it('should insert debug info into signal function that already has custom options', async () => {
env.write(
'test.ts',
`
import {signal, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent
{
testSignal = signal('Hello World', { equal: () => true });
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).toContain(
`signal('Hello World', { ...(ngDevMode ? { debugName: "testSignal" } : /* istanbul ignore next */ {}), equal: () => true })`,
);
});
it('should tree-shake away debug info if in prod mode for signal function that has custom options', async () => {
env.write(
'test.ts',
`
import {signal, Component} from '@angular/core';
declare function equal(): boolean;
@Component({
template: ''
}) class MyComponent
{
testSignal = signal('Hello World', { equal });
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).toContain(`signal("Hello World", { equal });`);
expect(builtContent).not.toContain('ngDevMode');
expect(builtContent).not.toContain('debugName');
});
});
describe('Property Assignment Case', () => {
it('should insert debug info into signal function', () => {
env.write(
'test.ts',
`
import {signal, Component, WritableSignal} from '@angular/core';
@Component({
template: ''
}) class MyComponent
{
testSignal: WritableSignal<string>;
constructor() {
this.testSignal = signal('Hello World');
}
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).toContain(
`signal('Hello World', ...(ngDevMode ? [{ debugName: "testSignal" }] : /* istanbul ignore next */ [])`,
);
});
it('should tree-shake away debug info if in prod mode', async () => {
env.write(
'test.ts',
`
import {signal, Component, WritableSignal} from '@angular/core';
@Component({
template: ''
}) class MyComponent
{
testSignal: WritableSignal<string>;
constructor() {
this.testSignal = signal('Hello World');
}
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).not.toContain('debugName');
expect(builtContent).toContain('signal("Hello World")');
});
it('should not tree-shake away debug info if in dev mode', async () => {
env.write(
'test.ts',
`
import {signal, Component, WritableSignal} from '@angular/core';
@Component({
template: ''
}) class MyComponent
{
testSignal: WritableSignal<string>;
constructor() {
this.testSignal = signal('Hello World');
}
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(`signal("Hello World", { debugName: "testSignal" });`);
});
it('should insert debug info into signal function that already has custom options', async () => {
env.write(
'test.ts',
`
import {signal, Component, WritableSignal} from '@angular/core';
@Component({
template: ''
}) class MyComponent
{
testSignal: WritableSignal<string>;
constructor() {
this.testSignal = signal('Hello World', { equal: () => true });
}
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).toContain(
`signal('Hello World', { ...(ngDevMode ? { debugName: "testSignal" } : /* istanbul ignore next */ {}), equal: () => true })`,
);
});
it('should tree-shake away debug info if in prod mode for signal function that has custom options', async () => {
env.write(
'test.ts',
`
import {signal, Component, WritableSignal} from '@angular/core';
declare function equal(): boolean;
@Component({
template: ''
}) class MyComponent
{
testSignal: WritableSignal<string>;
constructor() {
this.testSignal = signal('Hello World', { equal });
}
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).toContain(`signal("Hello World", { equal });`);
expect(builtContent).not.toContain('ngDevMode');
expect(builtContent).not.toContain('debugName');
});
});
});
describe('computed', () => {
it('should not insert debug info into computed function if not imported from angular core', () => {
env.write(
'test.ts',
`
declare function computed(fn: () => any): any;
const testComputed = computed(() => 123);
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).not.toContain('debugName');
});
it('should insert debug info into computed function if imported from angular core', () => {
env.write(
'test.ts',
`
import {signal, computed} from '@angular/core';
const testSignal = signal(123);
const testComputed = computed(() => testSignal());
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).toContain(
`computed(() => testSignal(), ...(ngDevMode ? [{ debugName: "testComputed" }] : /* istanbul ignore next */ []))`,
);
});
describe('Variable Declaration Case', () => {
it('should tree-shake away debug info if in prod mode', async () => {
env.write(
'test.ts',
`
import {signal, computed} from '@angular/core';
const testSignal = signal(123);
const testComputed = computed(() => testSignal());
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).not.toContain('debugName');
expect(builtContent).toContain('computed(() => testSignal())');
});
it('should not tree-shake away debug info if in dev mode', async () => {
env.write(
'test.ts',
`
import {signal, computed} from '@angular/core';
const testSignal = signal(123);
const testComputed = computed(() => testSignal());
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(
`computed(() => testSignal(), { debugName: "testComputed" })`,
);
});
it('should insert debug info into computed function that already has custom options', async () => {
env.write(
'test.ts',
`
import {signal, computed} from '@angular/core';
const testSignal = signal(123);
const testComputed = computed(() => testSignal(), { equal: () => true });
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).toContain(
`computed(() => testSignal(), { ...(ngDevMode ? { debugName: "testComputed" } : /* istanbul ignore next */ {}), equal: () => true })`,
);
});
it('should tree-shake away debug info if in prod mode for computed function that has custom options', async () => {
env.write(
'test.ts',
`
import {signal, computed} from '@angular/core';
declare function equal(): boolean;
const testSignal = signal(123);
const testComputed = computed(() => testSignal(), { equal });
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).toContain(`testComputed = computed(() => testSignal(), { equal })`);
expect(builtContent).not.toContain('ngDevMode');
expect(builtContent).not.toContain('debugName');
});
it('should not tree-shake away debug info if in dev mode and has custom options', async () => {
env.write(
'test.ts',
`
import {signal, computed} from '@angular/core';
declare function equal(): boolean;
const testSignal = signal(123);
const testComputed = computed(() => testSignal(), { equal });
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(
`testComputed = computed(() => testSignal(), { debugName: "testComputed", equal });`,
);
});
});
describe('Property Declaration Case', () => {
it('should tree-shake away debug info if in prod mode', async () => {
env.write(
'test.ts',
`
import {signal, computed, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testSignal = signal(123);
testComputed = computed(() => this.testSignal());
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).not.toContain('debugName');
expect(builtContent).toContain('computed(() => this.testSignal())');
});
it('should not tree-shake away debug info if in dev mode', async () => {
env.write(
'test.ts',
`
import {signal, computed, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testSignal = signal(123);
testComputed = computed(() => this.testSignal());
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(
`computed(() => this.testSignal(), { debugName: "testComputed" })`,
);
});
it('should insert debug info into computed function that already has custom options', async () => {
env.write(
'test.ts',
`
import {signal, computed, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testSignal = signal(123);
testComputed = computed(() => this.testSignal(), { equal: () => true });
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).toContain(
`computed(() => this.testSignal(), { ...(ngDevMode ? { debugName: "testComputed" } : /* istanbul ignore next */ {}), equal: () => true })`,
);
});
it('should tree-shake away debug info if in prod mode for computed function that has custom options', async () => {
env.write(
'test.ts',
`
import {signal, computed, Component} from '@angular/core';
declare function equal(): boolean;
@Component({
template: ''
}) class MyComponent {
testSignal = signal(123);
testComputed = computed(() => this.testSignal(), { equal });
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).toContain(`computed(() => this.testSignal(), { equal })`);
expect(builtContent).not.toContain('ngDevMode');
expect(builtContent).not.toContain('debugName');
});
it('should not tree-shake away debug info if in dev mode and has custom options', async () => {
env.write(
'test.ts',
`
import {signal, computed, Component} from '@angular/core';
declare function equal(): boolean;
@Component({
template: ''
}) class MyComponent {
testSignal = signal(123);
testComputed = computed(() => this.testSignal(), { equal });
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(
`computed(() => this.testSignal(), { debugName: "testComputed", equal });`,
);
});
});
describe('Property Assignment Case', () => {
it('should tree-shake away debug info if in prod mode', async () => {
env.write(
'test.ts',
`
import {signal, computed, Component, WritableSignal, Signal} from '@angular/core';
@Component({
template: ''
}) class MyComponent
{
testSignal: WritableSignal<number>;
testComputed: Signal<number>;
constructor() {
this.testSignal = signal(123);
this.testComputed = computed(() => this.testSignal());
}
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).not.toContain('debugName');
expect(builtContent).toContain('computed(() => this.testSignal())');
});
it('should not tree-shake away debug info if in dev mode', async () => {
env.write(
'test.ts',
`
import {signal, computed, Component, WritableSignal, Signal} from '@angular/core';
@Component({
template: ''
}) class MyComponent
{
testSignal: WritableSignal<number>;
testComputed: Signal<number>;
constructor() {
this.testSignal = signal(123);
this.testComputed = computed(() => this.testSignal());
}
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(
`computed(() => this.testSignal(), { debugName: "testComputed" })`,
);
});
it('should insert debug info into computed function that already has custom options', async () => {
env.write(
'test.ts',
`
import {signal, computed, Component, WritableSignal, Signal} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testSignal: WritableSignal<number>;
testComputed: Signal<number>;
constructor() {
this.testSignal = signal(123);
this.testComputed = computed(() => this.testSignal(), { equal: () => true });
}
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).toContain(
`computed(() => this.testSignal(), { ...(ngDevMode ? { debugName: "testComputed" } : /* istanbul ignore next */ {}), equal: () => true })`,
);
});
it('should tree-shake away debug info if in prod mode for computed function that has custom options', async () => {
env.write(
'test.ts',
`
import {signal, computed, Component, WritableSignal, Signal} from '@angular/core';
declare function equal(): boolean;
@Component({
template: ''
}) class MyComponent {
testSignal: WritableSignal<number>;
testComputed: Signal<number>;
constructor() {
this.testSignal = signal(123);
this.testComputed = computed(() => this.testSignal(), { equal });
}
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).toContain(`computed(() => this.testSignal(), { equal })`);
expect(builtContent).not.toContain('ngDevMode');
expect(builtContent).not.toContain('debugName');
});
it('should not tree-shake away debug info if in dev mode and has custom options', async () => {
env.write(
'test.ts',
`
import {signal, computed, Component, WritableSignal, Signal} from '@angular/core';
declare function equal(): boolean;
@Component({
template: ''
}) class MyComponent {
testSignal: WritableSignal<number>;
testComputed: Signal<number>;
constructor() {
this.testSignal = signal(123);
this.testComputed = computed(() => this.testSignal(), { equal });
}
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(
`computed(() => this.testSignal(), { debugName: "testComputed", equal });`,
);
});
});
});
describe('model', () => {
it('should not insert debug info into model function if not imported from angular core', () => {
env.write(
'test.ts',
`
declare function model(value: any): any;
import {Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testModel = model('Hello World');
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).not.toContain('debugName');
});
it('should insert debug info into model function if imported from angular core', () => {
env.write(
'test.ts',
`
import {model, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testModel = model('Hello World');
testModel2 = model();
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).toContain(
`model('Hello World', ...(ngDevMode ? [{ debugName: "testModel" }] : /* istanbul ignore next */ [])`,
);
expect(jsContents).toContain(
`model(...(ngDevMode ? [undefined, { debugName: "testModel2" }] : /* istanbul ignore next */ [])`,
);
});
it('should tree-shake away debug info if in prod mode', async () => {
env.write(
'test.ts',
`
import {model, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testModel = model('Hello World');
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).not.toContain('debugName');
expect(builtContent).toContain('model("Hello World")');
});
describe('.required', () => {
it('should insert debug info into .required', () => {
env.write(
'test.ts',
`
import {model, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testModel = model.required();
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).toContain(
`model.required(...(ngDevMode ? [{ debugName: "testModel" }] : /* istanbul ignore next */ [])`,
);
});
it('should insert debug info into .required that already has custom options', () => {
env.write(
'test.ts',
`
import {model, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testModel = model.required({ alias: 'testModelAlias' });
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).toContain(
`model.required({ ...(ngDevMode ? { debugName: "testModel" } : /* istanbul ignore next */ {}), alias: 'testModelAlias' })`,
);
});
it('should tree-shake away debug info if in prod mode', async () => {
env.write(
'test.ts',
`
import {model, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testModel = model.required();
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).not.toContain('debugName');
expect(builtContent).toContain('model.required();');
});
it('should not tree-shake away debug info if in dev mode', async () => {
env.write(
'test.ts',
`
import {model, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testModel = model.required();
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(`model.required({ debugName: "testModel" });`);
});
it('should tree-shake away debug info if in prod mode with custom options', async () => {
env.write(
'test.ts',
`
import {model, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testModel = model.required({ alias: 'testModelAlias' });
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).not.toContain('debugName');
expect(builtContent).toContain('model.required({ alias: "testModelAlias" });');
});
it('should not tree-shake away debug info if in dev mode with custom options', async () => {
env.write(
'test.ts',
`
import {model, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testModel = model.required({ alias: 'testModelAlias' });
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(
`model.required({ debugName: "testModel", alias: "testModelAlias" });`,
);
});
});
});
describe('input', () => {
it('should not insert debug info into input function if not imported from angular core', () => {
env.write(
'test.ts',
`
declare function input(): any;
import {Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testInput = input();
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).not.toContain('debugName');
});
it('should insert debug info into input function if imported from angular core', () => {
env.write(
'test.ts',
`
import {input, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testInput = input();
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).toContain(
`input(...(ngDevMode ? [undefined, { debugName: "testInput" }] : /* istanbul ignore next */ [])`,
);
});
it('should tree-shake away debug info if in prod mode', async () => {
env.write(
'test.ts',
`
import {input, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testInput = input();
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).not.toContain('debugName');
expect(builtContent).toContain('input();');
});
describe('.required', () => {
it('should insert debug info into .required', () => {
env.write(
'test.ts',
`
import {input, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testInput = input.required();
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).toContain(
`input.required(...(ngDevMode ? [{ debugName: "testInput" }] : /* istanbul ignore next */ []))`,
);
});
it('should insert debug info into .required that already has custom options', () => {
env.write(
'test.ts',
`
import {input, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testInput = input.required({ alias: 'testInputAlias' });
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).toContain(
`input.required({ ...(ngDevMode ? { debugName: "testInput" } : /* istanbul ignore next */ {}), alias: 'testInputAlias' })`,
);
});
it('should tree-shake away debug info if in prod mode', async () => {
env.write(
'test.ts',
`
import {input, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testInput = input.required();
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).not.toContain('debugName');
expect(builtContent).toContain('input.required();');
});
it('should not tree-shake away debug info if in dev mode', async () => {
env.write(
'test.ts',
`
import {input, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testInput = input.required();
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(`input.required({ debugName: "testInput" });`);
});
it('should tree-shake away debug info if in prod mode with custom options', async () => {
env.write(
'test.ts',
`
import {input, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testInput = input.required({ alias: 'testInputAlias' });
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).not.toContain('debugName');
expect(builtContent).toContain('input.required({ alias: "testInputAlias" });');
});
it('should not tree-shake away debug info if in dev mode with custom options', async () => {
env.write(
'test.ts',
`
import {input, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testInput = input.required({ alias: 'testInputAlias' });
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(
`input.required({ debugName: "testInput", alias: "testInputAlias" });`,
);
});
});
});
describe('viewChild', () => {
it('should not insert debug info into viewChild function if not imported from angular core', () => {
env.write(
'test.ts',
`
declare function viewChild(value: any): any;
import {Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testViewChild = viewChild('foo');
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).not.toContain('debugName');
});
it('should insert debug info into viewChild function if imported from angular core', () => {
env.write(
'test.ts',
`
import {viewChild, Component} from '@angular/core';
@Component({
selector: 'child-component',
template: ''
})
class ChildComponent {}
@Component({
template: '<child-component/>',
imports: [ChildComponent]
})
class MyComponent {
testViewChild = viewChild('foo');
testViewChildComponent = viewChild(ChildComponent);
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).toContain(
`viewChild('foo', ...(ngDevMode ? [{ debugName: "testViewChild" }] : /* istanbul ignore next */ [])`,
);
expect(jsContents).toContain(
`viewChild(ChildComponent, ...(ngDevMode ? [{ debugName: "testViewChildComponent" }] : /* istanbul ignore next */ [])`,
);
});
it('should tree-shake away debug info if in prod mode', async () => {
env.write(
'test.ts',
`
import {viewChild, Component} from '@angular/core';
@Component({
selector: 'child-component',
template: ''
}) class ChildComponent {}
@Component({
template: '<child-component/>',
imports: [ChildComponent]
})
class MyComponent {
testViewChild = viewChild('foo');
testViewChildComponent = viewChild(ChildComponent);
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).not.toContain('debugName');
expect(builtContent).toContain(`viewChild("foo")`);
expect(builtContent).toContain(`viewChild(ChildComponent)`);
});
it('should not tree-shake away debug info if in dev mode', async () => {
env.write(
'test.ts',
`
import {viewChild, Component} from '@angular/core';
@Component({
selector: 'child-component',
template: ''
}) class ChildComponent {}
@Component({
template: '<child-component/>',
imports: [ChildComponent]
})
class MyComponent {
testViewChild = viewChild('foo');
testViewChildComponent = viewChild(ChildComponent);
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(`viewChild("foo", { debugName: "testViewChild" })`);
expect(builtContent).toContain(
`viewChild(ChildComponent, { debugName: "testViewChildComponent" })`,
);
});
it('should tree-shake away debug info if in prod mode with existing options', async () => {
env.write(
'test.ts',
`
import {viewChild, Component, ElementRef} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testViewChild = viewChild('foo', { read: ElementRef });
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).not.toContain('debugName');
expect(builtContent).toContain('viewChild("foo", { read: ElementRef })');
});
it('should not tree-shake away debug info if in dev mode with existing options', async () => {
env.write(
'test.ts',
`
import {viewChild, Component, ElementRef} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testViewChild = viewChild('foo', { read: ElementRef });
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(
`viewChild("foo", { debugName: "testViewChild", read: ElementRef })`,
);
});
});
describe('viewChildren', () => {
it('should not insert debug info into viewChildren function if not imported from angular core', () => {
env.write(
'test.ts',
`
declare function viewChildren(value: any): any;
import {Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testViewChildren = viewChildren('foo');
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).not.toContain('debugName');
});
it('should insert debug info into viewChildren function if imported from angular core', () => {
env.write(
'test.ts',
`
import {viewChildren, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testViewChildren = viewChildren('foo');
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).toContain(
`viewChildren('foo', ...(ngDevMode ? [{ debugName: "testViewChildren" }] : /* istanbul ignore next */ [])`,
);
});
it('should tree-shake away debug info if in prod mode', async () => {
env.write(
'test.ts',
`
import {viewChildren, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testViewChildren = viewChildren('foo');
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).not.toContain('debugName');
expect(builtContent).toContain('viewChildren("foo")');
});
it('should not tree-shake away debug info if in dev mode', async () => {
env.write(
'test.ts',
`
import {viewChildren, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testViewChildren = viewChildren('foo');
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(`viewChildren("foo", { debugName: "testViewChildren" })`);
});
it('should tree-shake away debug info if in prod mode with existing options', async () => {
env.write(
'test.ts',
`
import {viewChildren, Component, ElementRef} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testViewChild = viewChildren('foo', { read: ElementRef });
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).not.toContain('debugName');
expect(builtContent).toContain('viewChildren("foo", { read: ElementRef })');
});
it('should not tree-shake away debug info if in dev mode with existing options', async () => {
env.write(
'test.ts',
`
import {viewChildren, Component, ElementRef} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testViewChild = viewChildren('foo', { read: ElementRef });
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(
`viewChildren("foo", { debugName: "testViewChild", read: ElementRef })`,
);
});
});
describe('contentChild', () => {
it('should not insert debug info into contentChild function if not imported from angular core', () => {
env.write(
'test.ts',
`
import {Component} from '@angular/core';
declare function contentChild(value: any): any;
@Component({
template: ''
}) class MyComponent {
testContentChild = contentChild('foo');
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).not.toContain('debugName');
});
it('should insert debug info into contentChild function if imported from angular core', () => {
env.write(
'test.ts',
`
import {contentChild, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testContentChild = contentChild('foo');
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).toContain(
`contentChild('foo', ...(ngDevMode ? [{ debugName: "testContentChild" }] : /* istanbul ignore next */ [])`,
);
});
it('should tree-shake away debug info if in prod mode', async () => {
env.write(
'test.ts',
`
import {contentChild, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testContentChild = contentChild('foo');
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).not.toContain('debugName');
expect(builtContent).toContain('contentChild("foo")');
});
it('should not tree-shake away debug info if in dev mode', async () => {
env.write(
'test.ts',
`
import {contentChild, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testContentChild = contentChild('foo');
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(`contentChild("foo", { debugName: "testContentChild" })`);
});
it('should tree-shake away debug info if in prod mode with existing options', async () => {
env.write(
'test.ts',
`
import {contentChild, Component, ElementRef} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testContentChild = contentChild('foo', { read: ElementRef });
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).not.toContain('debugName');
expect(builtContent).toContain('contentChild("foo", { read: ElementRef })');
});
it('should not tree-shake away debug info if in dev mode with existing options', async () => {
env.write(
'test.ts',
`
import {contentChild, Component, ElementRef} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testContentChild = contentChild('foo', { read: ElementRef });
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(
`contentChild("foo", { debugName: "testContentChild", read: ElementRef })`,
);
});
});
describe('contentChildren', () => {
it('should not insert debug info into contentChildren function if not imported from angular core', () => {
env.write(
'test.ts',
`
import {Component} from '@angular/core';
declare function contentChildren(value: any): any;
const testContentChildren = contentChildren('foo');
@Component({
template: ''
}) class MyComponent {
testContentChildren = contentChildren('foo');
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).not.toContain('debugName');
});
it('should insert debug info into contentChildren function if imported from angular core', () => {
env.write(
'test.ts',
`
import {contentChildren, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testContentChildren = contentChildren('foo');
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).toContain(
`contentChildren('foo', ...(ngDevMode ? [{ debugName: "testContentChildren" }] : /* istanbul ignore next */ [])`,
);
});
it('should tree-shake away debug info if in prod mode', async () => {
env.write(
'test.ts',
`
import {contentChildren, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testContentChildren = contentChildren('foo');
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).not.toContain('debugName');
expect(builtContent).toContain('contentChildren("foo")');
});
it('should not tree-shake away debug info if in dev mode', async () => {
env.write(
'test.ts',
`
import {contentChildren, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testContentChildren = contentChildren('foo');
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(
`contentChildren("foo", { debugName: "testContentChildren" })`,
);
});
it('should tree-shake away debug info if in prod mode with existing options', async () => {
env.write(
'test.ts',
`
import {contentChildren, Component, ElementRef} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testContentChildren = contentChildren('foo', { read: ElementRef });
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).not.toContain('debugName');
expect(builtContent).toContain('contentChildren("foo", { read: ElementRef })');
});
it('should not tree-shake away debug info if in dev mode with existing options', async () => {
env.write(
'test.ts',
`
import {contentChildren, Component, ElementRef} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testContentChildren = contentChildren('foo', { read: ElementRef });
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(
`contentChildren("foo", { debugName: "testContentChildren", read: ElementRef })`,
);
});
});
describe('effect', () => {
it('should not insert debug info into effect function if not imported from angular core', () => {
env.write(
'test.ts',
`
declare function signal(val: any): any;
declare function effect(fn: () => any): any;
import {Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testSignal = signal(123);
testEffect = effect(() => this.testSignal());
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).not.toContain('debugName');
});
it('should insert debug info into effect function if imported from angular core', () => {
env.write(
'test.ts',
`
import {signal, effect, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testSignal = signal(123);
testEffect = effect(() => this.testSignal());
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).toContain(
`effect(() => this.testSignal(), ...(ngDevMode ? [{ debugName: "testEffect" }] : /* istanbul ignore next */ [])`,
);
});
it('should tree-shake away debug info if in prod mode', async () => {
env.write(
'test.ts',
`
import {signal, effect, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testSignal = signal(123);
testEffect = effect(() => this.testSignal());
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).not.toContain('debugName');
expect(builtContent).toContain('effect(() => this.testSignal())');
});
it('should not tree-shake away debug info if in dev mode', async () => {
env.write(
'test.ts',
`
import {signal, effect, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testSignal = signal(123);
testEffect = effect(() => this.testSignal());
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(
`effect(() => this.testSignal(), { debugName: "testEffect" })`,
);
});
it('should tree-shake away debug info if in prod mode with existing options', async () => {
env.write(
'test.ts',
`
import {signal, effect, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testSignal = signal(123);
testEffect = effect(() => this.testSignal(), { manualCleanup: true, allowSignalWrites: true });
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).not.toContain('debugName');
expect(builtContent).toContain(
'effect(() => this.testSignal(), { manualCleanup: !0, allowSignalWrites: !0 })',
);
});
it('should not tree-shake away debug info if in dev mode with existing options', async () => {
env.write(
'test.ts',
`
import {signal, effect, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testSignal = signal(123);
testEffect = effect(() => this.testSignal(), { manualCleanup: true, allowSignalWrites: true });
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(
`effect(() => this.testSignal(), { debugName: "testEffect", manualCleanup: !0, allowSignalWrites: !0 })`,
);
});
});
describe('linkedSignal', () => {
it('should not insert debug info into linkedSignal function if not imported from angular core', () => {
env.write(
'test.ts',
`
declare function linkedSignal(fn: () => any): any;
const testLinkedSignal = linkedSignal(() => 123);
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).not.toContain('debugName');
});
it('should insert debug info into linkedSignal function if imported from angular core', () => {
env.write(
'test.ts',
`
import {signal, linkedSignal} from '@angular/core';
const testSignal = signal(123);
const testLinkedSignal = linkedSignal(() => testSignal());
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).toContain(
`linkedSignal(() => testSignal(), ...(ngDevMode ? [{ debugName: "testLinkedSignal" }] : /* istanbul ignore next */ [])`,
);
});
describe('Variable Declaration Case', () => {
it('should tree-shake away debug info if in prod mode', async () => {
env.write(
'test.ts',
`
import {signal, linkedSignal} from '@angular/core';
const testSignal = signal(123);
const testLinkedSignal = linkedSignal(() => testSignal());
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).not.toContain('debugName');
expect(builtContent).toContain('linkedSignal(() => testSignal())');
});
it('should not tree-shake away debug info if in dev mode', async () => {
env.write(
'test.ts',
`
import {signal, linkedSignal} from '@angular/core';
const testSignal = signal(123);
const testLinkedSignal = linkedSignal(() => testSignal());
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(
`linkedSignal(() => testSignal(), { debugName: "testLinkedSignal" })`,
);
});
it('should insert debug info into linkedSignal function that already has custom options', async () => {
env.write(
'test.ts',
`
import {signal, linkedSignal} from '@angular/core';
const testSignal = signal(123);
const testLinkedSignal = linkedSignal(() => testSignal(), { equal: () => true });
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).toContain(
`linkedSignal(() => testSignal(), { ...(ngDevMode ? { debugName: "testLinkedSignal" } : /* istanbul ignore next */ {}), equal: () => true })`,
);
});
it('should tree-shake away debug info if in prod mode for linkedSignal function that has custom options', async () => {
env.write(
'test.ts',
`
import {signal, linkedSignal} from '@angular/core';
declare function equal(): boolean;
const testSignal = signal(123);
const testLinkedSignal = linkedSignal(() => testSignal(), { equal });
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).toContain(
`testLinkedSignal = linkedSignal(() => testSignal(), { equal })`,
);
expect(builtContent).not.toContain('ngDevMode');
expect(builtContent).not.toContain('debugName');
});
it('should not tree-shake away debug info if in dev mode and has custom options', async () => {
env.write(
'test.ts',
`
import {signal, linkedSignal} from '@angular/core';
declare function equal(): boolean;
const testSignal = signal(123);
const testLinkedSignal = linkedSignal(() => testSignal(), { equal });
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(
`testLinkedSignal = linkedSignal(() => testSignal(), { debugName: "testLinkedSignal", equal });`,
);
});
it('should insert debug info into linkedSignal with a computation object', async () => {
env.write(
'test.ts',
`
import {signal, linkedSignal} from '@angular/core';
const testSignal = signal(123);
const testLinkedSignal = linkedSignal({
source: testSignal,
computation: (src, prev) => src,
});
`,
);
env.driveMain();
const jsContents = cleanNewLines(env.getContents('test.js'));
expect(jsContents).toContain(
'testLinkedSignal = linkedSignal({ ...(ngDevMode ? { debugName: "testLinkedSignal" } : /* istanbul ignore next */ {}), ' +
'source: testSignal, ' +
'computation: (src, prev) => src ' +
'})',
);
});
it('should tree-shake away debug info if in prod mode for linkedSignal with a computation object', async () => {
env.write(
'test.ts',
`
import {signal, linkedSignal} from '@angular/core';
const computation = (src: any, prev: any) => src;
const testSignal = signal(123);
const testLinkedSignal = linkedSignal({
source: testSignal,
computation,
});
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
const contentWoNewLines = cleanNewLines(builtContent);
expect(contentWoNewLines).toContain(
'testLinkedSignal = linkedSignal({ source: testSignal, computation })',
);
expect(builtContent).not.toContain('ngDevMode');
expect(builtContent).not.toContain('debugName');
});
it('should not tree-shake away debug info if in dev mode and with a computation object', async () => {
env.write(
'test.ts',
`
import {signal, linkedSignal} from '@angular/core';
const computation = (src: any, prev: any) => src;
const testSignal = signal(123);
const testLinkedSignal = linkedSignal({
source: testSignal,
computation,
});
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
const contentWoNewLines = cleanNewLines(builtContent);
expect(contentWoNewLines).toContain(
'testLinkedSignal = linkedSignal({ ' +
'debugName: "testLinkedSignal", ' +
'source: testSignal, ' +
'computation ' +
'})',
);
});
});
describe('Property Declaration Case', () => {
it('should tree-shake away debug info if in prod mode', async () => {
env.write(
'test.ts',
`
import {signal, linkedSignal, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testSignal = signal(123);
testLinkedSignal = linkedSignal(() => this.testSignal());
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).not.toContain('debugName');
expect(builtContent).toContain('linkedSignal(() => this.testSignal())');
});
it('should not tree-shake away debug info if in dev mode', async () => {
env.write(
'test.ts',
`
import {signal, linkedSignal, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testSignal = signal(123);
testLinkedSignal = linkedSignal(() => this.testSignal());
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(
`linkedSignal(() => this.testSignal(), { debugName: "testLinkedSignal" })`,
);
});
it('should insert debug info into linkedSignal function that already has custom options', async () => {
env.write(
'test.ts',
`
import {signal, linkedSignal, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testSignal = signal(123);
testLinkedSignal = linkedSignal(() => this.testSignal(), { equal: () => true });
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).toContain(
`linkedSignal(() => this.testSignal(), { ...(ngDevMode ? { debugName: "testLinkedSignal" } : /* istanbul ignore next */ {}), equal: () => true })`,
);
});
it('should tree-shake away debug info if in prod mode for linkedSignal function that has custom options', async () => {
env.write(
'test.ts',
`
import {signal, linkedSignal, Component} from '@angular/core';
const equal = () => true;
@Component({
template: ''
}) class MyComponent {
testSignal = signal(123);
testLinkedSignal = linkedSignal(() => this.testSignal(), { equal });
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).toContain(
`this.testLinkedSignal = linkedSignal(() => this.testSignal(), { equal })`,
);
expect(builtContent).not.toContain('ngDevMode');
expect(builtContent).not.toContain('debugName');
});
it('should not tree-shake away debug info if in dev mode and has custom options', async () => {
env.write(
'test.ts',
`
import {signal, linkedSignal, Component} from '@angular/core';
const equal = () => true;
@Component({
template: ''
}) class MyComponent {
testSignal = signal(123);
testLinkedSignal = linkedSignal(() => this.testSignal(), { equal });
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(
`this.testLinkedSignal = linkedSignal(() => this.testSignal(), { debugName: "testLinkedSignal", equal });`,
);
});
it('should insert debug info into linkedSignal with a computation object', async () => {
env.write(
'test.ts',
`
import {signal, linkedSignal, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testSignal = signal(123);
testLinkedSignal = linkedSignal({
source: this.testSignal,
computation: (src, prev) => src,
});
}
`,
);
env.driveMain();
const jsContents = cleanNewLines(env.getContents('test.js'));
expect(jsContents).toContain(
'linkedSignal({ ...(ngDevMode ? { debugName: "testLinkedSignal" } : /* istanbul ignore next */ {}), ' +
'source: this.testSignal, ' +
'computation: (src, prev) => src ' +
'})',
);
});
it('should tree-shake away debug info if in prod mode for linkedSignal with a computation object', async () => {
env.write(
'test.ts',
`
import {signal, linkedSignal, Component} from '@angular/core';
const computation = (src: any, prev: any) => src;
@Component({
template: ''
}) class MyComponent {
testSignal = signal(123);
testLinkedSignal = linkedSignal({
source: this.testSignal,
computation,
});
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
const contentWoNewLines = cleanNewLines(builtContent);
expect(contentWoNewLines).toContain(
'this.testLinkedSignal = linkedSignal({ source: this.testSignal, computation })',
);
expect(builtContent).not.toContain('ngDevMode');
expect(builtContent).not.toContain('debugName');
});
it('should not tree-shake away debug info if in dev mode and with a computation object', async () => {
env.write(
'test.ts',
`
import {signal, linkedSignal, Component} from '@angular/core';
const computation = (src: any, prev: any) => src;
@Component({
template: ''
}) class MyComponent {
testSignal = signal(123);
testLinkedSignal = linkedSignal({
source: this.testSignal,
computation,
});
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
const contentWoNewLines = cleanNewLines(builtContent);
expect(contentWoNewLines).toContain(
'this.testLinkedSignal = linkedSignal({ ' +
'debugName: "testLinkedSignal", ' +
'source: this.testSignal, ' +
'computation ' +
'})',
);
});
});
describe('Property Assignment Case', () => {
it('should tree-shake away debug info if in prod mode', async () => {
env.write(
'test.ts',
`
import {signal, linkedSignal, Component, WritableSignal, Signal} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testSignal: WritableSignal<number>;
testLinkedSignal: Signal<number>;
constructor() {
this.testSignal = signal(123);
this.testLinkedSignal = linkedSignal(() => this.testSignal());
}
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).not.toContain('debugName');
expect(builtContent).toContain('linkedSignal(() => this.testSignal())');
});
it('should not tree-shake away debug info if in dev mode', async () => {
env.write(
'test.ts',
`
import {signal, linkedSignal, Component, WritableSignal, Signal} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testSignal: WritableSignal<number>;
testLinkedSignal: Signal<number>;
constructor() {
this.testSignal = signal(123);
this.testLinkedSignal = linkedSignal(() => this.testSignal());
}
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(
`linkedSignal(() => this.testSignal(), { debugName: "testLinkedSignal" })`,
);
});
it('should insert debug info into linkedSignal function that already has custom options', async () => {
env.write(
'test.ts',
`
import {signal, linkedSignal, Component, WritableSignal, Signal} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testSignal: WritableSignal<number>;
testLinkedSignal: Signal<number>;
constructor() {
this.testSignal = signal(123);
this.testLinkedSignal = linkedSignal(() => this.testSignal(), { equal: () => true });
}
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).toContain(
`linkedSignal(() => this.testSignal(), { ...(ngDevMode ? { debugName: "testLinkedSignal" } : /* istanbul ignore next */ {}), equal: () => true })`,
);
});
it('should tree-shake away debug info if in prod mode for linkedSignal function that has custom options', async () => {
env.write(
'test.ts',
`
import {signal, linkedSignal, Component, WritableSignal, Signal} from '@angular/core';
const equal = () => true;
@Component({
template: ''
}) class MyComponent {
testSignal: WritableSignal<number>;
testLinkedSignal: Signal<number>;
constructor() {
this.testSignal = signal(123);
this.testLinkedSignal = linkedSignal(() => this.testSignal(), { equal });
}
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
expect(builtContent).toContain(
`this.testLinkedSignal = linkedSignal(() => this.testSignal(), { equal })`,
);
expect(builtContent).not.toContain('ngDevMode');
expect(builtContent).not.toContain('debugName');
});
it('should not tree-shake away debug info if in dev mode and has custom options', async () => {
env.write(
'test.ts',
`
import {signal, linkedSignal, Component, WritableSignal, Signal} from '@angular/core';
const equal = () => true;
@Component({
template: ''
}) class MyComponent {
testSignal: WritableSignal<number>;
testLinkedSignal: Signal<number>;
constructor() {
this.testSignal = signal(123);
this.testLinkedSignal = linkedSignal(() => this.testSignal(), { equal });
}
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
expect(builtContent).toContain(
`this.testLinkedSignal = linkedSignal(() => this.testSignal(), { debugName: "testLinkedSignal", equal });`,
);
});
it('should insert debug info into linkedSignal with a computation object', async () => {
env.write(
'test.ts',
`
import {signal, linkedSignal, Component, WritableSignal, Signal} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testSignal: WritableSignal<number>;
testLinkedSignal: Signal<number>;
constructor() {
this.testSignal = signal(123);
this.testLinkedSignal = linkedSignal({
source: this.testSignal,
computation: (src, prev) => src,
});
}
}
`,
);
env.driveMain();
const jsContents = cleanNewLines(env.getContents('test.js'));
expect(jsContents).toContain(
'linkedSignal({ ...(ngDevMode ? { debugName: "testLinkedSignal" } : /* istanbul ignore next */ {}), ' +
'source: this.testSignal, ' +
'computation: (src, prev) => src ' +
'})',
);
});
it('should tree-shake away debug info if in prod mode for linkedSignal with a computation object', async () => {
env.write(
'test.ts',
`
import {signal, linkedSignal, Component, WritableSignal, Signal} from '@angular/core';
const computation = (src: any, prev: any) => src;
@Component({
template: ''
}) class MyComponent {
testSignal: WritableSignal<number>;
testLinkedSignal: Signal<number>;
constructor() {
this.testSignal = signal(123);
this.testLinkedSignal = linkedSignal({
source: this.testSignal,
computation,
});
}
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
const contentWoNewLines = cleanNewLines(builtContent);
expect(contentWoNewLines).toContain(
'this.testLinkedSignal = linkedSignal({ source: this.testSignal, computation })',
);
expect(builtContent).not.toContain('ngDevMode');
expect(builtContent).not.toContain('debugName');
});
it('should not tree-shake away debug info if in dev mode and with a computation object', async () => {
env.write(
'test.ts',
`
import {signal, linkedSignal, Component, WritableSignal, Signal} from '@angular/core';
const computation = (src: any, prev: any) => src;
@Component({
template: ''
}) class MyComponent {
testSignal: WritableSignal<number>;
testLinkedSignal: Signal<number>;
constructor() {
this.testSignal = signal(123);
this.testLinkedSignal = linkedSignal({
source: this.testSignal,
computation,
});
}
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
const contentWoNewLines = cleanNewLines(builtContent);
expect(contentWoNewLines).toContain(
'this.testLinkedSignal = linkedSignal({ ' +
'debugName: "testLinkedSignal", ' +
'source: this.testSignal, ' +
'computation ' +
'})',
);
});
});
});
describe('resource', () => {
it('should not insert debug info into resource function if not imported from angular core', () => {
env.write(
'test.ts',
`
declare function resource(props: any): any;
const testResource = resource({
defaultValue: 'foo',
loader: async () => 'bar',
});
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).not.toContain('debugName');
});
it('should insert debug info into resource function if imported from angular core', () => {
env.write(
'test.ts',
`
import {resource} from '@angular/core';
const testResource = resource({
defaultValue: 'foo',
loader: async () => 'bar',
});
`,
);
env.driveMain();
const jsContents = cleanNewLines(env.getContents('test.js'));
expect(jsContents).toContain(
'resource({ ' +
'...(ngDevMode ? { debugName: "testResource" } : /* istanbul ignore next */ {}), ' +
`defaultValue: 'foo', ` +
`loader: async () => 'bar' ` +
'})',
);
});
describe('Variable Declaration Case', () => {
it('should tree-shake away debug info if in prod mode', async () => {
env.write(
'test.ts',
`
import {resource} from '@angular/core';
const loader = async () => 'bar';
const testResource = resource({
defaultValue: "foo",
loader,
});
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
const contentWoNewLines = cleanNewLines(builtContent);
expect(contentWoNewLines).not.toContain('debugName');
expect(contentWoNewLines).toContain(
`testResource = resource({ defaultValue: "foo", loader })`,
);
});
it('should not tree-shake away debug info if in dev mode', async () => {
env.write(
'test.ts',
`
import {resource} from '@angular/core';
const loader = async () => 'bar';
const testResource = resource({
defaultValue: 'foo',
loader,
});
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
const contentWoNewLines = cleanNewLines(builtContent);
expect(contentWoNewLines).toContain(
'testResource = resource({ ' +
'debugName: "testResource", ' +
'defaultValue: "foo", ' +
'loader ' +
'})',
);
});
});
describe('Property Declaration Case', () => {
it('should insert debug info into resource function', () => {
env.write(
'test.ts',
`
import {resource, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testResource = resource({
defaultValue: 'foo',
loader: async () => 'bar',
});
}`,
);
env.driveMain();
const jsContents = cleanNewLines(env.getContents('test.js'));
expect(jsContents).toContain(
'resource({ ' +
'...(ngDevMode ? { debugName: "testResource" } : /* istanbul ignore next */ {}), ' +
`defaultValue: 'foo', ` +
`loader: async () => 'bar' ` +
'})',
);
});
it('should tree-shake away debug info if in prod mode', async () => {
env.write(
'test.ts',
`
import {resource, Component} from '@angular/core';
const loader = async () => 'bar';
@Component({
template: ''
}) class MyComponent {
testResource = resource({
defaultValue: 'foo',
loader,
});
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
const contentWoNewLines = cleanNewLines(builtContent);
expect(contentWoNewLines).not.toContain('debugName');
expect(contentWoNewLines).toContain(
`testResource = resource({ defaultValue: "foo", loader })`,
);
});
it('should not tree-shake away debug info if in dev mode', async () => {
env.write(
'test.ts',
`
import {resource, Component} from '@angular/core';
const loader = async () => 'bar';
@Component({
template: ''
}) class MyComponent {
testResource = resource({
defaultValue: 'foo',
loader,
});
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
const contentWoNewLines = cleanNewLines(builtContent);
expect(contentWoNewLines).toContain(
'testResource = resource({ ' +
'debugName: "testResource", ' +
'defaultValue: "foo", ' +
'loader ' +
'})',
);
});
});
describe('Property Assignment Case', () => {
it('should insert debug info into resource function', () => {
env.write(
'test.ts',
`
import {resource, ResourceRef, Component} from '@angular/core';
@Component({
template: ''
}) class MyComponent {
testResource: ResourceRef<any>;
constructor() {
this.testResource = resource({
defaultValue: 'foo',
loader: async () => 'bar',
});
}
}
`,
);
env.driveMain();
const jsContents = cleanNewLines(env.getContents('test.js'));
expect(jsContents).toContain(
'resource({ ' +
'...(ngDevMode ? { debugName: "testResource" } : /* istanbul ignore next */ {}), ' +
`defaultValue: 'foo', ` +
`loader: async () => 'bar' ` +
'})',
);
});
it('should tree-shake away debug info if in prod mode', async () => {
env.write(
'test.ts',
`
import {resource, ResourceRef, Component} from '@angular/core';
const loader = async () => 'bar';
@Component({
template: ''
}) class MyComponent {
testResource: ResourceRef<any>;
constructor() {
this.testResource = resource({
defaultValue: 'foo',
loader,
});
}
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
const contentWoNewLines = cleanNewLines(builtContent);
expect(contentWoNewLines).not.toContain('debugName');
expect(contentWoNewLines).toContain(
`testResource = resource({ defaultValue: "foo", loader })`,
);
});
it('should not tree-shake away debug info if in dev mode', async () => {
env.write(
'test.ts',
`
import {resource, ResourceRef, Component} from '@angular/core';
const loader = async () => 'bar';
@Component({
template: ''
}) class MyComponent {
testResource: ResourceRef<any>;
constructor() {
this.testResource = resource({
defaultValue: 'foo',
loader,
});
}
}
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
const contentWoNewLines = cleanNewLines(builtContent);
expect(contentWoNewLines).toContain(
'testResource = resource({ ' +
'debugName: "testResource", ' +
'defaultValue: "foo", ' +
'loader ' +
'})',
);
});
});
});
describe('httpResource', () => {
it('should not insert debug info into httpResource function if not imported from angular core', () => {
env.write(
'test.ts',
`
declare function httpResource(props: any): any;
const testResource = httpResource(() => '/api');
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
expect(jsContents).not.toContain('debugName');
});
it('should insert debug info into httpResource function if imported from angular core', () => {
env.write(
'test.ts',
`
import {httpResource} from '@angular/common/http';
const testHttpResource = httpResource(() => '/api');
`,
);
env.driveMain();
const jsContents = cleanNewLines(env.getContents('test.js'));
expect(jsContents).toContain(
`httpResource(() => '/api', ...(ngDevMode ? [{ debugName: "testHttpResource" }] : /* istanbul ignore next */ []))`,
);
});
describe('Variable Declaration Case', () => {
it('should tree-shake away debug info if in prod mode', async () => {
env.write(
'test.ts',
`
import {httpResource} from '@angular/common/http';
const testHttpResource = httpResource(() => '/api');
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
const contentWoNewLines = cleanNewLines(builtContent);
expect(contentWoNewLines).not.toContain('debugName');
expect(contentWoNewLines).toContain(`testHttpResource = httpResource(() => "/api")`);
});
it('should not tree-shake away debug info if in dev mode', async () => {
env.write(
'test.ts',
`
import {httpResource} from '@angular/common/http';
const testHttpResource = httpResource(() => '/api');
`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
const contentWoNewLines = cleanNewLines(builtContent);
expect(contentWoNewLines).toContain(
'testHttpResource = httpResource(() => "/api", { ' +
'debugName: "testHttpResource" ' +
'})',
);
});
});
describe('Property Declaration Case', () => {
it('should insert debug info into httpResource function', () => {
env.write(
'test.ts',
`
import {Component} from '@angular/core';
import {httpResource} from '@angular/common/http';
@Component({
template: ''
}) class MyComponent {
testHttpResource = httpResource(() => '/api');
}`,
);
env.driveMain();
const jsContents = cleanNewLines(env.getContents('test.js'));
expect(jsContents).toContain(
`httpResource(() => '/api', ...(ngDevMode ? [{ debugName: "testHttpResource" }] : /* istanbul ignore next */ []))`,
);
});
it('should tree-shake away debug info if in prod mode', async () => {
env.write(
'test.ts',
`
import {Component} from '@angular/core';
import {httpResource} from '@angular/common/http';
@Component({
template: ''
}) class MyComponent {
testHttpResource = httpResource(() => '/api');
}`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
const contentWoNewLines = cleanNewLines(builtContent);
expect(contentWoNewLines).not.toContain('debugName');
expect(contentWoNewLines).toContain(`testHttpResource = httpResource(() => "/api")`);
});
it('should not tree-shake away debug info if in dev mode', async () => {
env.write(
'test.ts',
`
import {Component} from '@angular/core';
import {httpResource} from '@angular/common/http';
@Component({
template: ''
}) class MyComponent {
testHttpResource = httpResource(() => '/api');
}`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
const contentWoNewLines = cleanNewLines(builtContent);
expect(contentWoNewLines).toContain(
'testHttpResource = httpResource(() => "/api", { ' +
'debugName: "testHttpResource" ' +
'})',
);
});
});
describe('Property Assignment Case', () => {
it('should insert debug info into httpResource function', () => {
env.write(
'test.ts',
`
import {Component} from '@angular/core';
import {httpResource, HttpResourceRef} from '@angular/common/http';
@Component({
template: ''
}) class MyComponent {
testHttpResource: HttpResourceRef<any>;
constructor() {
this.testHttpResource = httpResource(() => '/api');
}
}`,
);
env.driveMain();
const jsContents = cleanNewLines(env.getContents('test.js'));
expect(jsContents).toContain(
`httpResource(() => '/api', ...(ngDevMode ? [{ debugName: "testHttpResource" }] : /* istanbul ignore next */ []))`,
);
});
it('should tree-shake away debug info if in prod mode', async () => {
env.write(
'test.ts',
`
import {Component} from '@angular/core';
import {httpResource, HttpResourceRef} from '@angular/common/http';
@Component({
template: ''
}) class MyComponent {
testHttpResource: HttpResourceRef<any>;
constructor() {
this.testHttpResource = httpResource(() => '/api');
}
}`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedProdBuildOptions)).code;
const contentWoNewLines = cleanNewLines(builtContent);
expect(contentWoNewLines).not.toContain('debugName');
expect(contentWoNewLines).toContain(`testHttpResource = httpResource(() => "/api")`);
});
it('should not tree-shake away debug info if in dev mode', async () => {
env.write(
'test.ts',
`
import {Component} from '@angular/core';
import {httpResource, HttpResourceRef} from '@angular/common/http';
@Component({
template: ''
}) class MyComponent {
testHttpResource: HttpResourceRef<any>;
constructor() {
this.testHttpResource = httpResource(() => '/api');
}
}`,
);
env.driveMain();
const jsContents = env.getContents('test.js');
const builtContent = (await esbuild.transform(jsContents, minifiedDevBuildOptions)).code;
const contentWoNewLines = cleanNewLines(builtContent);
expect(contentWoNewLines).toContain(
'testHttpResource = httpResource(() => "/api", { ' +
'debugName: "testHttpResource" ' +
'})',
);
});
});
});
});
});