1 | /* Copyright (c) 2002,2003 CrystalClear Software, Inc. |
2 | * Use, modification and distribution is subject to the |
3 | * Boost Software License, Version 1.0. (See accompanying |
4 | * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) |
5 | * Author: Bart Garst |
6 | */ |
7 | |
8 | #include <iostream> |
9 | #include "boost/date_time/period.hpp" |
10 | #include "testfrmwk.hpp" |
11 | |
12 | /*! duration_rep parameter for period requires a func unit() that |
13 | * returns the smallest unit of measure for this type. This minimal |
14 | * class fulfills that, and other, requirements */ |
15 | template<class int_type> |
16 | class duration_type { |
17 | public: |
18 | duration_type(int_type a = 0) : _val(a) {} |
19 | static int_type unit() { return 1; } |
20 | int_type get_rep() { return _val; } |
21 | bool operator==(duration_type<int_type> rhs) { return _val == rhs._val; } |
22 | bool operator<(duration_type<int_type> rhs) { return _val < rhs._val; } |
23 | bool operator>(duration_type<int_type> rhs) { return _val > rhs._val; } |
24 | private: |
25 | int_type _val; |
26 | }; |
27 | //! To enable things like "cout << period.length()" |
28 | template<class int_type> |
29 | inline |
30 | std::ostream& operator<<(std::ostream& os, duration_type<int_type> dt){ |
31 | os << dt.get_rep(); |
32 | return os; |
33 | } |
34 | //! this operator is needed because period adds a duration_rep to a point_rep |
35 | template<class int_type> |
36 | inline |
37 | int_type operator+(int i, duration_type<int_type> dt){ |
38 | return i + dt.get_rep(); |
39 | } |
40 | |
41 | //! this operator is needed because period adds a duration_rep to a point_rep |
42 | template<class int_type> |
43 | inline |
44 | int_type operator-(int i, duration_type<int_type> dt){ |
45 | return i - dt.get_rep(); |
46 | } |
47 | |
48 | |
49 | int main(){ |
50 | using namespace boost::date_time; |
51 | typedef period<int, duration_type<int> > a_period; |
52 | |
53 | /*** check all functions - normal periods ***/ |
54 | |
55 | a_period p1(1, duration_type<int>(9)); |
56 | check(testname: "Different constructors" , testcond: p1 == a_period(1, 10)); |
57 | check(testname: "First" , testcond: p1.begin() == 1); |
58 | check(testname: "Last" , testcond: p1.last() == 9); |
59 | check(testname: "End" , testcond: p1.end() == 10); |
60 | check(testname: "Length" , testcond: p1.length() == 9); |
61 | check(testname: "is_null (not)" , testcond: !p1.is_null()); |
62 | |
63 | a_period p2(5, 30); |
64 | check(testname: "First" , testcond: p2.begin() == 5); |
65 | check(testname: "Last" , testcond: p2.last() == 29); |
66 | check(testname: "End" , testcond: p2.end() == 30); |
67 | check(testname: "Length" , testcond: p2.length() == 25); |
68 | check(testname: "is_null (not)" , testcond: !p2.is_null()); |
69 | |
70 | a_period p3(35, 81); |
71 | check(testname: "Operator ==" , testcond: p1 == a_period(1,10)); |
72 | check(testname: "Operator !=" , testcond: p1 != p2); |
73 | check(testname: "Operator <" , testcond: p1 < p3); |
74 | check(testname: "Operator >" , testcond: p3 > p2); |
75 | |
76 | { |
77 | a_period p(1,10); |
78 | p.shift(d: 5); |
79 | check(testname: "Shift (right)" , testcond: p == a_period(6,15)); |
80 | p.shift(d: -15); |
81 | check(testname: "Shift (left)" , testcond: p == a_period(-9,0)); |
82 | } |
83 | |
84 | check(testname: "Contains rep" , testcond: p2.contains(point: 20)); |
85 | check(testname: "Contains rep (not)" , testcond: !p2.contains(point: 2)); |
86 | check(testname: "Contains period" , testcond: p1.contains(other: a_period(2,8))); |
87 | check(testname: "Contains period (not)" , testcond: !p1.contains(other: p3)); |
88 | |
89 | check(testname: "Intersects" , testcond: p1.intersects(other: p2)); |
90 | check(testname: "Intersects" , testcond: p2.intersects(other: p1)); |
91 | |
92 | check(testname: "Adjacent" , testcond: p1.is_adjacent(other: a_period(-5,1))); |
93 | check(testname: "Adjacent" , testcond: p1.is_adjacent(other: a_period(10,20))); |
94 | check(testname: "Adjacent (not)" , testcond: !p1.is_adjacent(other: p3)); |
95 | |
96 | check(testname: "Is before" , testcond: p1.is_before(t: 15)); |
97 | check(testname: "Is after" , testcond: p3.is_after(t: 15)); |
98 | |
99 | check(testname: "Intersection" , testcond: (p1.intersection(other: p2) == a_period(5,10))); |
100 | check(testname: "Intersection" , testcond: (p1.intersection(other: p3).is_null())); |
101 | |
102 | check(testname: "Merge" , testcond: p1.merge(other: p2) == a_period(1,30) ); |
103 | check(testname: "Merge" , testcond: p1.merge(other: p3).is_null()); |
104 | |
105 | check(testname: "Span" , testcond: p3.span(other: p1) == a_period(1, 81)); |
106 | |
107 | /*** zero length period ***/ |
108 | |
109 | // treat a zero length period as a point |
110 | a_period zero_len(3,duration_type<int>(0)); |
111 | check(testname: "Same beg & end == zero_length" , |
112 | testcond: a_period(1,1) == a_period(1, duration_type<int>(0))); |
113 | check(testname: "2 point (zero length) == 1 point zero duration" , |
114 | testcond: a_period(3,3) == zero_len); |
115 | |
116 | // zero_length period always returns false for is_before & is_after |
117 | check(testname: "Is Before zero period" , testcond: !zero_len.is_before(t: 5)); |
118 | check(testname: "Is After zero period (not)" , testcond: !zero_len.is_after(t: 5)); |
119 | check(testname: "Is Before zero period (not)" , testcond: !zero_len.is_before(t: -5)); |
120 | check(testname: "Is After zero period" , testcond: !zero_len.is_after(t: -5)); |
121 | |
122 | check(testname: "is_null" , testcond: zero_len.is_null()); |
123 | check(testname: "Contains rep (not)" , testcond: !zero_len.contains(point: 20)); |
124 | // a null_period cannot contain any points |
125 | check(testname: "Contains rep" , testcond: !zero_len.contains(point: 3)); |
126 | check(testname: "Contains period (not)" , testcond: !zero_len.contains(other: a_period(5,8))); |
127 | check(testname: "Contains period" , testcond: p1.contains(other: zero_len)); |
128 | check(testname: "Intersects" , testcond: zero_len.intersects(other: p1)); |
129 | check(testname: "Intersects" , testcond: p1.intersects(other: zero_len)); |
130 | check(testname: "Adjacent" , testcond: zero_len.is_adjacent(other: a_period(-10,3))); |
131 | check(testname: "Adjacent" , testcond: a_period(-10,3).is_adjacent(other: zero_len)); |
132 | check(testname: "Intersection" , testcond: (zero_len.intersection(other: p1) == zero_len)); |
133 | check(testname: "Span" , testcond: zero_len.span(other: p2) == a_period(3,30)); |
134 | |
135 | /*** invalid period ***/ |
136 | |
137 | a_period null_per(5,1); |
138 | |
139 | check(testname: "Is Before invalid period (always false)" , testcond: !null_per.is_before(t: 7)); |
140 | check(testname: "Is After invalid period (always false)" , testcond: !null_per.is_after(t: 7)); |
141 | check(testname: "Is Before invalid period (always false)" , testcond: !null_per.is_before(t: -5)); |
142 | check(testname: "Is After invalid period (always false)" , testcond: !null_per.is_after(t: -5)); |
143 | |
144 | check(testname: "is_null" , testcond: null_per.is_null()); |
145 | check(testname: "Contains rep larger (always false)" , testcond: !null_per.contains(point: 20)); |
146 | check(testname: "Contains rep in-between (always false)" , testcond: !null_per.contains(point: 3)); |
147 | check(testname: "Contains period (not)" , testcond: !null_per.contains(other: a_period(7,9))); |
148 | check(testname: "Contains period" , testcond: p1.contains(other: null_per)); |
149 | check(testname: "Intersects" , testcond: null_per.intersects(other: p1)); |
150 | check(testname: "Intersects" , testcond: p1.intersects(other: null_per)); |
151 | check(testname: "Adjacent" , testcond: null_per.is_adjacent(other: a_period(-10,5))); |
152 | check(testname: "Adjacent" , testcond: null_per.is_adjacent(other: a_period(1,10))); |
153 | |
154 | // what should this next one do? |
155 | //check("Intersection", (null_per.intersection(p1) == zero_len)); |
156 | check(testname: "Span" , testcond: null_per.span(other: p3) == a_period(5,81)); |
157 | |
158 | { |
159 | std::cout << std::endl; |
160 | a_period p1x(0, -2); |
161 | check(testname: "First" , testcond: p1x.begin() == 0); |
162 | check(testname: "Last" , testcond: p1x.last() == -3); |
163 | check(testname: "End" , testcond: p1x.end() == -2); |
164 | check(testname: "Length" , testcond: p1x.length() == -2); |
165 | check(testname: "is_null" , testcond: p1x.is_null()); |
166 | } |
167 | { |
168 | std::cout << std::endl; |
169 | a_period p1x(0, -1); |
170 | check(testname: "First" , testcond: p1x.begin() == 0); |
171 | check(testname: "Last" , testcond: p1x.last() == -2); |
172 | check(testname: "End" , testcond: p1x.end() == -1); |
173 | check(testname: "Length" , testcond: p1x.length() == -1); |
174 | check(testname: "is_null" , testcond: p1x.is_null()); |
175 | } |
176 | { |
177 | std::cout << std::endl; |
178 | a_period p1x(0, 0); |
179 | check(testname: "First" , testcond: p1x.begin() == 0); |
180 | check(testname: "Last" , testcond: p1x.last() == -1); |
181 | check(testname: "End" , testcond: p1x.end() == 0); |
182 | check(testname: "Length" , testcond: p1x.length() == 0); |
183 | check(testname: "is_null" , testcond: p1x.is_null()); |
184 | } |
185 | { |
186 | std::cout << std::endl; |
187 | a_period p1x(0, 1); |
188 | check(testname: "First" , testcond: p1x.begin() == 0); |
189 | check(testname: "Last" , testcond: p1x.last() == 0); |
190 | check(testname: "End" , testcond: p1x.end() == 1); |
191 | check(testname: "Length" , testcond: p1x.length() == 1); |
192 | check(testname: "is_null" , testcond: !p1x.is_null()); |
193 | } |
194 | { |
195 | std::cout << std::endl; |
196 | a_period p1x(0, 2); |
197 | check(testname: "First" , testcond: p1x.begin() == 0); |
198 | check(testname: "Last" , testcond: p1x.last() == 1); |
199 | check(testname: "End" , testcond: p1x.end() == 2); |
200 | check(testname: "Length" , testcond: p1x.length() == 2); |
201 | check(testname: "is_null" , testcond: !p1x.is_null()); |
202 | } |
203 | { |
204 | std::cout << std::endl; |
205 | a_period p1x(0, duration_type<int>(-1)); |
206 | check(testname: "First" , testcond: p1x.begin() == 0); |
207 | check(testname: "Last" , testcond: p1x.last() == -2); |
208 | check(testname: "End" , testcond: p1x.end() == -1); |
209 | check(testname: "Length" , testcond: p1x.length() == -1); |
210 | check(testname: "is_null" , testcond: p1x.is_null()); |
211 | } |
212 | { |
213 | std::cout << std::endl; |
214 | a_period p1x(0, duration_type<int>(-2)); |
215 | check(testname: "First" , testcond: p1x.begin() == 0); |
216 | check(testname: "Last" , testcond: p1x.last() == -3); |
217 | check(testname: "End" , testcond: p1x.end() == -2); |
218 | check(testname: "Length" , testcond: p1x.length() == -2); |
219 | check(testname: "is_null" , testcond: p1x.is_null()); |
220 | } |
221 | { |
222 | std::cout << std::endl; |
223 | a_period p1x(0, duration_type<int>(0)); |
224 | check(testname: "First" , testcond: p1x.begin() == 0); |
225 | check(testname: "Last" , testcond: p1x.last() == -1); |
226 | check(testname: "End" , testcond: p1x.end() == 0); |
227 | check(testname: "Length" , testcond: p1x.length() == 0); |
228 | check(testname: "is_null" , testcond: p1x.is_null()); |
229 | } |
230 | { |
231 | std::cout << std::endl; |
232 | a_period p1x(0, duration_type<int>(1)); |
233 | check(testname: "First" , testcond: p1x.begin() == 0); |
234 | check(testname: "Last" , testcond: p1x.last() == 0); |
235 | check(testname: "End" , testcond: p1x.end() == 1); |
236 | check(testname: "Length" , testcond: p1x.length() == 1); |
237 | check(testname: "is_null" , testcond: !p1x.is_null()); |
238 | } |
239 | { |
240 | std::cout << std::endl; |
241 | a_period p1x(0, duration_type<int>(2)); |
242 | check(testname: "First" , testcond: p1x.begin() == 0); |
243 | check(testname: "Last" , testcond: p1x.last() == 1); |
244 | check(testname: "End" , testcond: p1x.end() == 2); |
245 | check(testname: "Length" , testcond: p1x.length() == 2); |
246 | check(testname: "is_null" , testcond: !p1x.is_null()); |
247 | } |
248 | { |
249 | std::cout << std::endl; |
250 | a_period p1x(1,1); // length should be 0 |
251 | a_period p2x(1,2); // length should be 1 |
252 | a_period p3x(1,3); // length should be 2 |
253 | check(testname: "Length p1" , testcond: p1x.length() == 0); |
254 | check(testname: "Length p2" , testcond: p2x.length() == 1); |
255 | check(testname: "Length p3" , testcond: p3x.length() == 2); |
256 | check(testname: "is_null p1 (not)" , testcond: p1x.is_null()); |
257 | check(testname: "is_null p2 (not)" , testcond: !p2x.is_null()); |
258 | } |
259 | |
260 | { |
261 | a_period p1x(1,2); // length should be 1 |
262 | p1x.shift(d: duration_type<int>(1)); |
263 | a_period p2x(2,3); // shifted result |
264 | check(testname: "shift" , testcond: p1x == p2x); |
265 | } |
266 | { |
267 | a_period p1x(5,duration_type<int>(3)); |
268 | a_period p2x(3,10); // expanded result |
269 | p1x.expand(d: duration_type<int>(2)); //from 2000-Jan-01--2000-Jan-04 |
270 | check(testname: "expand" , testcond: p1x == p2x); |
271 | } |
272 | return printTestStats(); |
273 | } |
274 | |