2 Copyright (C) 2013-2015 Carl Hetherington <cth@carlh.net>
4 This file is part of libdcp.
6 libdcp 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.
11 libdcp 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.
16 You should have received a copy of the GNU General Public License
17 along with libdcp. If not, see <http://www.gnu.org/licenses/>.
20 #include <boost/test/unit_test.hpp>
22 #include "exceptions.h"
24 using boost::optional;
26 /** Check that dcp::Time works */
27 BOOST_AUTO_TEST_CASE (dcp_time)
29 /* tcr of 250 makes the editable event length the same as an Interop `tick' */
30 dcp::Time t (977143, 24, 250);
32 BOOST_CHECK_EQUAL (t.e, 73);
33 BOOST_CHECK_EQUAL (t.s, 34);
34 BOOST_CHECK_EQUAL (t.m, 18);
35 BOOST_CHECK_EQUAL (t.h, 11);
36 BOOST_CHECK_EQUAL (t.as_string(dcp::INTEROP), "11:18:34:073");
38 /* Use a tcr of 24 so that the editable event is a frame */
39 dcp::Time a (3, 2, 3, 4, 24);
40 dcp::Time b (2, 3, 4, 5, 24);
43 BOOST_CHECK_EQUAL (r.h, 0);
44 BOOST_CHECK_EQUAL (r.m, 58);
45 BOOST_CHECK_EQUAL (r.s, 58);
46 BOOST_CHECK_EQUAL (r.e, 23);
47 BOOST_CHECK_EQUAL (r.as_string(dcp::INTEROP), "00:58:58:023");
49 /* Different tcr (25) */
50 a = dcp::Time (1, 58, 56, 2, 25);
51 b = dcp::Time (1, 7, 12, 1, 25);
53 BOOST_CHECK_EQUAL (r.h, 3);
54 BOOST_CHECK_EQUAL (r.m, 6);
55 BOOST_CHECK_EQUAL (r.s, 8);
56 BOOST_CHECK_EQUAL (r.e, 3);
57 BOOST_CHECK_EQUAL (r.as_string(dcp::INTEROP), "03:06:08:003");
59 /* Another arbitrary tcr (30) */
60 a = dcp::Time (24, 12, 6, 3, 30);
61 b = dcp::Time (16, 8, 4, 2, 30);
62 BOOST_CHECK_CLOSE (a / b, 1.5, 1e-5);
64 a = dcp::Time (3600 * 24, 24, 250);
65 BOOST_CHECK_EQUAL (a.h, 1);
66 BOOST_CHECK_EQUAL (a.m, 0);
67 BOOST_CHECK_EQUAL (a.s, 0);
68 BOOST_CHECK_EQUAL (a.e, 0);
70 a = dcp::Time (60 * 24, 24, 250);
71 BOOST_CHECK_EQUAL (a.h, 0);
72 BOOST_CHECK_EQUAL (a.m, 1);
73 BOOST_CHECK_EQUAL (a.s, 0);
74 BOOST_CHECK_EQUAL (a.e, 0);
76 /* Check rounding; 3424 is 142.666666666... seconds or 0.166666666... ticks */
77 a = dcp::Time (3424, 24, 250);
78 BOOST_CHECK_EQUAL (a.h, 0);
79 BOOST_CHECK_EQUAL (a.m, 2);
80 BOOST_CHECK_EQUAL (a.s, 22);
81 BOOST_CHECK_EQUAL (a.e, 167);
83 a = dcp::Time (3425, 24, 250);
84 BOOST_CHECK_EQUAL (a.h, 0);
85 BOOST_CHECK_EQUAL (a.m, 2);
86 BOOST_CHECK_EQUAL (a.s, 22);
87 BOOST_CHECK_EQUAL (a.e, 177);
89 /* Check addition of times with different tcrs */
90 a = dcp::Time (0, 0, 0, 3, 24);
91 b = dcp::Time (0, 0, 0, 4, 48);
93 BOOST_CHECK_EQUAL (r, dcp::Time (0, 0, 0, 240, 1152));
95 /* Check rounding on conversion from seconds */
96 BOOST_CHECK_EQUAL (dcp::Time (80.990, 1000), dcp::Time (0, 1, 20, 990, 1000));
99 a = dcp::Time (1, 58, 56, 2, 25);
100 BOOST_CHECK_EQUAL (a.rebase (250), dcp::Time (1, 58, 56, 20, 250));
101 b = dcp::Time (9, 12, 41, 17, 99);
102 BOOST_CHECK_EQUAL (b.rebase (250), dcp::Time (9, 12, 41, 42, 250));
103 /* We must round down in rebase() */
104 a = dcp::Time (0, 2, 57, 999, 1000);
105 BOOST_CHECK_EQUAL (a.rebase (250), dcp::Time (0, 2, 57, 249, 250));
107 /* Check some allowed constructions from string */
110 a = dcp::Time ("01:23:45:123", optional<int>());
111 BOOST_CHECK_EQUAL (a, dcp::Time (1, 23, 45, 123, 250));
113 a = dcp::Time ("01:23:45.123", optional<int>());
114 BOOST_CHECK_EQUAL (a, dcp::Time (1, 23, 45, 123, 1000));
116 a = dcp::Time ("01:23:45:12", 250);
117 BOOST_CHECK_EQUAL (a, dcp::Time (1, 23, 45, 12, 250));
119 /* Check some disallowed constructions from string */
120 BOOST_CHECK_THROW (dcp::Time ("01:23:45:1234", optional<int>()), dcp::DCPReadError);
121 BOOST_CHECK_THROW (dcp::Time ("01:23:45:1234:66", optional<int>()), dcp::DCPReadError);
122 BOOST_CHECK_THROW (dcp::Time ("01:23:45:", optional<int>()), dcp::DCPReadError);
123 BOOST_CHECK_THROW (dcp::Time ("01:23::123", optional<int>()), dcp::DCPReadError);
124 BOOST_CHECK_THROW (dcp::Time ("01::45:123", optional<int>()), dcp::DCPReadError);
125 BOOST_CHECK_THROW (dcp::Time (":23:45:123", optional<int>()), dcp::DCPReadError);
126 BOOST_CHECK_THROW (dcp::Time ("01:23:45.1234", optional<int>()), dcp::DCPReadError);
127 BOOST_CHECK_THROW (dcp::Time ("01:23:45.1234.66", optional<int>()), dcp::DCPReadError);
128 BOOST_CHECK_THROW (dcp::Time ("01:23:45.", optional<int>()), dcp::DCPReadError);
129 BOOST_CHECK_THROW (dcp::Time ("01:23:.123", optional<int>()), dcp::DCPReadError);
130 BOOST_CHECK_THROW (dcp::Time ("01::45.123", optional<int>()), dcp::DCPReadError);
131 BOOST_CHECK_THROW (dcp::Time (":23:45.123", optional<int>()), dcp::DCPReadError);
132 BOOST_CHECK_THROW (dcp::Time ("01:23:45:123", 250), dcp::DCPReadError);
133 BOOST_CHECK_THROW (dcp::Time ("01:23:45:123:66", 250), dcp::DCPReadError);
134 BOOST_CHECK_THROW (dcp::Time ("01:23:45:", 250), dcp::DCPReadError);
135 BOOST_CHECK_THROW (dcp::Time ("01:23::123", 250), dcp::DCPReadError);
136 BOOST_CHECK_THROW (dcp::Time ("01::45:123", 250), dcp::DCPReadError);
137 BOOST_CHECK_THROW (dcp::Time (":23:45:123", 250), dcp::DCPReadError);