@@ -9,12 +9,26 @@ pub enum TimeFilter {
99 After ( SystemTime ) ,
1010}
1111
12+ #[ cfg( not( test) ) ]
13+ fn now ( ) -> Zoned {
14+ Zoned :: now ( )
15+ }
16+
17+ #[ cfg( test) ]
18+ thread_local ! {
19+ static TESTTIME : std:: cell:: RefCell <Option <Zoned >> = None . into( ) ;
20+ }
21+
22+ /// This allows us to set a specific time when running tests
23+ #[ cfg( test) ]
24+ fn now ( ) -> Zoned {
25+ TESTTIME . with_borrow ( |reftime| reftime. as_ref ( ) . cloned ( ) . unwrap_or_else ( || Zoned :: now ( ) ) )
26+ }
27+
1228impl TimeFilter {
13- fn from_str ( ref_time : & SystemTime , s : & str ) -> Option < SystemTime > {
29+ fn from_str ( s : & str ) -> Option < SystemTime > {
1430 s. parse :: < Span > ( )
15- . and_then ( |duration| {
16- Zoned :: try_from ( * ref_time) . and_then ( |zdt| zdt. checked_sub ( duration) )
17- } )
31+ . and_then ( |duration| now ( ) . checked_sub ( duration) )
1832 . ok ( )
1933 . or_else ( || {
2034 let local_tz = TimeZone :: system ( ) ;
@@ -37,12 +51,12 @@ impl TimeFilter {
3751 . map ( SystemTime :: from)
3852 }
3953
40- pub fn before ( ref_time : & SystemTime , s : & str ) -> Option < TimeFilter > {
41- TimeFilter :: from_str ( ref_time , s) . map ( TimeFilter :: Before )
54+ pub fn before ( s : & str ) -> Option < TimeFilter > {
55+ TimeFilter :: from_str ( s) . map ( TimeFilter :: Before )
4256 }
4357
44- pub fn after ( ref_time : & SystemTime , s : & str ) -> Option < TimeFilter > {
45- TimeFilter :: from_str ( ref_time , s) . map ( TimeFilter :: After )
58+ pub fn after ( s : & str ) -> Option < TimeFilter > {
59+ TimeFilter :: from_str ( s) . map ( TimeFilter :: After )
4660 }
4761
4862 pub fn applies_to ( & self , t : & SystemTime ) -> bool {
@@ -58,107 +72,96 @@ mod tests {
5872 use super :: * ;
5973 use std:: time:: Duration ;
6074
75+ fn set_test_time ( time : Zoned ) -> SystemTime {
76+ TESTTIME . with_borrow_mut ( |t| * t = Some ( time. clone ( ) ) ) ;
77+ time. into ( )
78+ }
79+
6180 #[ test]
6281 fn is_time_filter_applicable ( ) {
6382 let local_tz = TimeZone :: system ( ) ;
64- let ref_time = local_tz
65- . to_ambiguous_zoned ( "2010-10-10 10:10:10" . parse :: < DateTime > ( ) . unwrap ( ) )
66- . later ( )
67- . unwrap ( )
68- . into ( ) ;
83+ let ref_time = set_test_time (
84+ local_tz
85+ . to_ambiguous_zoned ( "2010-10-10 10:10:10" . parse :: < DateTime > ( ) . unwrap ( ) )
86+ . later ( )
87+ . unwrap ( ) ,
88+ ) ;
6989
70- assert ! ( TimeFilter :: after( & ref_time, "1min" )
71- . unwrap( )
72- . applies_to( & ref_time) ) ;
73- assert ! ( !TimeFilter :: before( & ref_time, "1min" )
74- . unwrap( )
75- . applies_to( & ref_time) ) ;
90+ assert ! ( TimeFilter :: after( "1min" ) . unwrap( ) . applies_to( & ref_time) ) ;
91+ assert ! ( !TimeFilter :: before( "1min" ) . unwrap( ) . applies_to( & ref_time) ) ;
7692
7793 let t1m_ago = ref_time - Duration :: from_secs ( 60 ) ;
78- assert ! ( !TimeFilter :: after( & ref_time, "30sec" )
79- . unwrap( )
80- . applies_to( & t1m_ago) ) ;
81- assert ! ( TimeFilter :: after( & ref_time, "2min" )
82- . unwrap( )
83- . applies_to( & t1m_ago) ) ;
94+ assert ! ( !TimeFilter :: after( "30sec" ) . unwrap( ) . applies_to( & t1m_ago) ) ;
95+ assert ! ( TimeFilter :: after( "2min" ) . unwrap( ) . applies_to( & t1m_ago) ) ;
8496
85- assert ! ( TimeFilter :: before( & ref_time, "30sec" )
86- . unwrap( )
87- . applies_to( & t1m_ago) ) ;
88- assert ! ( !TimeFilter :: before( & ref_time, "2min" )
89- . unwrap( )
90- . applies_to( & t1m_ago) ) ;
97+ assert ! ( TimeFilter :: before( "30sec" ) . unwrap( ) . applies_to( & t1m_ago) ) ;
98+ assert ! ( !TimeFilter :: before( "2min" ) . unwrap( ) . applies_to( & t1m_ago) ) ;
9199
92100 let t10s_before = "2010-10-10 10:10:00" ;
93- assert ! ( !TimeFilter :: before( & ref_time , t10s_before)
101+ assert ! ( !TimeFilter :: before( t10s_before)
94102 . unwrap( )
95103 . applies_to( & ref_time) ) ;
96- assert ! ( TimeFilter :: before( & ref_time , t10s_before)
104+ assert ! ( TimeFilter :: before( t10s_before)
97105 . unwrap( )
98106 . applies_to( & t1m_ago) ) ;
99107
100- assert ! ( TimeFilter :: after( & ref_time , t10s_before)
108+ assert ! ( TimeFilter :: after( t10s_before)
101109 . unwrap( )
102110 . applies_to( & ref_time) ) ;
103- assert ! ( !TimeFilter :: after( & ref_time, t10s_before)
104- . unwrap( )
105- . applies_to( & t1m_ago) ) ;
111+ assert ! ( !TimeFilter :: after( t10s_before) . unwrap( ) . applies_to( & t1m_ago) ) ;
106112
107113 let same_day = "2010-10-10" ;
108- assert ! ( !TimeFilter :: before( & ref_time, same_day)
109- . unwrap( )
110- . applies_to( & ref_time) ) ;
111- assert ! ( !TimeFilter :: before( & ref_time, same_day)
112- . unwrap( )
113- . applies_to( & t1m_ago) ) ;
114-
115- assert ! ( TimeFilter :: after( & ref_time, same_day)
116- . unwrap( )
117- . applies_to( & ref_time) ) ;
118- assert ! ( TimeFilter :: after( & ref_time, same_day)
119- . unwrap( )
120- . applies_to( & t1m_ago) ) ;
121-
122- let ref_time = "2010-10-10T10:10:10+00:00"
123- . parse :: < Timestamp > ( )
124- . unwrap ( )
125- . into ( ) ;
114+ assert ! ( !TimeFilter :: before( same_day) . unwrap( ) . applies_to( & ref_time) ) ;
115+ assert ! ( !TimeFilter :: before( same_day) . unwrap( ) . applies_to( & t1m_ago) ) ;
116+
117+ assert ! ( TimeFilter :: after( same_day) . unwrap( ) . applies_to( & ref_time) ) ;
118+ assert ! ( TimeFilter :: after( same_day) . unwrap( ) . applies_to( & t1m_ago) ) ;
119+
120+ let ref_time = set_test_time (
121+ "2010-10-10T10:10:10+00:00"
122+ . parse :: < Timestamp > ( )
123+ . unwrap ( )
124+ . to_zoned ( local_tz. clone ( ) ) ,
125+ ) ;
126126 let t1m_ago = ref_time - Duration :: from_secs ( 60 ) ;
127127 let t10s_before = "2010-10-10T10:10:00+00:00" ;
128- assert ! ( !TimeFilter :: before( & ref_time , t10s_before)
128+ assert ! ( !TimeFilter :: before( t10s_before)
129129 . unwrap( )
130130 . applies_to( & ref_time) ) ;
131- assert ! ( TimeFilter :: before( & ref_time , t10s_before)
131+ assert ! ( TimeFilter :: before( t10s_before)
132132 . unwrap( )
133133 . applies_to( & t1m_ago) ) ;
134134
135- assert ! ( TimeFilter :: after( & ref_time , t10s_before)
135+ assert ! ( TimeFilter :: after( t10s_before)
136136 . unwrap( )
137137 . applies_to( & ref_time) ) ;
138- assert ! ( !TimeFilter :: after( & ref_time, t10s_before)
139- . unwrap( )
140- . applies_to( & t1m_ago) ) ;
138+ assert ! ( !TimeFilter :: after( t10s_before) . unwrap( ) . applies_to( & t1m_ago) ) ;
141139
142140 let ref_timestamp = 1707723412u64 ; // Mon Feb 12 07:36:52 UTC 2024
143- let ref_time = "2024-02-12T07:36:52+00:00"
144- . parse :: < Timestamp > ( )
145- . unwrap ( )
146- . into ( ) ;
141+ let ref_time = set_test_time (
142+ "2024-02-12T07:36:52+00:00"
143+ . parse :: < Timestamp > ( )
144+ . unwrap ( )
145+ . to_zoned ( local_tz) ,
146+ ) ;
147147 let t1m_ago = ref_time - Duration :: from_secs ( 60 ) ;
148148 let t1s_later = ref_time + Duration :: from_secs ( 1 ) ;
149149 // Timestamp only supported via '@' prefix
150- assert ! ( TimeFilter :: before( & ref_time , & ref_timestamp. to_string( ) ) . is_none( ) ) ;
151- assert ! ( TimeFilter :: before( & ref_time , & format!( "@{ref_timestamp}" ) )
150+ assert ! ( TimeFilter :: before( & ref_timestamp. to_string( ) ) . is_none( ) ) ;
151+ assert ! ( TimeFilter :: before( & format!( "@{ref_timestamp}" ) )
152152 . unwrap( )
153153 . applies_to( & t1m_ago) ) ;
154- assert ! ( !TimeFilter :: before( & ref_time , & format!( "@{ref_timestamp}" ) )
154+ assert ! ( !TimeFilter :: before( & format!( "@{ref_timestamp}" ) )
155155 . unwrap( )
156156 . applies_to( & t1s_later) ) ;
157- assert ! ( !TimeFilter :: after( & ref_time , & format!( "@{ref_timestamp}" ) )
157+ assert ! ( !TimeFilter :: after( & format!( "@{ref_timestamp}" ) )
158158 . unwrap( )
159159 . applies_to( & t1m_ago) ) ;
160- assert ! ( TimeFilter :: after( & ref_time , & format!( "@{ref_timestamp}" ) )
160+ assert ! ( TimeFilter :: after( & format!( "@{ref_timestamp}" ) )
161161 . unwrap( )
162162 . applies_to( & t1s_later) ) ;
163+
164+ // Stop using manually set times
165+ TESTTIME . with_borrow_mut ( |t| * t = None ) ;
163166 }
164167}
0 commit comments