@@ -8,79 +8,246 @@ namespace Microsoft.Extensions.SourceGeneration.Configuration.Binder.Tests
88{
99 public partial class ConfigurationBinderTests : ConfigurationBinderTestsBase
1010 {
11+ // These are regression tests for https://github.com/dotnet/runtime/issues/90851
12+ // Source Generator Interceptors rely on identifying an accurate invocation
13+ // source location (line and character positions). These tests cover newline
14+ // and whitespace scenarios to ensure the interceptors get wired up correctly.
15+
1116 [ Fact ]
12- public void GeneratorHandlesInvocationsOnNewline ( )
17+ public void TestBindingInvocationsWithNewlines_GetMethodTypeArg ( )
1318 {
1419 IConfiguration configuration = TestHelpers . GetConfigurationFromJsonString ( @"{""Longitude"":1,""Latitude"":2}" ) ;
1520
16- GeolocationRecord record = configuration . Get <
17- GeolocationRecord
18- > ( ) ;
19- Verify ( ) ;
21+ // Newline between the configuration instance and the binding invocation (with the dot on the first line)
22+ GeolocationRecord record1 = ( GeolocationRecord ) configuration .
23+ Get ( typeof ( GeolocationRecord ) , _ => { } ) ;
24+
25+ AssertRecordIsBound ( record1 , 1 , 2 ) ;
2026
21- record = ( GeolocationRecord ) configuration
27+ // Newline between the configuration instance and the binding invocation (with the dot on the second line)
28+ GeolocationRecord record2 = ( GeolocationRecord ) configuration
2229 . Get ( typeof ( GeolocationRecord ) , _ => { } ) ;
23- Verify ( ) ;
2430
25- TestHelpers
26- . GetConfigurationFromJsonString ( @"{""Longitude"":3,""Latitude"":4}" )
27- . Bind ( record ) ;
28- Verify ( 3 , 4 ) ;
31+ AssertRecordIsBound ( record2 , 1 , 2 ) ;
2932
30- int lat = configuration
31- . GetValue < int > ( "Latitude" ) ;
32- Assert . Equal ( 2 , lat ) ;
33+ // Newlines between the instance, the invocation, and the arguments
34+ GeolocationRecord record3 = ( GeolocationRecord ) configuration
35+ . Get (
36+ typeof ( GeolocationRecord ) ,
37+ _ => { }
38+ ) ;
39+
40+ AssertRecordIsBound ( record3 , 1 , 2 ) ;
41+
42+ // Newlines before and after the instance (with the dot on the first line)
43+ GeolocationRecord record4 = ( GeolocationRecord )
44+ configuration .
45+ Get ( typeof ( GeolocationRecord ) , _ => { } ) ;
46+
47+ AssertRecordIsBound ( record4 , 1 , 2 ) ;
48+
49+ // Newlines before and after the instance (with the dot on the second line)
50+ GeolocationRecord record5 = ( GeolocationRecord )
51+ configuration
52+ . Get ( typeof ( GeolocationRecord ) , _ => { } ) ;
53+
54+ AssertRecordIsBound ( record5 , 1 , 2 ) ;
55+
56+ // Newlines in every place possible
57+ GeolocationRecord
58+ record6
59+ =
60+ (
61+ GeolocationRecord
62+ )
63+ configuration
64+ .
65+ Get
66+ (
67+ typeof
68+ (
69+ GeolocationRecord
70+ )
71+ ,
72+ _
73+ =>
74+ {
75+ }
76+ )
77+ ;
78+
79+ AssertRecordIsBound ( record6 , 1 , 2 ) ;
80+ }
3381
34- record = configuration . Get
82+ [ Fact ]
83+ public void TestBindingInvocationsWithNewlines_GetMethodGeneric ( )
84+ {
85+ IConfiguration configuration = TestHelpers . GetConfigurationFromJsonString ( @"{""Longitude"":1,""Latitude"":2}" ) ;
86+
87+ // Newline between the invocation method name and the generic type argument
88+ GeolocationRecord record1 = configuration . Get
3589 < GeolocationRecord > ( ) ;
36- Verify ( ) ;
3790
38- record = ( GeolocationRecord ) configuration
39- . Get (
40- typeof ( GeolocationRecord ) , _ =>
41- { } ) ;
42- Verify ( ) ;
91+ AssertRecordIsBound ( record1 , 1 , 2 ) ;
4392
93+ // Newlines on either side of the generic type argument
94+ GeolocationRecord record2 = configuration . Get <
95+ GeolocationRecord
96+ > ( ) ;
97+
98+ AssertRecordIsBound ( record2 , 1 , 2 ) ;
99+
100+ // Newlines in every place possible
101+ GeolocationRecord
102+ record3
103+ =
104+ configuration
105+ .
106+ Get
107+ <
108+ GeolocationRecord
109+ >
110+ ( )
111+ ;
112+
113+ AssertRecordIsBound ( record3 , 1 , 2 ) ;
114+ }
115+
116+ [ Fact ]
117+ public void TestBindingInvocationsWithNewlines_BindExtensionMethod ( )
118+ {
119+ // Newline between the configuration instance and the extension method invocation
120+ GeolocationRecord record1 = new GeolocationRecord ( ) ;
121+ TestHelpers . GetConfigurationFromJsonString ( @"{""Longitude"":1,""Latitude"":2}" )
122+ . Bind ( record1 ) ;
123+
124+ AssertRecordIsBound ( record1 , 1 , 2 ) ;
125+
126+ // Newlines between the method that returns the instance and the extension method invocation
127+ GeolocationRecord record2 = new GeolocationRecord ( ) ;
44128 TestHelpers
45- . GetConfigurationFromJsonString ( @"{""Longitude"":3,
46- ""Latitude"":4}
47- " )
129+ . GetConfigurationFromJsonString ( @"{""Longitude"":1,""Latitude"":2}" )
130+ . Bind ( record2 ) ;
131+
132+ AssertRecordIsBound ( record2 , 1 , 2 ) ;
133+
134+ // Newlines within the argument to the method returning the configuration and around the extension method argument
135+ GeolocationRecord record3 = new GeolocationRecord ( ) ;
136+ TestHelpers
137+ . GetConfigurationFromJsonString ( @"{""Longitude"":1,
138+ ""Latitude"":2}
139+ " )
48140 . Bind (
49- record
141+ record3
50142 ) ;
51- Verify ( 3 , 4 ) ;
52143
53- long latLong = configuration
54- . GetValue <
144+ AssertRecordIsBound ( record3 , 1 , 2 ) ;
145+
146+ // Newlines in every place possible
147+ GeolocationRecord record4 = new GeolocationRecord ( ) ;
148+ TestHelpers
149+ .
150+ GetConfigurationFromJsonString
151+ (
152+ @"{""Longitude"":1, ""Latitude"":2}"
153+ )
154+ .
155+ Bind
156+ (
157+ record4
158+ )
159+ ;
160+
161+ AssertRecordIsBound ( record4 , 1 , 2 ) ;
162+ }
163+
164+ [ Fact ]
165+ public void TestBindingInvocationsWithNewlines_BindStaticMethod ( )
166+ {
167+ IConfiguration configuration = TestHelpers . GetConfigurationFromJsonString ( @"{""Longitude"":1,""Latitude"":2}" ) ;
168+
169+ // Newline between the class and the static method invocation (with the dot on the first line)
170+ GeolocationRecord record1 = new GeolocationRecord ( ) ;
171+ ConfigurationBinder .
172+ Bind ( configuration , record1 ) ;
173+
174+ // Newline between the class and the static method invocation (with the dot on the second line)
175+ GeolocationRecord record2 = new GeolocationRecord ( ) ;
176+ ConfigurationBinder
177+ . Bind ( configuration , record2 ) ;
178+
179+ AssertRecordIsBound ( record2 , 1 , 2 ) ;
180+
181+ // Newline before the arguments
182+ GeolocationRecord record3 = new GeolocationRecord ( ) ;
183+ ConfigurationBinder . Bind (
184+ configuration , record3 ) ;
185+
186+ AssertRecordIsBound ( record3 , 1 , 2 ) ;
187+
188+ // Newlines in every place possible
189+ GeolocationRecord record4 = new GeolocationRecord ( ) ;
190+ ConfigurationBinder
191+ .
192+ Bind
193+ (
194+ configuration
195+ ,
196+ record4
197+ )
198+ ;
199+
200+ AssertRecordIsBound ( record4 , 1 , 2 ) ;
201+ }
202+
203+ [ Fact ]
204+ public void TestBindingInvocationsWithNewlines_GetValueMethod ( )
205+ {
206+ IConfiguration configuration = TestHelpers . GetConfigurationFromJsonString ( @"{""Longitude"":1,""Latitude"":2}" ) ;
207+
208+ // Newline between the configuration instance and the binding invocation (with the dot on the first line)
209+ int lat1 = configuration .
210+ GetValue < int > ( "Latitude" ) ;
211+
212+ Assert . Equal ( 2 , lat1 ) ;
213+
214+ // Newline between the configuration instance and the binding invocation (with the dot on the second line)
215+ int lat2 = configuration
216+ . GetValue < int > ( "Latitude" ) ;
217+
218+ Assert . Equal ( 2 , lat2 ) ;
219+
220+ // Newlines in every place possible
221+ long
222+ lat3
223+ =
224+ configuration
225+ .
226+ GetValue
227+ <
228+ int
229+ >
230+ (
231+ "Latitude"
232+ )
233+ ;
234+ Assert . Equal ( 2 , lat3 ) ;
235+
236+ // Newlines and pragmas wrapped around the generic type argument
237+ long lat4 = configuration . GetValue <
55238#if DEBUG
56239 int
57240#else
58241 long
59242#endif
60- >
61- ( "Latitude" )
62- ;
63- Assert . Equal ( 2 , lat ) ;
64-
65- record = ( GeolocationRecord ) configuration .
66- Get ( typeof ( GeolocationRecord ) , _ => { } ) ;
67- Verify ( ) ;
243+ > ( "Latitude" ) ;
68244
69- record = ( GeolocationRecord )
70- configuration .
71- Get ( typeof ( GeolocationRecord ) , _ => { } ) ;
72- Verify ( ) ;
73-
74- record = ( GeolocationRecord )
75- configuration
76- . Get ( typeof ( GeolocationRecord ) , _ => { } ) ;
77- Verify ( ) ;
245+ Assert . Equal ( 2 , lat4 ) ;
246+ }
78247
79- void Verify ( int longitude = 1 , int latitude = 2 )
80- {
81- Assert . Equal ( longitude , record . Longitude ) ;
82- Assert . Equal ( latitude , record . Latitude ) ;
83- }
248+ private static void AssertRecordIsBound ( GeolocationRecord record , int longitude , int latitude )
249+ {
250+ Assert . Equal ( ( longitude , latitude ) , ( record . Longitude , record . Latitude ) ) ;
84251 }
85252 }
86253}
0 commit comments