1+ using System . Text . Json ;
2+ using Scarlet . System . Text . Json . DateTimeConverter . Tests . Model ;
3+
4+ namespace Scarlet . System . Text . Json . DateTimeConverter . Tests ;
5+
6+ public partial class ReflectionBasedTests
7+ {
8+ [ Fact ]
9+ public void ReflectionBased_DateTime_WithAttribute ( )
10+ {
11+ // Arrange
12+ var options = new JsonSerializerOptions
13+ {
14+ Converters = { new JsonDateTimeConverterAttribute ( "yyyy-MM-ddTHH:mm:ss" ) . CreateConverter ( typeof ( DateTime ) ) }
15+ } ;
16+ var originalDate = new DateTime ( 2023 , 10 , 1 , 12 , 0 , 0 , DateTimeKind . Utc ) ;
17+
18+ // Act
19+ var json = JsonSerializer . Serialize ( originalDate , options ) ;
20+ var deserializedDate = JsonSerializer . Deserialize < DateTime > ( json , options ) ;
21+
22+ // Assert
23+ Assert . Equal ( originalDate , deserializedDate ) ;
24+ Assert . Equal ( "\" 2023-10-01T12:00:00\" " , json ) ;
25+ }
26+
27+ [ Fact ]
28+ public void ReflectionBased_NullableDateTime_WithAttribute ( )
29+ {
30+ // Arrange
31+ var options = new JsonSerializerOptions
32+ {
33+ Converters = { new JsonDateTimeConverterAttribute ( "yyyy-MM-ddTHH:mm:ss" ) . CreateConverter ( typeof ( DateTime ? ) ) }
34+ } ;
35+ DateTime ? originalDate = new DateTime ( 2023 , 10 , 1 , 12 , 0 , 0 , DateTimeKind . Utc ) ;
36+
37+ // Act
38+ var json = JsonSerializer . Serialize ( originalDate , options ) ;
39+ var deserializedDate = JsonSerializer . Deserialize < DateTime ? > ( json , options ) ;
40+
41+ // Assert
42+ Assert . Equal ( originalDate , deserializedDate ) ;
43+ Assert . Equal ( "\" 2023-10-01T12:00:00\" " , json ) ;
44+ }
45+
46+ [ Fact ]
47+ public void ReflectionBased_DateTimeOffset_WithAttribute ( )
48+ {
49+ // Arrange
50+ var options = new JsonSerializerOptions
51+ {
52+ Converters = { new JsonDateTimeConverterAttribute ( "yyyy-MM-ddTHH:mm:ss.fffZ" ) . CreateConverter ( typeof ( DateTimeOffset ) ) }
53+ } ;
54+ var originalDate = new DateTimeOffset ( 2023 , 10 , 1 , 12 , 0 , 0 , TimeSpan . Zero ) ;
55+
56+ // Act
57+ var json = JsonSerializer . Serialize ( originalDate , options ) ;
58+ var deserializedDate = JsonSerializer . Deserialize < DateTimeOffset > ( json , options ) ;
59+
60+ // Assert
61+ Assert . Equal ( originalDate , deserializedDate ) ;
62+ Assert . Equal ( "\" 2023-10-01T12:00:00.000Z\" " , json ) ;
63+ }
64+
65+ [ Fact ]
66+ public void ReflectionBased_NullableDateTimeOffset_WithAttribute ( )
67+ {
68+ // Arrange
69+ var options = new JsonSerializerOptions
70+ {
71+ Converters = { new JsonDateTimeConverterAttribute ( "yyyy-MM-ddTHH:mm:ss.fffZ" ) . CreateConverter ( typeof ( DateTimeOffset ? ) ) }
72+ } ;
73+ DateTimeOffset ? originalDate = new DateTimeOffset ( 2023 , 10 , 1 , 12 , 0 , 0 , TimeSpan . Zero ) ;
74+
75+ // Act
76+ var json = JsonSerializer . Serialize ( originalDate , options ) ;
77+ var deserializedDate = JsonSerializer . Deserialize < DateTimeOffset ? > ( json , options ) ;
78+
79+ // Assert
80+ Assert . Equal ( originalDate , deserializedDate ) ;
81+ Assert . Equal ( "\" 2023-10-01T12:00:00.000Z\" " , json ) ;
82+ }
83+
84+ [ Fact ]
85+ public void ReflectionBased_DateOnly_WithAttribute ( )
86+ {
87+ // Arrange
88+ var options = new JsonSerializerOptions
89+ {
90+ Converters = { new JsonDateTimeConverterAttribute ( "MM/dd/yyyy" ) . CreateConverter ( typeof ( DateOnly ) ) }
91+ } ;
92+ var originalDate = new DateOnly ( 2023 , 10 , 1 ) ;
93+
94+ // Act
95+ var json = JsonSerializer . Serialize ( originalDate , options ) ;
96+ var deserializedDate = JsonSerializer . Deserialize < DateOnly > ( json , options ) ;
97+
98+ // Assert
99+ Assert . Equal ( originalDate , deserializedDate ) ;
100+ Assert . Equal ( "\" 10/01/2023\" " , json ) ;
101+ }
102+
103+ [ Fact ]
104+ public void ReflectionBased_NullableDateOnly_WithAttribute ( )
105+ {
106+ // Arrange
107+ var options = new JsonSerializerOptions
108+ {
109+ Converters = { new JsonDateTimeConverterAttribute ( "MM/dd/yyyy" ) . CreateConverter ( typeof ( DateOnly ? ) ) }
110+ } ;
111+ DateOnly ? originalDate = new DateOnly ( 2023 , 10 , 1 ) ;
112+
113+ // Act
114+ var json = JsonSerializer . Serialize ( originalDate , options ) ;
115+ var deserializedDate = JsonSerializer . Deserialize < DateOnly ? > ( json , options ) ;
116+
117+ // Assert
118+ Assert . Equal ( originalDate , deserializedDate ) ;
119+ Assert . Equal ( "\" 10/01/2023\" " , json ) ;
120+ }
121+
122+ [ Fact ]
123+ public void ReflectionBased_TimeOnly_WithAttribute ( )
124+ {
125+ // Arrange
126+ var options = new JsonSerializerOptions
127+ {
128+ Converters = { new JsonDateTimeConverterAttribute ( "HH.mm.ss" ) . CreateConverter ( typeof ( TimeOnly ) ) }
129+ } ;
130+ var originalTime = new TimeOnly ( 14 , 30 , 45 ) ;
131+
132+ // Act
133+ var json = JsonSerializer . Serialize ( originalTime , options ) ;
134+ var deserializedTime = JsonSerializer . Deserialize < TimeOnly > ( json , options ) ;
135+
136+ // Assert
137+ Assert . Equal ( originalTime , deserializedTime ) ;
138+ Assert . Equal ( "\" 14.30.45\" " , json ) ;
139+ }
140+
141+ [ Fact ]
142+ public void ReflectionBased_NullableTimeOnly_WithAttribute ( )
143+ {
144+ // Arrange
145+ var options = new JsonSerializerOptions
146+ {
147+ Converters = { new JsonDateTimeConverterAttribute ( "HH.mm.ss" ) . CreateConverter ( typeof ( TimeOnly ? ) ) }
148+ } ;
149+ TimeOnly ? originalTime = new TimeOnly ( 14 , 30 , 45 ) ;
150+
151+ // Act
152+ var json = JsonSerializer . Serialize ( originalTime , options ) ;
153+ var deserializedTime = JsonSerializer . Deserialize < TimeOnly ? > ( json , options ) ;
154+
155+ // Assert
156+ Assert . Equal ( originalTime , deserializedTime ) ;
157+ Assert . Equal ( "\" 14.30.45\" " , json ) ;
158+ }
159+
160+ [ Fact ]
161+ public void ReflectionBased_CompleteModel_WithAttribute ( )
162+ {
163+ // Arrange
164+ var options = new JsonSerializerOptions
165+ {
166+ WriteIndented = true
167+ } ;
168+ var originalModel = new ReflectionBasedModel
169+ {
170+ DateTimeProperty = new DateTime ( 2023 , 10 , 1 , 12 , 0 , 0 , DateTimeKind . Utc ) ,
171+ NullableDateTimeProperty = new DateTime ( 2023 , 10 , 1 , 12 , 0 , 0 , DateTimeKind . Utc ) ,
172+ DateTimeOffsetProperty = new DateTimeOffset ( 2023 , 10 , 1 , 12 , 0 , 0 , TimeSpan . Zero ) ,
173+ NullableDateTimeOffsetProperty = new DateTimeOffset ( 2023 , 10 , 1 , 12 , 0 , 0 , TimeSpan . Zero ) ,
174+ DateOnlyProperty = new DateOnly ( 2023 , 10 , 1 ) ,
175+ NullableDateOnlyProperty = new DateOnly ( 2023 , 10 , 1 ) ,
176+ TimeOnlyProperty = new TimeOnly ( 14 , 30 , 45 ) ,
177+ NullableTimeOnlyProperty = new TimeOnly ( 14 , 30 , 45 )
178+ } ;
179+ const string expectedJson = """
180+ {
181+ "DateTimeProperty": "2023-10-01T12:00:00",
182+ "NullableDateTimeProperty": "2023-10-01T12:00:00",
183+ "DateTimeOffsetProperty": "2023-10-01T12:00:00.000Z",
184+ "NullableDateTimeOffsetProperty": "2023-10-01T12:00:00.000Z",
185+ "DateOnlyProperty": "10/01/2023",
186+ "NullableDateOnlyProperty": "10/01/2023",
187+ "TimeOnlyProperty": "14.30.45",
188+ "NullableTimeOnlyProperty": "14.30.45"
189+ }
190+ """ ;
191+
192+ // Act
193+ var json = JsonSerializer . Serialize ( originalModel , options ) ;
194+ var deserializedModel = JsonSerializer . Deserialize < ReflectionBasedModel > ( json , options ) ;
195+
196+ // Assert
197+ Assert . NotNull ( deserializedModel ) ;
198+ Assert . Equal ( originalModel . DateTimeProperty , deserializedModel . DateTimeProperty ) ;
199+ Assert . Equal ( originalModel . NullableDateTimeProperty , deserializedModel . NullableDateTimeProperty ) ;
200+ Assert . Equal ( originalModel . DateTimeOffsetProperty , deserializedModel . DateTimeOffsetProperty ) ;
201+ Assert . Equal ( originalModel . NullableDateTimeOffsetProperty , deserializedModel . NullableDateTimeOffsetProperty ) ;
202+ Assert . Equal ( originalModel . DateOnlyProperty , deserializedModel . DateOnlyProperty ) ;
203+ Assert . Equal ( originalModel . NullableDateOnlyProperty , deserializedModel . NullableDateOnlyProperty ) ;
204+ Assert . Equal ( originalModel . TimeOnlyProperty , deserializedModel . TimeOnlyProperty ) ;
205+ Assert . Equal ( originalModel . NullableTimeOnlyProperty , deserializedModel . NullableTimeOnlyProperty ) ;
206+ Assert . Equal ( expectedJson , json ) ;
207+ }
208+
209+ [ Fact ]
210+ public void ReflectionBased_CompleteModel_WithAttribute_WithNullValues ( )
211+ {
212+ // Arrange
213+ var options = new JsonSerializerOptions
214+ {
215+ WriteIndented = true
216+ } ;
217+ var originalModel = new ReflectionBasedModel
218+ {
219+ DateTimeProperty = new DateTime ( 2023 , 10 , 1 , 12 , 0 , 0 , DateTimeKind . Utc ) ,
220+ NullableDateTimeProperty = null ,
221+ DateTimeOffsetProperty = new DateTimeOffset ( 2023 , 10 , 1 , 12 , 0 , 0 , TimeSpan . Zero ) ,
222+ NullableDateTimeOffsetProperty = null ,
223+ DateOnlyProperty = new DateOnly ( 2023 , 10 , 1 ) ,
224+ NullableDateOnlyProperty = null ,
225+ TimeOnlyProperty = new TimeOnly ( 14 , 30 , 45 ) ,
226+ NullableTimeOnlyProperty = null
227+ } ;
228+ const string expectedJson = """
229+ {
230+ "DateTimeProperty": "2023-10-01T12:00:00",
231+ "NullableDateTimeProperty": null,
232+ "DateTimeOffsetProperty": "2023-10-01T12:00:00.000Z",
233+ "NullableDateTimeOffsetProperty": null,
234+ "DateOnlyProperty": "10/01/2023",
235+ "NullableDateOnlyProperty": null,
236+ "TimeOnlyProperty": "14.30.45",
237+ "NullableTimeOnlyProperty": null
238+ }
239+ """ ;
240+
241+ // Act
242+ var json = JsonSerializer . Serialize ( originalModel , options ) ;
243+ var deserializedModel = JsonSerializer . Deserialize < ReflectionBasedModel > ( json , options ) ;
244+
245+ // Assert
246+ Assert . NotNull ( deserializedModel ) ;
247+ Assert . Equal ( originalModel . DateTimeProperty , deserializedModel . DateTimeProperty ) ;
248+ Assert . Null ( deserializedModel . NullableDateTimeProperty ) ;
249+ Assert . Equal ( originalModel . DateTimeOffsetProperty , deserializedModel . DateTimeOffsetProperty ) ;
250+ Assert . Null ( deserializedModel . NullableDateTimeOffsetProperty ) ;
251+ Assert . Equal ( originalModel . DateOnlyProperty , deserializedModel . DateOnlyProperty ) ;
252+ Assert . Null ( deserializedModel . NullableDateOnlyProperty ) ;
253+ Assert . Equal ( originalModel . TimeOnlyProperty , deserializedModel . TimeOnlyProperty ) ;
254+ Assert . Null ( deserializedModel . NullableTimeOnlyProperty ) ;
255+ Assert . Equal ( expectedJson , json ) ;
256+ }
257+ }
0 commit comments