@@ -8,79 +8,246 @@ namespace Microsoft.Extensions.SourceGeneration.Configuration.Binder.Tests
8
8
{
9
9
public partial class ConfigurationBinderTests : ConfigurationBinderTestsBase
10
10
{
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
+
11
16
[ Fact ]
12
- public void GeneratorHandlesInvocationsOnNewline ( )
17
+ public void TestBindingInvocationsWithNewlines_GetMethodTypeArg ( )
13
18
{
14
19
IConfiguration configuration = TestHelpers . GetConfigurationFromJsonString ( @"{""Longitude"":1,""Latitude"":2}" ) ;
15
20
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 ) ;
20
26
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
22
29
. Get ( typeof ( GeolocationRecord ) , _ => { } ) ;
23
- Verify ( ) ;
24
30
25
- TestHelpers
26
- . GetConfigurationFromJsonString ( @"{""Longitude"":3,""Latitude"":4}" )
27
- . Bind ( record ) ;
28
- Verify ( 3 , 4 ) ;
31
+ AssertRecordIsBound ( record2 , 1 , 2 ) ;
29
32
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
+ }
33
81
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
35
89
< GeolocationRecord > ( ) ;
36
- Verify ( ) ;
37
90
38
- record = ( GeolocationRecord ) configuration
39
- . Get (
40
- typeof ( GeolocationRecord ) , _ =>
41
- { } ) ;
42
- Verify ( ) ;
91
+ AssertRecordIsBound ( record1 , 1 , 2 ) ;
43
92
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 ( ) ;
44
128
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
+ " )
48
140
. Bind (
49
- record
141
+ record3
50
142
) ;
51
- Verify ( 3 , 4 ) ;
52
143
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 <
55
238
#if DEBUG
56
239
int
57
240
#else
58
241
long
59
242
#endif
60
- >
61
- ( "Latitude" )
62
- ;
63
- Assert . Equal ( 2 , lat ) ;
64
-
65
- record = ( GeolocationRecord ) configuration .
66
- Get ( typeof ( GeolocationRecord ) , _ => { } ) ;
67
- Verify ( ) ;
243
+ > ( "Latitude" ) ;
68
244
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
+ }
78
247
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 ) ) ;
84
251
}
85
252
}
86
253
}
0 commit comments