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 */
15template<class int_type>
16class 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()"
28template<class int_type>
29inline
30std::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
35template<class int_type>
36inline
37int_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
42template<class int_type>
43inline
44int_type operator-(int i, duration_type<int_type> dt){
45 return i - dt.get_rep();
46}
47
48
49int 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

source code of boost/libs/date_time/test/testgeneric_period.cpp