Move a couple of tests to a more appropriate place.
[dcpomatic.git] / test / dcpomatic_time_test.cc
1 /*
2     Copyright (C) 2015-2017 Carl Hetherington <cth@carlh.net>
3
4     This file is part of DCP-o-matic.
5
6     DCP-o-matic is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     DCP-o-matic is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
18
19 */
20
21 /** @file  test/dcpomatic_time_test.cc
22  *  @brief Test Time and TimePeriod classes.
23  *  @ingroup selfcontained
24  */
25
26 #include "lib/dcpomatic_time.h"
27 #include "lib/dcpomatic_time_coalesce.h"
28 #include <boost/test/unit_test.hpp>
29 #include <list>
30 #include <iostream>
31
32 using std::list;
33 using std::cout;
34
35 BOOST_AUTO_TEST_CASE (dcpomatic_time_test)
36 {
37         FrameRateChange frc (24, 48);
38         int j = 0;
39         int k = 0;
40         for (int64_t i = 0; i < 62000; i += 2000) {
41                 DCPTime d (i);
42                 ContentTime c (d, frc);
43                 BOOST_CHECK_EQUAL (c.frames_floor (24.0), j);
44                 ++k;
45                 if (k == 2) {
46                         ++j;
47                         k = 0;
48                 }
49         }
50 }
51
52 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_overlaps_test)
53 {
54         /* Taking times as the start of a sampling interval
55
56            |--|--|--|--|--|--|--|--|--|--|
57            0  1  2  3  4  5  6  7  8  9  |
58            |--|--|--|--|--|--|--|--|--|--|
59
60            <------a----><----b----->
61
62            and saying `from' is the start of the first sampling
63            interval and `to' is the start of the interval after
64            the period... a and b do not overlap.
65         */
66
67         TimePeriod<DCPTime> a (DCPTime (0), DCPTime (4));
68         TimePeriod<DCPTime> b (DCPTime (4), DCPTime (8));
69         BOOST_CHECK (!a.overlap (b));
70
71         /* Some more obvious non-overlaps */
72         a = TimePeriod<DCPTime> (DCPTime (0), DCPTime (4));
73         b = TimePeriod<DCPTime> (DCPTime (5), DCPTime (8));
74         BOOST_CHECK (!a.overlap (b));
75
76         /* Some overlaps */
77         a = TimePeriod<DCPTime> (DCPTime (0), DCPTime (4));
78         b = TimePeriod<DCPTime> (DCPTime (3), DCPTime (8));
79         BOOST_CHECK (a.overlap(b));
80         BOOST_CHECK (a.overlap(b).get() == DCPTimePeriod(DCPTime(3), DCPTime(4)));
81         a = TimePeriod<DCPTime> (DCPTime (1), DCPTime (9));
82         b = TimePeriod<DCPTime> (DCPTime (0), DCPTime (10));
83         BOOST_CHECK (a.overlap(b));
84         BOOST_CHECK (a.overlap(b).get() == DCPTimePeriod(DCPTime(1), DCPTime(9)));
85 }
86
87 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test1)
88 {
89         DCPTimePeriod A (DCPTime (0), DCPTime (106));
90         list<DCPTimePeriod> B;
91         B.push_back (DCPTimePeriod (DCPTime (0), DCPTime (42)));
92         B.push_back (DCPTimePeriod (DCPTime (52), DCPTime (91)));
93         B.push_back (DCPTimePeriod (DCPTime (94), DCPTime (106)));
94         list<DCPTimePeriod> r = subtract (A, B);
95         list<DCPTimePeriod>::const_iterator i = r.begin ();
96         BOOST_REQUIRE (i != r.end ());
97         BOOST_CHECK (i->from == DCPTime (42));
98         BOOST_CHECK (i->to == DCPTime (52));
99         ++i;
100         BOOST_REQUIRE (i != r.end ());
101         BOOST_CHECK (i->from == DCPTime (91));
102         BOOST_CHECK (i->to == DCPTime (94));
103         ++i;
104         BOOST_REQUIRE (i == r.end ());
105 }
106
107 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test2)
108 {
109         DCPTimePeriod A (DCPTime (0), DCPTime (106));
110         list<DCPTimePeriod> B;
111         B.push_back (DCPTimePeriod (DCPTime (14), DCPTime (42)));
112         B.push_back (DCPTimePeriod (DCPTime (52), DCPTime (91)));
113         B.push_back (DCPTimePeriod (DCPTime (94), DCPTime (106)));
114         list<DCPTimePeriod> r = subtract (A, B);
115         list<DCPTimePeriod>::const_iterator i = r.begin ();
116         BOOST_REQUIRE (i != r.end ());
117         BOOST_CHECK (i->from == DCPTime (0));
118         BOOST_CHECK (i->to == DCPTime (14));
119         ++i;
120         BOOST_REQUIRE (i != r.end ());
121         BOOST_CHECK (i->from == DCPTime (42));
122         BOOST_CHECK (i->to == DCPTime (52));
123         ++i;
124         BOOST_REQUIRE (i != r.end ());
125         BOOST_CHECK (i->from == DCPTime (91));
126         BOOST_CHECK (i->to == DCPTime (94));
127         ++i;
128         BOOST_REQUIRE (i == r.end ());
129 }
130
131 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test3)
132 {
133         DCPTimePeriod A (DCPTime (0), DCPTime (106));
134         list<DCPTimePeriod> B;
135         B.push_back (DCPTimePeriod (DCPTime (14), DCPTime (42)));
136         B.push_back (DCPTimePeriod (DCPTime (52), DCPTime (91)));
137         B.push_back (DCPTimePeriod (DCPTime (94), DCPTime (99)));
138         list<DCPTimePeriod> r = subtract (A, B);
139         list<DCPTimePeriod>::const_iterator i = r.begin ();
140         BOOST_REQUIRE (i != r.end ());
141         BOOST_CHECK (i->from == DCPTime (0));
142         BOOST_CHECK (i->to == DCPTime (14));
143         ++i;
144         BOOST_REQUIRE (i != r.end ());
145         BOOST_CHECK (i->from == DCPTime (42));
146         BOOST_CHECK (i->to == DCPTime (52));
147         ++i;
148         BOOST_REQUIRE (i != r.end ());
149         BOOST_CHECK (i->from == DCPTime (91));
150         BOOST_CHECK (i->to == DCPTime (94));
151         ++i;
152         BOOST_REQUIRE (i != r.end ());
153         BOOST_CHECK (i->from == DCPTime (99));
154         BOOST_CHECK (i->to == DCPTime (106));
155         ++i;
156         BOOST_REQUIRE (i == r.end ());
157 }
158
159 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test4)
160 {
161         DCPTimePeriod A (DCPTime (0), DCPTime (106));
162         list<DCPTimePeriod> B;
163         list<DCPTimePeriod> r = subtract (A, B);
164         list<DCPTimePeriod>::const_iterator i = r.begin ();
165         BOOST_REQUIRE (i != r.end ());
166         BOOST_CHECK (i->from == DCPTime (0));
167         BOOST_CHECK (i->to == DCPTime (106));
168         ++i;
169         BOOST_REQUIRE (i == r.end ());
170 }
171
172 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test5)
173 {
174         DCPTimePeriod A (DCPTime (0), DCPTime (106));
175         list<DCPTimePeriod> B;
176         B.push_back (DCPTimePeriod (DCPTime (14), DCPTime (42)));
177         B.push_back (DCPTimePeriod (DCPTime (42), DCPTime (91)));
178         B.push_back (DCPTimePeriod (DCPTime (94), DCPTime (99)));
179         list<DCPTimePeriod> r = subtract (A, B);
180         list<DCPTimePeriod>::const_iterator i = r.begin ();
181         BOOST_REQUIRE (i != r.end ());
182         BOOST_CHECK (i->from == DCPTime (0));
183         BOOST_CHECK (i->to == DCPTime (14));
184         ++i;
185         BOOST_REQUIRE (i != r.end ());
186         BOOST_CHECK (i->from ==DCPTime (91));
187         BOOST_CHECK (i->to == DCPTime (94));
188         ++i;
189         BOOST_REQUIRE (i != r.end ());
190         BOOST_CHECK (i->from == DCPTime (99));
191         BOOST_CHECK (i->to == DCPTime (106));
192         ++i;
193         BOOST_REQUIRE (i == r.end ());
194 }
195
196 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test6)
197 {
198         DCPTimePeriod A (DCPTime (0), DCPTime (106));
199         list<DCPTimePeriod> B;
200         B.push_back (DCPTimePeriod (DCPTime (0), DCPTime (42)));
201         B.push_back (DCPTimePeriod (DCPTime (42), DCPTime (91)));
202         B.push_back (DCPTimePeriod (DCPTime (91), DCPTime (106)));
203         list<DCPTimePeriod> r = subtract (A, B);
204         BOOST_CHECK (r.empty());
205 }
206
207 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test7)
208 {
209         DCPTimePeriod A (DCPTime (228), DCPTime (356));
210         list<DCPTimePeriod> B;
211         B.push_back (DCPTimePeriod (DCPTime (34), DCPTime (162)));
212         list<DCPTimePeriod> r = subtract (A, B);
213         list<DCPTimePeriod>::const_iterator i = r.begin ();
214         BOOST_REQUIRE (i != r.end ());
215         BOOST_CHECK (i->from == DCPTime (228));
216         BOOST_CHECK (i->to == DCPTime (356));
217         ++i;
218         BOOST_REQUIRE (i == r.end ());
219 }
220
221 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test8)
222 {
223         DCPTimePeriod A (DCPTime(0), DCPTime(32000));
224         list<DCPTimePeriod> B;
225         B.push_back (DCPTimePeriod (DCPTime(8000), DCPTime(20000)));
226         B.push_back (DCPTimePeriod (DCPTime(28000), DCPTime(32000)));
227         list<DCPTimePeriod> r = subtract (A, B);
228         list<DCPTimePeriod>::const_iterator i = r.begin ();
229         BOOST_REQUIRE (i != r.end ());
230         BOOST_CHECK (*i == DCPTimePeriod(DCPTime(0), DCPTime(8000)));
231         ++i;
232         BOOST_REQUIRE (i != r.end ());
233         BOOST_CHECK (*i == DCPTimePeriod(DCPTime(20000), DCPTime(28000)));
234         ++i;
235         BOOST_REQUIRE (i == r.end ());
236 }
237
238 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test1)
239 {
240         DCPTimePeriod A (DCPTime(14), DCPTime(29));
241         DCPTimePeriod B (DCPTime(45), DCPTime(91));
242         list<DCPTimePeriod> p;
243         p.push_back (A);
244         p.push_back (B);
245         list<DCPTimePeriod> q = coalesce (p);
246         BOOST_REQUIRE_EQUAL (q.size(), 2);
247         BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(29)));
248         BOOST_CHECK (q.back () == DCPTimePeriod(DCPTime(45), DCPTime(91)));
249 }
250
251 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test2)
252 {
253         DCPTimePeriod A (DCPTime(14), DCPTime(29));
254         DCPTimePeriod B (DCPTime(26), DCPTime(91));
255         list<DCPTimePeriod> p;
256         p.push_back (A);
257         p.push_back (B);
258         list<DCPTimePeriod> q = coalesce (p);
259         BOOST_REQUIRE_EQUAL (q.size(), 1);
260         BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(91)));
261 }
262
263 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test3)
264 {
265         DCPTimePeriod A (DCPTime(14), DCPTime(29));
266         DCPTimePeriod B (DCPTime(29), DCPTime(91));
267         list<DCPTimePeriod> p;
268         p.push_back (A);
269         p.push_back (B);
270         list<DCPTimePeriod> q = coalesce (p);
271         BOOST_REQUIRE_EQUAL (q.size(), 1);
272         BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(91)));
273 }
274
275 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test4)
276 {
277         DCPTimePeriod A (DCPTime(14), DCPTime(29));
278         DCPTimePeriod B (DCPTime(20), DCPTime(91));
279         DCPTimePeriod C (DCPTime(35), DCPTime(106));
280         list<DCPTimePeriod> p;
281         p.push_back (A);
282         p.push_back (B);
283         p.push_back (C);
284         list<DCPTimePeriod> q = coalesce (p);
285         BOOST_REQUIRE_EQUAL (q.size(), 1);
286         BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(106)));
287 }
288
289 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test5)
290 {
291         DCPTimePeriod A (DCPTime(14), DCPTime(29));
292         DCPTimePeriod B (DCPTime(20), DCPTime(91));
293         DCPTimePeriod C (DCPTime(100), DCPTime(106));
294         list<DCPTimePeriod> p;
295         p.push_back (A);
296         p.push_back (B);
297         p.push_back (C);
298         list<DCPTimePeriod> q = coalesce (p);
299         BOOST_REQUIRE_EQUAL (q.size(), 2);
300         BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(91)));
301         BOOST_CHECK (q.back()  == DCPTimePeriod(DCPTime(100), DCPTime(106)));
302 }
303
304 /* Straightforward test of DCPTime::ceil */
305 BOOST_AUTO_TEST_CASE (dcpomatic_time_ceil_test)
306 {
307         BOOST_CHECK_EQUAL (DCPTime(0).ceil(DCPTime::HZ / 2).get(), 0);
308         BOOST_CHECK_EQUAL (DCPTime(1).ceil(DCPTime::HZ / 2).get(), 2);
309         BOOST_CHECK_EQUAL (DCPTime(2).ceil(DCPTime::HZ / 2).get(), 2);
310         BOOST_CHECK_EQUAL (DCPTime(3).ceil(DCPTime::HZ / 2).get(), 4);
311
312         BOOST_CHECK_EQUAL (DCPTime(0).ceil(DCPTime::HZ / 42).get(), 0);
313         BOOST_CHECK_EQUAL (DCPTime(1).ceil(DCPTime::HZ / 42).get(), 42);
314         BOOST_CHECK_EQUAL (DCPTime(42).ceil(DCPTime::HZ / 42).get(), 42);
315         BOOST_CHECK_EQUAL (DCPTime(43).ceil(DCPTime::HZ / 42).get(), 84);
316
317         /* Check that rounding up to non-integer frame rates works */
318         BOOST_CHECK_EQUAL (DCPTime(45312).ceil(29.976).get(), 48038);
319 }
320
321 /* Straightforward test of DCPTime::floor */
322 BOOST_AUTO_TEST_CASE (dcpomatic_time_floor_test)
323 {
324         BOOST_CHECK_EQUAL (DCPTime(0).floor(DCPTime::HZ / 2).get(), 0);
325         BOOST_CHECK_EQUAL (DCPTime(1).floor(DCPTime::HZ / 2).get(), 0);
326         BOOST_CHECK_EQUAL (DCPTime(2).floor(DCPTime::HZ / 2).get(), 2);
327         BOOST_CHECK_EQUAL (DCPTime(3).floor(DCPTime::HZ / 2).get(), 2);
328
329         BOOST_CHECK_EQUAL (DCPTime(0).floor(DCPTime::HZ / 42).get(), 0);
330         BOOST_CHECK_EQUAL (DCPTime(1).floor(DCPTime::HZ / 42).get(), 0);
331         BOOST_CHECK_EQUAL (DCPTime(42).floor(DCPTime::HZ / 42.0).get(), 42);
332         BOOST_CHECK_EQUAL (DCPTime(43).floor(DCPTime::HZ / 42.0).get(), 42);
333
334         /* Check that rounding down to non-integer frame rates works */
335         BOOST_CHECK_EQUAL (DCPTime(45312).floor(29.976).get(), 44836);
336 }