@@ -151,6 +151,86 @@ def on_epoch_time(epoch_secs):
151151 exception = e
152152 self .assertIsNotNone (exception )
153153
154+ def test_cbor_encode_decode_datetime (self ):
155+ """Test automatic datetime encoding/decoding"""
156+ # Create a datetime object
157+ dt = datetime .datetime (2024 , 1 , 1 , 12 , 0 , 0 )
158+
159+ # Encode datetime - should automatically convert to CBOR tag 1 + timestamp
160+ encoder = AwsCborEncoder ()
161+ encoder .write_data_item (dt )
162+
163+ # Decode with callback to convert back to datetime
164+ def on_epoch_time (epoch_secs ):
165+ return datetime .datetime .fromtimestamp (epoch_secs )
166+
167+ decoder = AwsCborDecoder (encoder .get_encoded_data (), on_epoch_time )
168+ result = decoder .pop_next_data_item ()
169+
170+ # Verify the result matches original datetime
171+ self .assertEqual (dt , result )
172+ self .assertIsInstance (result , datetime .datetime )
173+
174+ # Test datetime with microsecond precision (milliseconds)
175+ dt_with_microseconds = datetime .datetime (2024 , 1 , 1 , 12 , 0 , 0 , 123456 ) # 123.456 milliseconds
176+ encoder3 = AwsCborEncoder ()
177+ encoder3 .write_data_item (dt_with_microseconds )
178+
179+ decoder3 = AwsCborDecoder (encoder3 .get_encoded_data (), on_epoch_time )
180+ result_microseconds = decoder3 .pop_next_data_item ()
181+
182+ # Verify microsecond precision is preserved
183+ self .assertEqual (dt_with_microseconds , result_microseconds )
184+ self .assertEqual (dt_with_microseconds .microsecond , result_microseconds .microsecond )
185+ self .assertIsInstance (result_microseconds , datetime .datetime )
186+
187+ # Test datetime in a list
188+ encoder2 = AwsCborEncoder ()
189+ test_list = [dt , "text" , 123 , dt_with_microseconds ]
190+ encoder2 .write_data_item (test_list )
191+
192+ decoder2 = AwsCborDecoder (encoder2 .get_encoded_data (), on_epoch_time )
193+ result_list = decoder2 .pop_next_data_item ()
194+
195+ self .assertEqual (len (result_list ), 4 )
196+ self .assertEqual (result_list [0 ], dt )
197+ self .assertEqual (result_list [1 ], "text" )
198+ self .assertEqual (result_list [2 ], 123 )
199+ self .assertEqual (result_list [3 ], dt_with_microseconds )
200+ # Verify microsecond precision in list
201+ self .assertEqual (result_list [3 ].microsecond , 123456 )
202+
203+ def test_cbor_encode_unsupported_type (self ):
204+ """Test that encoding unsupported types raises ValueError"""
205+ # Create a custom class that's not supported by CBOR encoder
206+ class CustomClass :
207+ def __init__ (self , value ):
208+ self .value = value
209+
210+ # Try to encode an unsupported type
211+ encoder = AwsCborEncoder ()
212+ unsupported_obj = CustomClass (42 )
213+
214+ # Should raise ValueError with message about unsupported type
215+ with self .assertRaises (ValueError ) as context :
216+ encoder .write_data_item (unsupported_obj )
217+ # Verify the error message mentions "Not supported type"
218+ self .assertIn ("Not supported type" , str (context .exception ))
219+
220+ # Test unsupported type in a list (should also fail)
221+ encoder2 = AwsCborEncoder ()
222+ with self .assertRaises (ValueError ) as context2 :
223+ encoder2 .write_data_item ([1 , 2 , unsupported_obj , 3 ])
224+
225+ self .assertIn ("Not supported type" , str (context2 .exception ))
226+
227+ # Test unsupported type as dict key (should also fail)
228+ encoder3 = AwsCborEncoder ()
229+ with self .assertRaises (ValueError ) as context3 :
230+ encoder3 .write_data_item ({unsupported_obj : "value" })
231+
232+ self .assertIn ("Not supported type" , str (context3 .exception ))
233+
154234 def _ieee754_bits_to_float (self , bits ):
155235 return struct .unpack ('>f' , struct .pack ('>I' , bits ))[0 ]
156236
0 commit comments