C++11 tidying.
[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
22 /** @file  test/dcpomatic_time_test.cc
23  *  @brief Test dcpomatic::Time and dcpomatic::TimePeriod classes.
24  *  @ingroup selfcontained
25  */
26
27
28 #include "lib/dcpomatic_time.h"
29 #include "lib/dcpomatic_time_coalesce.h"
30 #include <boost/test/unit_test.hpp>
31 #include <iostream>
32 #include <list>
33
34
35 using std::cout;
36 using std::list;
37 using namespace dcpomatic;
38
39
40 BOOST_AUTO_TEST_CASE (dcpomatic_time_test)
41 {
42         FrameRateChange frc (24, 48);
43         int j = 0;
44         int k = 0;
45         for (int64_t i = 0; i < 62000; i += 2000) {
46                 DCPTime d (i);
47                 ContentTime c (d, frc);
48                 BOOST_CHECK_EQUAL (c.frames_floor (24.0), j);
49                 ++k;
50                 if (k == 2) {
51                         ++j;
52                         k = 0;
53                 }
54         }
55 }
56
57
58 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_overlaps_test)
59 {
60         /* Taking times as the start of a sampling interval
61
62            |--|--|--|--|--|--|--|--|--|--|
63            0  1  2  3  4  5  6  7  8  9  |
64            |--|--|--|--|--|--|--|--|--|--|
65
66            <------a----><----b----->
67
68            and saying `from' is the start of the first sampling
69            interval and `to' is the start of the interval after
70            the period... a and b do not overlap.
71         */
72
73         TimePeriod<DCPTime> a (DCPTime(0), DCPTime(4));
74         TimePeriod<DCPTime> b (DCPTime (4), DCPTime (8));
75         BOOST_CHECK (!a.overlap (b));
76
77         /* Some more obvious non-overlaps */
78         a = TimePeriod<DCPTime> (DCPTime (0), DCPTime (4));
79         b = TimePeriod<DCPTime> (DCPTime (5), DCPTime (8));
80         BOOST_CHECK (!a.overlap (b));
81
82         /* Some overlaps */
83         a = TimePeriod<DCPTime> (DCPTime (0), DCPTime (4));
84         b = TimePeriod<DCPTime> (DCPTime (3), DCPTime (8));
85         BOOST_CHECK (a.overlap(b));
86         BOOST_CHECK (a.overlap(b).get() == DCPTimePeriod(DCPTime(3), DCPTime(4)));
87         a = TimePeriod<DCPTime> (DCPTime (1), DCPTime (9));
88         b = TimePeriod<DCPTime> (DCPTime (0), DCPTime (10));
89         BOOST_CHECK (a.overlap(b));
90         BOOST_CHECK (a.overlap(b).get() == DCPTimePeriod(DCPTime(1), DCPTime(9)));
91 }
92
93
94 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test1)
95 {
96         DCPTimePeriod A (DCPTime (0), DCPTime (106));
97         list<DCPTimePeriod> B = {
98                 DCPTimePeriod(DCPTime(0), DCPTime(42)),
99                 DCPTimePeriod(DCPTime(52), DCPTime(91)),
100                 DCPTimePeriod(DCPTime(94), DCPTime(106))
101         };
102         auto r = subtract (A, B);
103         auto i = r.begin ();
104         BOOST_REQUIRE (i != r.end ());
105         BOOST_CHECK (i->from == DCPTime (42));
106         BOOST_CHECK (i->to == DCPTime (52));
107         ++i;
108         BOOST_REQUIRE (i != r.end ());
109         BOOST_CHECK (i->from == DCPTime (91));
110         BOOST_CHECK (i->to == DCPTime (94));
111         ++i;
112         BOOST_REQUIRE (i == r.end ());
113 }
114
115
116 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test2)
117 {
118         DCPTimePeriod A (DCPTime (0), DCPTime (106));
119         list<DCPTimePeriod> B = {
120                 DCPTimePeriod(DCPTime(14), DCPTime(42)),
121                 DCPTimePeriod(DCPTime(52), DCPTime(91)),
122                 DCPTimePeriod(DCPTime(94), DCPTime(106))
123         };
124         auto r = subtract (A, B);
125         auto i = r.begin ();
126         BOOST_REQUIRE (i != r.end ());
127         BOOST_CHECK (i->from == DCPTime (0));
128         BOOST_CHECK (i->to == DCPTime (14));
129         ++i;
130         BOOST_REQUIRE (i != r.end ());
131         BOOST_CHECK (i->from == DCPTime (42));
132         BOOST_CHECK (i->to == DCPTime (52));
133         ++i;
134         BOOST_REQUIRE (i != r.end ());
135         BOOST_CHECK (i->from == DCPTime (91));
136         BOOST_CHECK (i->to == DCPTime (94));
137         ++i;
138         BOOST_REQUIRE (i == r.end ());
139 }
140
141
142 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test3)
143 {
144         DCPTimePeriod A (DCPTime (0), DCPTime (106));
145         list<DCPTimePeriod> B = {
146                 DCPTimePeriod(DCPTime(14), DCPTime(42)),
147                 DCPTimePeriod(DCPTime(52), DCPTime(91)),
148                 DCPTimePeriod(DCPTime(94), DCPTime(99))
149         };
150         auto r = subtract (A, B);
151         auto i = r.begin ();
152         BOOST_REQUIRE (i != r.end ());
153         BOOST_CHECK (i->from == DCPTime (0));
154         BOOST_CHECK (i->to == DCPTime (14));
155         ++i;
156         BOOST_REQUIRE (i != r.end ());
157         BOOST_CHECK (i->from == DCPTime (42));
158         BOOST_CHECK (i->to == DCPTime (52));
159         ++i;
160         BOOST_REQUIRE (i != r.end ());
161         BOOST_CHECK (i->from == DCPTime (91));
162         BOOST_CHECK (i->to == DCPTime (94));
163         ++i;
164         BOOST_REQUIRE (i != r.end ());
165         BOOST_CHECK (i->from == DCPTime (99));
166         BOOST_CHECK (i->to == DCPTime (106));
167         ++i;
168         BOOST_REQUIRE (i == r.end ());
169 }
170
171
172 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test4)
173 {
174         DCPTimePeriod A (DCPTime (0), DCPTime (106));
175         list<DCPTimePeriod> B;
176         auto r = subtract (A, B);
177         auto i = r.begin ();
178         BOOST_REQUIRE (i != r.end ());
179         BOOST_CHECK (i->from == DCPTime (0));
180         BOOST_CHECK (i->to == DCPTime (106));
181         ++i;
182         BOOST_REQUIRE (i == r.end ());
183 }
184
185
186 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test5)
187 {
188         DCPTimePeriod A (DCPTime (0), DCPTime (106));
189         list<DCPTimePeriod> B = {
190                 DCPTimePeriod(DCPTime(14), DCPTime(42)),
191                 DCPTimePeriod(DCPTime(42), DCPTime(91)),
192                 DCPTimePeriod(DCPTime(94), DCPTime(99))
193         };
194         auto r = subtract (A, B);
195         auto i = r.begin ();
196         BOOST_REQUIRE (i != r.end ());
197         BOOST_CHECK (i->from == DCPTime (0));
198         BOOST_CHECK (i->to == DCPTime (14));
199         ++i;
200         BOOST_REQUIRE (i != r.end ());
201         BOOST_CHECK (i->from ==DCPTime (91));
202         BOOST_CHECK (i->to == DCPTime (94));
203         ++i;
204         BOOST_REQUIRE (i != r.end ());
205         BOOST_CHECK (i->from == DCPTime (99));
206         BOOST_CHECK (i->to == DCPTime (106));
207         ++i;
208         BOOST_REQUIRE (i == r.end ());
209 }
210
211
212 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test6)
213 {
214         DCPTimePeriod A (DCPTime (0), DCPTime (106));
215         list<DCPTimePeriod> B = {
216                 DCPTimePeriod(DCPTime(0), DCPTime(42)),
217                 DCPTimePeriod(DCPTime(42), DCPTime(91)),
218                 DCPTimePeriod(DCPTime(91), DCPTime(106))
219         };
220         auto r = subtract (A, B);
221         BOOST_CHECK (r.empty());
222 }
223
224
225 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test7)
226 {
227         DCPTimePeriod A (DCPTime (228), DCPTime (356));
228         list<DCPTimePeriod> B = {
229                 DCPTimePeriod(DCPTime(34), DCPTime(162))
230         };
231         auto r = subtract (A, B);
232         auto i = r.begin ();
233         BOOST_REQUIRE (i != r.end ());
234         BOOST_CHECK (i->from == DCPTime (228));
235         BOOST_CHECK (i->to == DCPTime (356));
236         ++i;
237         BOOST_REQUIRE (i == r.end ());
238 }
239
240
241 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test8)
242 {
243         DCPTimePeriod A (DCPTime(0), DCPTime(32000));
244         list<DCPTimePeriod> B = {
245                 DCPTimePeriod(DCPTime(8000), DCPTime(20000)),
246                 DCPTimePeriod(DCPTime(28000), DCPTime(32000))
247         };
248         auto r = subtract (A, B);
249         auto i = r.begin ();
250         BOOST_REQUIRE (i != r.end ());
251         BOOST_CHECK (*i == DCPTimePeriod(DCPTime(0), DCPTime(8000)));
252         ++i;
253         BOOST_REQUIRE (i != r.end ());
254         BOOST_CHECK (*i == DCPTimePeriod(DCPTime(20000), DCPTime(28000)));
255         ++i;
256         BOOST_REQUIRE (i == r.end ());
257 }
258
259
260 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test1)
261 {
262         DCPTimePeriod A (DCPTime(14), DCPTime(29));
263         DCPTimePeriod B (DCPTime(45), DCPTime(91));
264         list<DCPTimePeriod> p = { A, B };
265         auto q = coalesce (p);
266         BOOST_REQUIRE_EQUAL (q.size(), 2U);
267         BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(29)));
268         BOOST_CHECK (q.back () == DCPTimePeriod(DCPTime(45), DCPTime(91)));
269 }
270
271
272 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test2)
273 {
274         DCPTimePeriod A (DCPTime(14), DCPTime(29));
275         DCPTimePeriod B (DCPTime(26), DCPTime(91));
276         list<DCPTimePeriod> p = { A, B };
277         auto q = coalesce (p);
278         BOOST_REQUIRE_EQUAL (q.size(), 1U);
279         BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(91)));
280 }
281
282
283 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test3)
284 {
285         DCPTimePeriod A (DCPTime(14), DCPTime(29));
286         DCPTimePeriod B (DCPTime(29), DCPTime(91));
287         list<DCPTimePeriod> p = { A, B };
288         auto q = coalesce (p);
289         BOOST_REQUIRE_EQUAL (q.size(), 1U);
290         BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(91)));
291 }
292
293
294 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test4)
295 {
296         DCPTimePeriod A (DCPTime(14), DCPTime(29));
297         DCPTimePeriod B (DCPTime(20), DCPTime(91));
298         DCPTimePeriod C (DCPTime(35), DCPTime(106));
299         list<DCPTimePeriod> p = { A, B, C };
300         auto q = coalesce (p);
301         BOOST_REQUIRE_EQUAL (q.size(), 1U);
302         BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(106)));
303 }
304
305
306 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test5)
307 {
308         DCPTimePeriod A (DCPTime(14), DCPTime(29));
309         DCPTimePeriod B (DCPTime(20), DCPTime(91));
310         DCPTimePeriod C (DCPTime(100), DCPTime(106));
311         list<DCPTimePeriod> p = { A, B, C };
312         auto q = coalesce (p);
313         BOOST_REQUIRE_EQUAL (q.size(), 2U);
314         BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(91)));
315         BOOST_CHECK (q.back()  == DCPTimePeriod(DCPTime(100), DCPTime(106)));
316 }
317
318
319 BOOST_AUTO_TEST_CASE (test_coalesce_with_overlapping_periods)
320 {
321         DCPTimePeriod A (DCPTime(0), DCPTime(10));
322         DCPTimePeriod B (DCPTime(2), DCPTime(8));
323         list<DCPTimePeriod> p = { A, B };
324         auto q = coalesce(p);
325         BOOST_REQUIRE_EQUAL (q.size(), 1U);
326         BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(0), DCPTime(10)));
327 }
328
329
330 /* Straightforward test of DCPTime::ceil */
331 BOOST_AUTO_TEST_CASE (dcpomatic_time_ceil_test)
332 {
333         BOOST_CHECK_EQUAL (DCPTime(0).ceil(DCPTime::HZ / 2).get(), 0);
334         BOOST_CHECK_EQUAL (DCPTime(1).ceil(DCPTime::HZ / 2).get(), 2);
335         BOOST_CHECK_EQUAL (DCPTime(2).ceil(DCPTime::HZ / 2).get(), 2);
336         BOOST_CHECK_EQUAL (DCPTime(3).ceil(DCPTime::HZ / 2).get(), 4);
337
338         BOOST_CHECK_EQUAL (DCPTime(0).ceil(DCPTime::HZ / 42).get(), 0);
339         BOOST_CHECK_EQUAL (DCPTime(1).ceil(DCPTime::HZ / 42).get(), 42);
340         BOOST_CHECK_EQUAL (DCPTime(42).ceil(DCPTime::HZ / 42).get(), 42);
341         BOOST_CHECK_EQUAL (DCPTime(43).ceil(DCPTime::HZ / 42).get(), 84);
342
343         /* Check that rounding up to non-integer frame rates works */
344         BOOST_CHECK_EQUAL (DCPTime(45312).ceil(29.976).get(), 48038);
345
346         /* Check another tricky case that used to fail */
347         BOOST_CHECK_EQUAL (DCPTime(212256039).ceil(23.976).get(), 212256256);
348 }
349
350
351 /* Straightforward test of DCPTime::floor */
352 BOOST_AUTO_TEST_CASE (dcpomatic_time_floor_test)
353 {
354         BOOST_CHECK_EQUAL (DCPTime(0).floor(DCPTime::HZ / 2).get(), 0);
355         BOOST_CHECK_EQUAL (DCPTime(1).floor(DCPTime::HZ / 2).get(), 0);
356         BOOST_CHECK_EQUAL (DCPTime(2).floor(DCPTime::HZ / 2).get(), 2);
357         BOOST_CHECK_EQUAL (DCPTime(3).floor(DCPTime::HZ / 2).get(), 2);
358
359         BOOST_CHECK_EQUAL (DCPTime(0).floor(DCPTime::HZ / 42).get(), 0);
360         BOOST_CHECK_EQUAL (DCPTime(1).floor(DCPTime::HZ / 42).get(), 0);
361         BOOST_CHECK_EQUAL (DCPTime(42).floor(DCPTime::HZ / 42.0).get(), 42);
362         BOOST_CHECK_EQUAL (DCPTime(43).floor(DCPTime::HZ / 42.0).get(), 42);
363
364         /* Check that rounding down to non-integer frame rates works */
365         BOOST_CHECK_EQUAL (DCPTime(45312).floor(29.976).get(), 44836);
366 }