@@ -46,6 +46,17 @@ class MyDoc(Document):
46
46
md = MyDoc (dt = '' )
47
47
self .assertRaises (ValidationError , md .save )
48
48
49
+ def test_date_from_empty_string (self ):
50
+ """
51
+ Ensure an exception is raised when trying to
52
+ cast an empty string to datetime.
53
+ """
54
+ class MyDoc (Document ):
55
+ dt = DateField ()
56
+
57
+ md = MyDoc (dt = '' )
58
+ self .assertRaises (ValidationError , md .save )
59
+
49
60
def test_datetime_from_whitespace_string (self ):
50
61
"""
51
62
Ensure an exception is raised when trying to
@@ -57,6 +68,17 @@ class MyDoc(Document):
57
68
md = MyDoc (dt = ' ' )
58
69
self .assertRaises (ValidationError , md .save )
59
70
71
+ def test_date_from_whitespace_string (self ):
72
+ """
73
+ Ensure an exception is raised when trying to
74
+ cast a whitespace-only string to datetime.
75
+ """
76
+ class MyDoc (Document ):
77
+ dt = DateField ()
78
+
79
+ md = MyDoc (dt = ' ' )
80
+ self .assertRaises (ValidationError , md .save )
81
+
60
82
def test_default_values_nothing_set (self ):
61
83
"""Ensure that default field values are used when creating
62
84
a document.
@@ -66,13 +88,14 @@ class Person(Document):
66
88
age = IntField (default = 30 , required = False )
67
89
userid = StringField (default = lambda : 'test' , required = True )
68
90
created = DateTimeField (default = datetime .datetime .utcnow )
91
+ day = DateField (default = datetime .date .today )
69
92
70
93
person = Person (name = "Ross" )
71
94
72
95
# Confirm saving now would store values
73
96
data_to_be_saved = sorted (person .to_mongo ().keys ())
74
97
self .assertEqual (data_to_be_saved ,
75
- ['age' , 'created' , 'name' , 'userid' ]
98
+ ['age' , 'created' , 'day' , ' name' , 'userid' ]
76
99
)
77
100
78
101
self .assertTrue (person .validate () is None )
@@ -81,16 +104,18 @@ class Person(Document):
81
104
self .assertEqual (person .age , person .age )
82
105
self .assertEqual (person .userid , person .userid )
83
106
self .assertEqual (person .created , person .created )
107
+ self .assertEqual (person .day , person .day )
84
108
85
109
self .assertEqual (person ._data ['name' ], person .name )
86
110
self .assertEqual (person ._data ['age' ], person .age )
87
111
self .assertEqual (person ._data ['userid' ], person .userid )
88
112
self .assertEqual (person ._data ['created' ], person .created )
113
+ self .assertEqual (person ._data ['day' ], person .day )
89
114
90
115
# Confirm introspection changes nothing
91
116
data_to_be_saved = sorted (person .to_mongo ().keys ())
92
117
self .assertEqual (
93
- data_to_be_saved , ['age' , 'created' , 'name' , 'userid' ])
118
+ data_to_be_saved , ['age' , 'created' , 'day' , ' name' , 'userid' ])
94
119
95
120
def test_default_values_set_to_None (self ):
96
121
"""Ensure that default field values are used even when
@@ -662,6 +687,32 @@ class LogEntry(Document):
662
687
log .time = 'ABC'
663
688
self .assertRaises (ValidationError , log .validate )
664
689
690
+ def test_date_validation (self ):
691
+ """Ensure that invalid values cannot be assigned to datetime
692
+ fields.
693
+ """
694
+ class LogEntry (Document ):
695
+ time = DateField ()
696
+
697
+ log = LogEntry ()
698
+ log .time = datetime .datetime .now ()
699
+ log .validate ()
700
+
701
+ log .time = datetime .date .today ()
702
+ log .validate ()
703
+
704
+ log .time = datetime .datetime .now ().isoformat (' ' )
705
+ log .validate ()
706
+
707
+ if dateutil :
708
+ log .time = datetime .datetime .now ().isoformat ('T' )
709
+ log .validate ()
710
+
711
+ log .time = - 1
712
+ self .assertRaises (ValidationError , log .validate )
713
+ log .time = 'ABC'
714
+ self .assertRaises (ValidationError , log .validate )
715
+
665
716
def test_datetime_tz_aware_mark_as_changed (self ):
666
717
from mongoengine import connection
667
718
@@ -733,6 +784,51 @@ class LogEntry(Document):
733
784
self .assertNotEqual (log .date , d1 )
734
785
self .assertEqual (log .date , d2 )
735
786
787
+ def test_date (self ):
788
+ """Tests showing pymongo date fields
789
+
790
+ See: http://api.mongodb.org/python/current/api/bson/son.html#dt
791
+ """
792
+ class LogEntry (Document ):
793
+ date = DateField ()
794
+
795
+ LogEntry .drop_collection ()
796
+
797
+ # Test can save dates
798
+ log = LogEntry ()
799
+ log .date = datetime .date .today ()
800
+ log .save ()
801
+ log .reload ()
802
+ self .assertEqual (log .date , datetime .date .today ())
803
+
804
+ d1 = datetime .datetime (1970 , 1 , 1 , 0 , 0 , 1 , 999 )
805
+ d2 = datetime .datetime (1970 , 1 , 1 , 0 , 0 , 1 )
806
+ log = LogEntry ()
807
+ log .date = d1
808
+ log .save ()
809
+ log .reload ()
810
+ self .assertEqual (log .date , d1 .date ())
811
+ self .assertEqual (log .date , d2 .date ())
812
+
813
+ d1 = datetime .datetime (1970 , 1 , 1 , 0 , 0 , 1 , 9999 )
814
+ d2 = datetime .datetime (1970 , 1 , 1 , 0 , 0 , 1 , 9000 )
815
+ log .date = d1
816
+ log .save ()
817
+ log .reload ()
818
+ self .assertEqual (log .date , d1 .date ())
819
+ self .assertEqual (log .date , d2 .date ())
820
+
821
+ if not six .PY3 :
822
+ # Pre UTC dates microseconds below 1000 are dropped
823
+ # This does not seem to be true in PY3
824
+ d1 = datetime .datetime (1969 , 12 , 31 , 23 , 59 , 59 , 999 )
825
+ d2 = datetime .datetime (1969 , 12 , 31 , 23 , 59 , 59 )
826
+ log .date = d1
827
+ log .save ()
828
+ log .reload ()
829
+ self .assertEqual (log .date , d1 .date ())
830
+ self .assertEqual (log .date , d2 .date ())
831
+
736
832
def test_datetime_usage (self ):
737
833
"""Tests for regular datetime fields"""
738
834
class LogEntry (Document ):
@@ -787,6 +883,51 @@ class LogEntry(Document):
787
883
)
788
884
self .assertEqual (logs .count (), 5 )
789
885
886
+ def test_date_usage (self ):
887
+ """Tests for regular datetime fields"""
888
+ class LogEntry (Document ):
889
+ date = DateField ()
890
+
891
+ LogEntry .drop_collection ()
892
+
893
+ d1 = datetime .datetime (1970 , 1 , 1 , 0 , 0 , 1 )
894
+ log = LogEntry ()
895
+ log .date = d1
896
+ log .validate ()
897
+ log .save ()
898
+
899
+ for query in (d1 , d1 .isoformat (' ' )):
900
+ log1 = LogEntry .objects .get (date = query )
901
+ self .assertEqual (log , log1 )
902
+
903
+ if dateutil :
904
+ log1 = LogEntry .objects .get (date = d1 .isoformat ('T' ))
905
+ self .assertEqual (log , log1 )
906
+
907
+ # create additional 19 log entries for a total of 20
908
+ for i in range (1971 , 1990 ):
909
+ d = datetime .datetime (i , 1 , 1 , 0 , 0 , 1 )
910
+ LogEntry (date = d ).save ()
911
+
912
+ self .assertEqual (LogEntry .objects .count (), 20 )
913
+
914
+ # Test ordering
915
+ logs = LogEntry .objects .order_by ("date" )
916
+ i = 0
917
+ while i < 19 :
918
+ self .assertTrue (logs [i ].date <= logs [i + 1 ].date )
919
+ i += 1
920
+
921
+ logs = LogEntry .objects .order_by ("-date" )
922
+ i = 0
923
+ while i < 19 :
924
+ self .assertTrue (logs [i ].date >= logs [i + 1 ].date )
925
+ i += 1
926
+
927
+ # Test searching
928
+ logs = LogEntry .objects .filter (date__gte = datetime .datetime (1980 , 1 , 1 ))
929
+ self .assertEqual (logs .count (), 10 )
930
+
790
931
def test_complexdatetime_storage (self ):
791
932
"""Tests for complex datetime fields - which can handle
792
933
microseconds without rounding.
0 commit comments