@@ -2109,6 +2109,204 @@ runInEachFileSystem(() => {
21092109 } ) ;
21102110 } ) ;
21112111
2112+ describe ( 'afterRenderEffect' , ( ) => {
2113+ it ( 'should not insert debug info into afterRenderEffect function if not imported from angular core' , ( ) => {
2114+ env . write (
2115+ 'test.ts' ,
2116+ `
2117+ declare function afterRenderEffect(fn: () => any): any;
2118+ import {Component} from '@angular/core';
2119+
2120+ @Component({
2121+ template: ''
2122+ }) class MyComponent {
2123+ testEffect = afterRenderEffect(() => {});
2124+ }
2125+ ` ,
2126+ ) ;
2127+ env . driveMain ( ) ;
2128+ const jsContents = env . getContents ( 'test.js' ) ;
2129+ expect ( jsContents ) . not . toContain ( 'debugName' ) ;
2130+ } ) ;
2131+
2132+ it ( 'should insert debug info into afterRenderEffect function if imported from angular core' , ( ) => {
2133+ env . write (
2134+ 'test.ts' ,
2135+ `
2136+ import {signal, afterRenderEffect, Component} from '@angular/core';
2137+
2138+ @Component({
2139+ template: ''
2140+ }) class MyComponent {
2141+ testSignal = signal(123);
2142+ testEffect = afterRenderEffect(() => this.testSignal());
2143+ }
2144+ ` ,
2145+ ) ;
2146+ env . driveMain ( ) ;
2147+ const jsContents = env . getContents ( 'test.js' ) ;
2148+ expect ( cleanNewLines ( jsContents ) ) . toContain (
2149+ `afterRenderEffect(() => this.testSignal(), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "testEffect" }] : /* istanbul ignore next */ []))` ,
2150+ ) ;
2151+ } ) ;
2152+
2153+ it ( 'should insert debug info into afterRenderEffect function with a phase spec' , ( ) => {
2154+ env . write (
2155+ 'test.ts' ,
2156+ `
2157+ import {signal, afterRenderEffect, Component} from '@angular/core';
2158+
2159+ @Component({
2160+ template: ''
2161+ }) class MyComponent {
2162+ testSignal = signal(123);
2163+ testEffect = afterRenderEffect({read: () => this.testSignal()});
2164+ }
2165+ ` ,
2166+ ) ;
2167+ env . driveMain ( ) ;
2168+ const jsContents = env . getContents ( 'test.js' ) ;
2169+ expect ( cleanNewLines ( jsContents ) ) . toContain (
2170+ `afterRenderEffect({ read: () => this.testSignal() }, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "testEffect" }] : /* istanbul ignore next */ []))` ,
2171+ ) ;
2172+ } ) ;
2173+
2174+ it ( 'should insert debug info into afterRenderEffect function in a property assignment' , ( ) => {
2175+ env . write (
2176+ 'test.ts' ,
2177+ `
2178+ import {signal, afterRenderEffect, AfterRenderRef, Component} from '@angular/core';
2179+
2180+ @Component({
2181+ template: ''
2182+ }) class MyComponent {
2183+ testSignal = signal(123);
2184+ testEffect: AfterRenderRef;
2185+ constructor() {
2186+ this.testEffect = afterRenderEffect(() => this.testSignal());
2187+ }
2188+ }
2189+ ` ,
2190+ ) ;
2191+ env . driveMain ( ) ;
2192+ const jsContents = env . getContents ( 'test.js' ) ;
2193+ expect ( cleanNewLines ( jsContents ) ) . toContain (
2194+ `afterRenderEffect(() => this.testSignal(), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "testEffect" }] : /* istanbul ignore next */ []))` ,
2195+ ) ;
2196+ } ) ;
2197+
2198+ it ( 'should not override an explicit debugName' , ( ) => {
2199+ env . write (
2200+ 'test.ts' ,
2201+ `
2202+ import {afterRenderEffect, Component} from '@angular/core';
2203+
2204+ @Component({
2205+ template: ''
2206+ }) class MyComponent {
2207+ testEffect = afterRenderEffect(() => {}, {debugName: 'customName'});
2208+ }
2209+ ` ,
2210+ ) ;
2211+ env . driveMain ( ) ;
2212+ const jsContents = env . getContents ( 'test.js' ) ;
2213+ expect ( jsContents ) . toContain ( `debugName: 'customName'` ) ;
2214+ expect ( jsContents ) . not . toContain ( 'debugName: "testEffect"' ) ;
2215+ } ) ;
2216+
2217+ it ( 'should tree-shake away debug info if in prod mode' , async ( ) => {
2218+ env . write (
2219+ 'test.ts' ,
2220+ `
2221+ import {signal, afterRenderEffect, Component} from '@angular/core';
2222+ @Component({
2223+ template: ''
2224+ }) class MyComponent {
2225+ testSignal = signal(123);
2226+ testEffect = afterRenderEffect(() => this.testSignal());
2227+ }
2228+ ` ,
2229+ ) ;
2230+ env . driveMain ( ) ;
2231+ const jsContents = env . getContents ( 'test.js' ) ;
2232+ const builtContent = ( await esbuild . transform ( jsContents , minifiedProdBuildOptions ) ) . code ;
2233+ expect ( builtContent ) . not . toContain ( 'debugName' ) ;
2234+ expect ( cleanNewLines ( builtContent ) ) . toContain (
2235+ 'afterRenderEffect( () => this.testSignal() )' ,
2236+ ) ;
2237+ } ) ;
2238+
2239+ it ( 'should not tree-shake away debug info if in dev mode' , async ( ) => {
2240+ env . write (
2241+ 'test.ts' ,
2242+ `
2243+ import {signal, afterRenderEffect, Component} from '@angular/core';
2244+
2245+ @Component({
2246+ template: ''
2247+ }) class MyComponent {
2248+ testSignal = signal(123);
2249+ testEffect = afterRenderEffect(() => this.testSignal());
2250+ }
2251+ ` ,
2252+ ) ;
2253+ env . driveMain ( ) ;
2254+
2255+ const jsContents = env . getContents ( 'test.js' ) ;
2256+ const builtContent = ( await esbuild . transform ( jsContents , minifiedDevBuildOptions ) ) . code ;
2257+ expect ( cleanNewLines ( builtContent ) ) . toContain (
2258+ `afterRenderEffect( () => this.testSignal(), { debugName: "testEffect" } )` ,
2259+ ) ;
2260+ } ) ;
2261+
2262+ it ( 'should tree-shake away debug info if in prod mode with existing options' , async ( ) => {
2263+ env . write (
2264+ 'test.ts' ,
2265+ `
2266+ import {signal, afterRenderEffect, Component} from '@angular/core';
2267+
2268+ @Component({
2269+ template: ''
2270+ }) class MyComponent {
2271+ testSignal = signal(123);
2272+ testEffect = afterRenderEffect(() => this.testSignal(), { manualCleanup: true });
2273+ }
2274+ ` ,
2275+ ) ;
2276+ env . driveMain ( ) ;
2277+
2278+ const jsContents = env . getContents ( 'test.js' ) ;
2279+ const builtContent = ( await esbuild . transform ( jsContents , minifiedProdBuildOptions ) ) . code ;
2280+ expect ( builtContent ) . not . toContain ( 'debugName' ) ;
2281+ expect ( cleanNewLines ( builtContent ) ) . toContain (
2282+ 'afterRenderEffect(() => this.testSignal(), { manualCleanup: !0 })' ,
2283+ ) ;
2284+ } ) ;
2285+
2286+ it ( 'should not tree-shake away debug info if in dev mode with existing options' , async ( ) => {
2287+ env . write (
2288+ 'test.ts' ,
2289+ `
2290+ import {signal, afterRenderEffect, Component} from '@angular/core';
2291+
2292+ @Component({
2293+ template: ''
2294+ }) class MyComponent {
2295+ testSignal = signal(123);
2296+ testEffect = afterRenderEffect(() => this.testSignal(), { manualCleanup: true });
2297+ }
2298+ ` ,
2299+ ) ;
2300+ env . driveMain ( ) ;
2301+
2302+ const jsContents = env . getContents ( 'test.js' ) ;
2303+ const builtContent = ( await esbuild . transform ( jsContents , minifiedDevBuildOptions ) ) . code ;
2304+ expect ( cleanNewLines ( builtContent ) ) . toContain (
2305+ `afterRenderEffect(() => this.testSignal(), { debugName: "testEffect", manualCleanup: !0 })` ,
2306+ ) ;
2307+ } ) ;
2308+ } ) ;
2309+
21122310 describe ( 'linkedSignal' , ( ) => {
21132311 it ( 'should not insert debug info into linkedSignal function if not imported from angular core' , ( ) => {
21142312 env . write (
0 commit comments