@@ -452,6 +452,99 @@ def test_w_bogus_string_value(self):
452452 self ._call_fut ("12:12:27.123" , object ())
453453
454454
455+ class Test_range_from_json (unittest .TestCase ):
456+ def _call_fut (self , value , field ):
457+ from google .cloud .bigquery ._helpers import _range_from_json
458+
459+ return _range_from_json (value , field )
460+
461+ def test_w_none_nullable (self ):
462+ self .assertIsNone (self ._call_fut (None , _Field ("NULLABLE" )))
463+
464+ def test_w_none_required (self ):
465+ with self .assertRaises (TypeError ):
466+ self ._call_fut (None , _Field ("REQUIRED" ))
467+
468+ def test_w_wrong_format (self ):
469+ range_field = _Field (
470+ "NULLABLE" ,
471+ field_type = "RANGE" ,
472+ range_element_type = _Field ("NULLABLE" , element_type = "DATE" ),
473+ )
474+ with self .assertRaises (ValueError ):
475+ self ._call_fut ("[2009-06-172019-06-17)" , range_field )
476+
477+ def test_w_wrong_element_type (self ):
478+ range_field = _Field (
479+ "NULLABLE" ,
480+ field_type = "RANGE" ,
481+ range_element_type = _Field ("NULLABLE" , element_type = "TIME" ),
482+ )
483+ with self .assertRaises (ValueError ):
484+ self ._call_fut ("[15:31:38, 15:50:38)" , range_field )
485+
486+ def test_w_unbounded_value (self ):
487+ range_field = _Field (
488+ "NULLABLE" ,
489+ field_type = "RANGE" ,
490+ range_element_type = _Field ("NULLABLE" , element_type = "DATE" ),
491+ )
492+ coerced = self ._call_fut ("[UNBOUNDED, 2019-06-17)" , range_field )
493+ self .assertEqual (
494+ coerced ,
495+ {"start" : None , "end" : datetime .date (2019 , 6 , 17 )},
496+ )
497+
498+ def test_w_date_value (self ):
499+ range_field = _Field (
500+ "NULLABLE" ,
501+ field_type = "RANGE" ,
502+ range_element_type = _Field ("NULLABLE" , element_type = "DATE" ),
503+ )
504+ coerced = self ._call_fut ("[2009-06-17, 2019-06-17)" , range_field )
505+ self .assertEqual (
506+ coerced ,
507+ {
508+ "start" : datetime .date (2009 , 6 , 17 ),
509+ "end" : datetime .date (2019 , 6 , 17 ),
510+ },
511+ )
512+
513+ def test_w_datetime_value (self ):
514+ range_field = _Field (
515+ "NULLABLE" ,
516+ field_type = "RANGE" ,
517+ range_element_type = _Field ("NULLABLE" , element_type = "DATETIME" ),
518+ )
519+ coerced = self ._call_fut (
520+ "[2009-06-17T13:45:30, 2019-06-17T13:45:30)" , range_field
521+ )
522+ self .assertEqual (
523+ coerced ,
524+ {
525+ "start" : datetime .datetime (2009 , 6 , 17 , 13 , 45 , 30 ),
526+ "end" : datetime .datetime (2019 , 6 , 17 , 13 , 45 , 30 ),
527+ },
528+ )
529+
530+ def test_w_timestamp_value (self ):
531+ from google .cloud ._helpers import _EPOCH
532+
533+ range_field = _Field (
534+ "NULLABLE" ,
535+ field_type = "RANGE" ,
536+ range_element_type = _Field ("NULLABLE" , element_type = "TIMESTAMP" ),
537+ )
538+ coerced = self ._call_fut ("[1234567, 1234789)" , range_field )
539+ self .assertEqual (
540+ coerced ,
541+ {
542+ "start" : _EPOCH + datetime .timedelta (seconds = 1 , microseconds = 234567 ),
543+ "end" : _EPOCH + datetime .timedelta (seconds = 1 , microseconds = 234789 ),
544+ },
545+ )
546+
547+
455548class Test_record_from_json (unittest .TestCase ):
456549 def _call_fut (self , value , field ):
457550 from google .cloud .bigquery ._helpers import _record_from_json
@@ -1323,11 +1416,21 @@ def test_w_str(self):
13231416
13241417
13251418class _Field (object ):
1326- def __init__ (self , mode , name = "unknown" , field_type = "UNKNOWN" , fields = ()):
1419+ def __init__ (
1420+ self ,
1421+ mode ,
1422+ name = "unknown" ,
1423+ field_type = "UNKNOWN" ,
1424+ fields = (),
1425+ range_element_type = None ,
1426+ element_type = None ,
1427+ ):
13271428 self .mode = mode
13281429 self .name = name
13291430 self .field_type = field_type
13301431 self .fields = fields
1432+ self .range_element_type = range_element_type
1433+ self .element_type = element_type
13311434
13321435
13331436def _field_isinstance_patcher ():
0 commit comments