@@ -17,7 +17,7 @@ import {factory as interpolatedSignalFactory} from '../../../checks/interpolated
1717import { ExtendedTemplateCheckerImpl } from '../../../src/extended_template_checker' ;
1818
1919runInEachFileSystem ( ( ) => {
20- describe ( 'Interpolated Signal ' , ( ) => {
20+ describe ( 'Interpolated Signal' , ( ) => {
2121 it ( 'binds the error code to its extended template diagnostic name' , ( ) => {
2222 expect ( interpolatedSignalFactory . code ) . toBe ( ErrorCode . INTERPOLATED_SIGNAL_NOT_INVOKED ) ;
2323 expect ( interpolatedSignalFactory . name )
@@ -51,7 +51,7 @@ runInEachFileSystem(() => {
5151 } ) ;
5252 } ) ;
5353
54- it ( 'should produce a warning when a signal isn\'t invoked' , ( ) => {
54+ it ( 'should produce a warning when a signal is not invoked' , ( ) => {
5555 const fileName = absoluteFrom ( '/main.ts' ) ;
5656 const { program, templateTypeChecker} = setup ( [
5757 {
@@ -81,7 +81,7 @@ runInEachFileSystem(() => {
8181 expect ( getSourceCodeForDiagnostic ( diags [ 1 ] ) ) . toBe ( `mySignal2` ) ;
8282 } ) ;
8383
84- it ( 'should produce a warning when a readonly signal isn\'t invoked' , ( ) => {
84+ it ( 'should produce a warning when a readonly signal is not invoked' , ( ) => {
8585 const fileName = absoluteFrom ( '/main.ts' ) ;
8686 const { program, templateTypeChecker} = setup ( [
8787 {
@@ -109,7 +109,7 @@ runInEachFileSystem(() => {
109109 expect ( getSourceCodeForDiagnostic ( diags [ 0 ] ) ) . toBe ( 'count' ) ;
110110 } ) ;
111111
112- it ( 'should produce a warning when a computed signal isn\'t invoked' , ( ) => {
112+ it ( 'should produce a warning when a computed signal is not invoked' , ( ) => {
113113 const fileName = absoluteFrom ( '/main.ts' ) ;
114114 const { program, templateTypeChecker} = setup ( [
115115 {
@@ -138,7 +138,7 @@ runInEachFileSystem(() => {
138138 expect ( getSourceCodeForDiagnostic ( diags [ 0 ] ) ) . toBe ( `mySignal2` ) ;
139139 } ) ;
140140
141- it ( 'should produce a warning when an input signal isn\'t invoked' , ( ) => {
141+ it ( 'should produce a warning when an input signal is not invoked' , ( ) => {
142142 const fileName = absoluteFrom ( '/main.ts' ) ;
143143 const { program, templateTypeChecker} = setup ( [
144144 {
@@ -166,7 +166,7 @@ runInEachFileSystem(() => {
166166 expect ( getSourceCodeForDiagnostic ( diags [ 0 ] ) ) . toBe ( `myInput` ) ;
167167 } ) ;
168168
169- it ( 'should produce a warning when a required input signal isn\'t invoked' , ( ) => {
169+ it ( 'should produce a warning when a required input signal is not invoked' , ( ) => {
170170 const fileName = absoluteFrom ( '/main.ts' ) ;
171171 const { program, templateTypeChecker} = setup ( [
172172 {
@@ -194,7 +194,7 @@ runInEachFileSystem(() => {
194194 expect ( getSourceCodeForDiagnostic ( diags [ 0 ] ) ) . toBe ( `myRequiredInput` ) ;
195195 } ) ;
196196
197- it ( 'should produce a warning when a model signal isn\'t invoked' , ( ) => {
197+ it ( 'should produce a warning when a model signal is not invoked' , ( ) => {
198198 const fileName = absoluteFrom ( '/main.ts' ) ;
199199 const { program, templateTypeChecker} = setup ( [
200200 {
@@ -213,7 +213,7 @@ runInEachFileSystem(() => {
213213 const sf = getSourceFileOrError ( program , fileName ) ;
214214 const component = getClass ( sf , 'TestCmp' ) ;
215215 const extendedTemplateChecker = new ExtendedTemplateCheckerImpl (
216- templateTypeChecker , program . getTypeChecker ( ) , [ interpolatedSignalFactory ] , { } /* options */
216+ templateTypeChecker , program . getTypeChecker ( ) , [ interpolatedSignalFactory ] , { } /* options */
217217 ) ;
218218 const diags = extendedTemplateChecker . getDiagnosticsForComponent ( component ) ;
219219 expect ( diags . length ) . toBe ( 1 ) ;
@@ -222,7 +222,7 @@ runInEachFileSystem(() => {
222222 expect ( getSourceCodeForDiagnostic ( diags [ 0 ] ) ) . toBe ( `myModel` ) ;
223223 } ) ;
224224
225- it ( 'should produce a warning when a required model signal isn\'t invoked' , ( ) => {
225+ it ( 'should produce a warning when a required model signal is not invoked' , ( ) => {
226226 const fileName = absoluteFrom ( '/main.ts' ) ;
227227 const { program, templateTypeChecker} = setup ( [
228228 {
@@ -241,7 +241,7 @@ runInEachFileSystem(() => {
241241 const sf = getSourceFileOrError ( program , fileName ) ;
242242 const component = getClass ( sf , 'TestCmp' ) ;
243243 const extendedTemplateChecker = new ExtendedTemplateCheckerImpl (
244- templateTypeChecker , program . getTypeChecker ( ) , [ interpolatedSignalFactory ] , { } /* options */
244+ templateTypeChecker , program . getTypeChecker ( ) , [ interpolatedSignalFactory ] , { } /* options */
245245 ) ;
246246 const diags = extendedTemplateChecker . getDiagnosticsForComponent ( component ) ;
247247 expect ( diags . length ) . toBe ( 1 ) ;
@@ -250,6 +250,40 @@ runInEachFileSystem(() => {
250250 expect ( getSourceCodeForDiagnostic ( diags [ 0 ] ) ) . toBe ( `myRequiredModel` ) ;
251251 } ) ;
252252
253+ it ( 'should produce a warning when a signal in a nested property read is not invoked' , ( ) => {
254+ const fileName = absoluteFrom ( '/main.ts' ) ;
255+ const { program, templateTypeChecker} = setup ( [
256+ {
257+ fileName,
258+ templates : {
259+ 'TestCmp' : `<div>{{ obj.nested.prop.signal }}</div>` ,
260+ } ,
261+ source : `
262+ import {signal, Signal} from '@angular/core';
263+
264+ export class TestCmp {
265+ obj = {
266+ nested: {
267+ prop: {
268+ signal: signal<number>(0)
269+ }
270+ }
271+ }
272+ }` ,
273+ } ,
274+ ] ) ;
275+ const sf = getSourceFileOrError ( program , fileName ) ;
276+ const component = getClass ( sf , 'TestCmp' ) ;
277+ const extendedTemplateChecker = new ExtendedTemplateCheckerImpl (
278+ templateTypeChecker , program . getTypeChecker ( ) , [ interpolatedSignalFactory ] , { } /* options */
279+ ) ;
280+ const diags = extendedTemplateChecker . getDiagnosticsForComponent ( component ) ;
281+ expect ( diags . length ) . toBe ( 1 ) ;
282+ expect ( diags [ 0 ] . category ) . toBe ( ts . DiagnosticCategory . Warning ) ;
283+ expect ( diags [ 0 ] . code ) . toBe ( ngErrorCode ( ErrorCode . INTERPOLATED_SIGNAL_NOT_INVOKED ) ) ;
284+ expect ( getSourceCodeForDiagnostic ( diags [ 0 ] ) ) . toBe ( `signal` ) ;
285+ } ) ;
286+
253287 it ( 'should not produce a warning when model signals are invoked' , ( ) => {
254288 const fileName = absoluteFrom ( '/main.ts' ) ;
255289 const { program, templateTypeChecker} = setup ( [
@@ -270,7 +304,7 @@ runInEachFileSystem(() => {
270304 const sf = getSourceFileOrError ( program , fileName ) ;
271305 const component = getClass ( sf , 'TestCmp' ) ;
272306 const extendedTemplateChecker = new ExtendedTemplateCheckerImpl (
273- templateTypeChecker , program . getTypeChecker ( ) , [ interpolatedSignalFactory ] , { } /* options */
307+ templateTypeChecker , program . getTypeChecker ( ) , [ interpolatedSignalFactory ] , { } /* options */
274308 ) ;
275309 const diags = extendedTemplateChecker . getDiagnosticsForComponent ( component ) ;
276310 expect ( diags . length ) . toBe ( 0 ) ;
@@ -328,7 +362,7 @@ runInEachFileSystem(() => {
328362 expect ( diags . length ) . toBe ( 0 ) ;
329363 } ) ;
330364
331- it ( 'should produce a warning when signal isn\'t invoked on interpolated binding' , ( ) => {
365+ it ( 'should produce a warning when signal is not invoked on interpolated binding' , ( ) => {
332366 const fileName = absoluteFrom ( '/main.ts' ) ;
333367 const { program, templateTypeChecker} = setup ( [
334368 {
@@ -436,7 +470,7 @@ runInEachFileSystem(() => {
436470 expect ( diags . length ) . toBe ( 0 ) ;
437471 } ) ;
438472
439- it ( 'should produce a warning when nested signal isn\'t invoked on interpolated binding' , ( ) => {
473+ it ( 'should produce a warning when nested signal is not invoked on interpolated binding' , ( ) => {
440474 const fileName = absoluteFrom ( '/main.ts' ) ;
441475 const { program, templateTypeChecker} = setup ( [
442476 {
0 commit comments