@@ -43,17 +43,21 @@ public void Attribute_should_set_correct_units()
4343 Microseconds = timeOnly ,
4444 Ticks = timeOnly ,
4545 Nanoseconds = timeOnly ,
46+ Document = timeOnly
4647 } ;
4748
4849 var json = testObj . ToJson ( ) ;
4950
50- var expected = "{ \" Hours\" : 13, "
51- + "\" Minutes\" : 804, "
52- + "\" Seconds\" : 48293, "
53- + "\" Milliseconds\" : 48293000, "
54- + "\" Microseconds\" : 48293000000, "
55- + "\" Ticks\" : 482930000000, "
56- + "\" Nanoseconds\" : 48293000000000 }" ;
51+ var baseString = """
52+ { "Hours" : 13, "Minutes" : 804, "Seconds" : 48293, "Milliseconds" : 48293000, "Microseconds" : 48293000000, "Ticks" : 482930000000, "Nanoseconds" : 48293000000000
53+ """ ;
54+
55+ var documentString = """
56+ { "Hour" : 13, "Minute" : 24, "Second" : 53, "Millisecond" : 0, "Microsecond" : 0, "Nanosecond" : 0, "Ticks" : 482930000000 }
57+ """ ;
58+
59+
60+ var expected = baseString + """, "Document" : """ + documentString + " }" ;
5761 Assert . Equal ( expected , json ) ;
5862 }
5963
@@ -69,7 +73,7 @@ public void Constructor_with_no_arguments_should_return_expected_result()
6973 [ Theory ]
7074 [ ParameterAttributeData ]
7175 public void Constructor_with_representation_should_return_expected_result (
72- [ Values ( BsonType . String , BsonType . Int64 , BsonType . Int32 , BsonType . Double ) ]
76+ [ Values ( BsonType . String , BsonType . Int64 , BsonType . Int32 , BsonType . Double , BsonType . Document ) ]
7377 BsonType representation ,
7478 [ Values ( TimeOnlyUnits . Ticks , TimeOnlyUnits . Hours , TimeOnlyUnits . Minutes , TimeOnlyUnits . Seconds ,
7579 TimeOnlyUnits . Milliseconds , TimeOnlyUnits . Microseconds , TimeOnlyUnits . Nanoseconds ) ]
@@ -81,6 +85,60 @@ public void Constructor_with_representation_should_return_expected_result(
8185 subject . Units . Should ( ) . Be ( units ) ;
8286 }
8387
88+ [ Theory ]
89+ [ InlineData ( """{ "x" : { "Hour" : { "$numberInt" : "8" }, "Minute" : { "$numberInt" : "32" }, "Second" : { "$numberInt" : "5" }, "Millisecond" : { "$numberInt" : "594" }, "Microsecond" : { "$numberInt" : "658" }, "Nanosecond" : { "$numberInt" : "300" }, "Ticks" : { "$numberLong" : "307255946583" } } }""" , "08:32:05.5946583" ) ]
90+ [ InlineData ( """{ "x" : { "Hour" : { "$numberInt" : "0" }, "Minute" : { "$numberInt" : "0" }, "Second" : { "$numberInt" : "0" }, "Millisecond" : { "$numberInt" : "0" }, "Microsecond" : { "$numberInt" : "0" }, "Nanosecond" : { "$numberInt" : "0" }, "Ticks" : { "$numberLong" : "0" } } }""" , "00:00:00.0000000" ) ]
91+ [ InlineData ( """{ "x" : { "Hour" : { "$numberInt" : "23" }, "Minute" : { "$numberInt" : "59" }, "Second" : { "$numberInt" : "59" }, "Millisecond" : { "$numberInt" : "999" }, "Microsecond" : { "$numberInt" : "999" }, "Nanosecond" : { "$numberInt" : "900" }, "Ticks" : { "$numberLong" : "863999999999" } } }""" , "23:59:59.9999999" ) ]
92+ public void Deserialize_with_document_should_have_expected_result ( string json , string expectedResult )
93+ {
94+ var subject = new TimeOnlySerializer ( ) ;
95+ TestDeserialize ( subject , json , expectedResult ) ;
96+ }
97+
98+ [ Theory ]
99+ [ InlineData ( """{ "x" : { "Hour" : { "$numberInt" : "8" }, "Minute" : { "$numberInt" : "32" }, "Second" : { "$numberInt" : "5" }, "Millisecond" : { "$numberInt" : "594" }, "Microsecond" : { "$numberInt" : "658" }, "Ticks" : { "$numberLong" : "307255946583" } } }""" , "08:32:05.5946583" ) ]
100+ [ InlineData ( """{ "x" : { "Hour" : { "$numberInt" : "8" }, "Minute" : { "$numberInt" : "32" }, "Second" : { "$numberInt" : "5" }, "Millisecond" : { "$numberInt" : "594" }, "Nanosecond" : { "$numberInt" : "300" }, "Ticks" : { "$numberLong" : "307255946583" } } }""" , "08:32:05.5946583" ) ]
101+ [ InlineData ( """{ "x" : { "Hour" : { "$numberInt" : "8" }, "Minute" : { "$numberInt" : "32" }, "Second" : { "$numberInt" : "5" }, "Millisecond" : { "$numberInt" : "594" }, "Ticks" : { "$numberLong" : "307255946583" } } }""" , "08:32:05.5946583" ) ]
102+ public void Deserialize_with_document_should_work_with_missing_microsecond_or_nanosecond ( string json , string expectedResult )
103+ {
104+ var subject = new TimeOnlySerializer ( ) ;
105+ TestDeserialize ( subject , json , expectedResult ) ;
106+ }
107+
108+ [ Theory ]
109+ [ InlineData ( """{ "x" : { "Hour" : { "$numberInt" : "7" }, "Minute" : { "$numberInt" : "32" }, "Second" : { "$numberInt" : "5" }, "Millisecond" : { "$numberInt" : "594" }, "Microsecond" : { "$numberInt" : "658" }, "Nanosecond" : { "$numberInt" : "300" }, "Ticks" : { "$numberLong" : "307255946583" } } }""" ) ]
110+ [ InlineData ( """{ "x" : { "Hour" : { "$numberInt" : "8" }, "Minute" : { "$numberInt" : "33" }, "Second" : { "$numberInt" : "5" }, "Millisecond" : { "$numberInt" : "594" }, "Microsecond" : { "$numberInt" : "658" }, "Nanosecond" : { "$numberInt" : "300" }, "Ticks" : { "$numberLong" : "307255946583" } } }""" ) ]
111+ [ InlineData ( """{ "x" : { "Hour" : { "$numberInt" : "8" }, "Minute" : { "$numberInt" : "32" }, "Second" : { "$numberInt" : "6" }, "Millisecond" : { "$numberInt" : "594" }, "Microsecond" : { "$numberInt" : "658" }, "Nanosecond" : { "$numberInt" : "300" }, "Ticks" : { "$numberLong" : "307255946583" } } }""" ) ]
112+ public void Deserialize_with_document_should_throw_when_component_is_not_correct ( string json )
113+ {
114+ var subject = new TimeOnlySerializer ( ) ;
115+
116+ using var reader = new JsonReader ( json ) ;
117+ reader . ReadStartDocument ( ) ;
118+ reader . ReadName ( "x" ) ;
119+ var context = BsonDeserializationContext . CreateRoot ( reader ) ;
120+
121+ var exception = Record . Exception ( ( ) => subject . Deserialize ( context ) ) ;
122+ exception . Should ( ) . BeOfType < BsonSerializationException > ( ) ;
123+ exception . Message . Should ( ) . Be ( "Deserialized TimeOnly components do not match the ticks value." ) ;
124+ }
125+
126+ [ Fact ]
127+ public void Deserialize_with_document_should_throw_when_field_is_unknown ( )
128+ {
129+ const string json = """{ "x" : { "Unknown": "test", Ticks: { "$numberDouble" : "307255946583" } } }""" ;
130+ var subject = new TimeOnlySerializer ( ) ;
131+
132+ using var reader = new JsonReader ( json ) ;
133+ reader . ReadStartDocument ( ) ;
134+ reader . ReadName ( "x" ) ;
135+ var context = BsonDeserializationContext . CreateRoot ( reader ) ;
136+
137+ var exception = Record . Exception ( ( ) => subject . Deserialize ( context ) ) ;
138+ exception . Should ( ) . BeOfType < BsonSerializationException > ( ) ;
139+ exception . Message . Should ( ) . Be ( "Invalid element: 'Unknown'." ) ;
140+ }
141+
84142 [ Theory ]
85143 [ InlineData ( """{ "x" : "08:32:05.5946583" }""" , "08:32:05.5946583" ) ]
86144 [ InlineData ( """{ "x" : "00:00:00.0000000" }""" , "00:00:00.0000000" ) ]
@@ -273,6 +331,17 @@ public void GetHashCode_should_return_zero()
273331 result . Should ( ) . Be ( 0 ) ;
274332 }
275333
334+ [ Theory ]
335+ [ InlineData ( "08:32:05.5946583" , """{ "x" : { "Hour" : { "$numberInt" : "8" }, "Minute" : { "$numberInt" : "32" }, "Second" : { "$numberInt" : "5" }, "Millisecond" : { "$numberInt" : "594" }, "Microsecond" : { "$numberInt" : "658" }, "Nanosecond" : { "$numberInt" : "300" }, "Ticks" : { "$numberLong" : "307255946583" } } }""" ) ]
336+ [ InlineData ( "00:00:00.0000000" , """{ "x" : { "Hour" : { "$numberInt" : "0" }, "Minute" : { "$numberInt" : "0" }, "Second" : { "$numberInt" : "0" }, "Millisecond" : { "$numberInt" : "0" }, "Microsecond" : { "$numberInt" : "0" }, "Nanosecond" : { "$numberInt" : "0" }, "Ticks" : { "$numberLong" : "0" } } }""" ) ]
337+ [ InlineData ( "23:59:59.9999999" , """{ "x" : { "Hour" : { "$numberInt" : "23" }, "Minute" : { "$numberInt" : "59" }, "Second" : { "$numberInt" : "59" }, "Millisecond" : { "$numberInt" : "999" }, "Microsecond" : { "$numberInt" : "999" }, "Nanosecond" : { "$numberInt" : "900" }, "Ticks" : { "$numberLong" : "863999999999" } } }""" ) ]
338+ public void Serialize_with_document_representation_should_have_expected_result ( string valueString , string expectedResult )
339+ {
340+ var subject = new TimeOnlySerializer ( BsonType . Document ) ;
341+
342+ TestSerialize ( subject , valueString , expectedResult ) ;
343+ }
344+
276345 [ Theory ]
277346 [ InlineData ( BsonType . String , "08:32:05.5946583" , """{ "x" : "08:32:05.5946583" }""" ) ]
278347 [ InlineData ( BsonType . String , "00:00:00.0000000" , """{ "x" : "00:00:00.0000000" }""" ) ]
@@ -407,8 +476,8 @@ public void Serializer_should_be_registered()
407476 [ Theory ]
408477 [ ParameterAttributeData ]
409478 public void WithRepresentation_should_return_expected_result (
410- [ Values ( BsonType . String , BsonType . Int64 , BsonType . Int32 , BsonType . Double ) ] BsonType oldRepresentation ,
411- [ Values ( BsonType . String , BsonType . Int64 , BsonType . Int32 , BsonType . Double ) ] BsonType newRepresentation )
479+ [ Values ( BsonType . String , BsonType . Int64 , BsonType . Int32 , BsonType . Double , BsonType . Document ) ] BsonType oldRepresentation ,
480+ [ Values ( BsonType . String , BsonType . Int64 , BsonType . Int32 , BsonType . Double , BsonType . Document ) ] BsonType newRepresentation )
412481 {
413482 var subject = new TimeOnlySerializer ( oldRepresentation ) ;
414483
@@ -473,6 +542,9 @@ private class TestClass
473542
474543 [ BsonTimeOnlyOptions ( BsonType . Int64 , TimeOnlyUnits . Nanoseconds ) ]
475544 public TimeOnly Nanoseconds { get ; set ; }
545+
546+ [ BsonTimeOnlyOptions ( BsonType . Document ) ]
547+ public TimeOnly Document { get ; set ; }
476548 }
477549 }
478550#endif
0 commit comments