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");
58 BOOST_CHECK_EQUAL (r.as_string(dcp::SMPTE), "03:06:08:03");
60 /* Another arbitrary tcr (30) */
61 a = dcp::Time (24, 12, 6, 3, 30);
62 b = dcp::Time (16, 8, 4, 2, 30);
63 BOOST_CHECK_CLOSE (a / b, 1.5, 1e-5);
65 a = dcp::Time (3600 * 24, 24, 250);
66 BOOST_CHECK_EQUAL (a.h, 1);
67 BOOST_CHECK_EQUAL (a.m, 0);
68 BOOST_CHECK_EQUAL (a.s, 0);
69 BOOST_CHECK_EQUAL (a.e, 0);
71 a = dcp::Time (60 * 24, 24, 250);
72 BOOST_CHECK_EQUAL (a.h, 0);
73 BOOST_CHECK_EQUAL (a.m, 1);
74 BOOST_CHECK_EQUAL (a.s, 0);
75 BOOST_CHECK_EQUAL (a.e, 0);
77 /* Check rounding; 3424 is 142.666666666... seconds or 0.166666666... ticks */
78 a = dcp::Time (3424, 24, 250);
79 BOOST_CHECK_EQUAL (a.h, 0);
80 BOOST_CHECK_EQUAL (a.m, 2);
81 BOOST_CHECK_EQUAL (a.s, 22);
82 BOOST_CHECK_EQUAL (a.e, 167);
84 a = dcp::Time (3425, 24, 250);
85 BOOST_CHECK_EQUAL (a.h, 0);
86 BOOST_CHECK_EQUAL (a.m, 2);
87 BOOST_CHECK_EQUAL (a.s, 22);
88 BOOST_CHECK_EQUAL (a.e, 177);
90 /* Check addition of times with different tcrs */
91 a = dcp::Time (0, 0, 0, 3, 24);
92 b = dcp::Time (0, 0, 0, 4, 48);
94 BOOST_CHECK_EQUAL (r, dcp::Time (0, 0, 0, 240, 1152));
96 /* Check rounding on conversion from seconds */
97 BOOST_CHECK_EQUAL (dcp::Time (80.990, 1000), dcp::Time (0, 1, 20, 990, 1000));
100 a = dcp::Time (1, 58, 56, 2, 25);
101 BOOST_CHECK_EQUAL (a.rebase (250), dcp::Time (1, 58, 56, 20, 250));
102 b = dcp::Time (9, 12, 41, 17, 99);
103 BOOST_CHECK_EQUAL (b.rebase (250), dcp::Time (9, 12, 41, 42, 250));
104 /* We must round down in rebase() */
105 a = dcp::Time (0, 2, 57, 999, 1000);
106 BOOST_CHECK_EQUAL (a.rebase (250), dcp::Time (0, 2, 57, 249, 250));
108 /* Check some allowed constructions from string */
111 a = dcp::Time ("01:23:45:123", optional<int>());
112 BOOST_CHECK_EQUAL (a, dcp::Time (1, 23, 45, 123, 250));
114 a = dcp::Time ("01:23:45.123", optional<int>());
115 BOOST_CHECK_EQUAL (a, dcp::Time (1, 23, 45, 123, 1000));
117 a = dcp::Time ("01:23:45:12", 250);
118 BOOST_CHECK_EQUAL (a, dcp::Time (1, 23, 45, 12, 250));
120 /* Check some disallowed constructions from string */
121 BOOST_CHECK_THROW (dcp::Time ("01:23:45:1234", optional<int>()), dcp::DCPReadError);
122 BOOST_CHECK_THROW (dcp::Time ("01:23:45:1234:66", optional<int>()), dcp::DCPReadError);
123 BOOST_CHECK_THROW (dcp::Time ("01:23:45:", optional<int>()), dcp::DCPReadError);
124 BOOST_CHECK_THROW (dcp::Time ("01:23::123", optional<int>()), dcp::DCPReadError);
125 BOOST_CHECK_THROW (dcp::Time ("01::45:123", optional<int>()), dcp::DCPReadError);
126 BOOST_CHECK_THROW (dcp::Time (":23:45:123", optional<int>()), dcp::DCPReadError);
127 BOOST_CHECK_THROW (dcp::Time ("01:23:45.1234", optional<int>()), dcp::DCPReadError);
128 BOOST_CHECK_THROW (dcp::Time ("01:23:45.1234.66", optional<int>()), dcp::DCPReadError);
129 BOOST_CHECK_THROW (dcp::Time ("01:23:45.", optional<int>()), dcp::DCPReadError);
130 BOOST_CHECK_THROW (dcp::Time ("01:23:.123", optional<int>()), dcp::DCPReadError);
131 BOOST_CHECK_THROW (dcp::Time ("01::45.123", optional<int>()), dcp::DCPReadError);
132 BOOST_CHECK_THROW (dcp::Time (":23:45.123", optional<int>()), dcp::DCPReadError);
133 BOOST_CHECK_THROW (dcp::Time ("01:23:45:123", 250), dcp::DCPReadError);
134 BOOST_CHECK_THROW (dcp::Time ("01:23:45:123:66", 250), dcp::DCPReadError);
135 BOOST_CHECK_THROW (dcp::Time ("01:23:45:", 250), dcp::DCPReadError);
136 BOOST_CHECK_THROW (dcp::Time ("01:23::123", 250), dcp::DCPReadError);
137 BOOST_CHECK_THROW (dcp::Time ("01::45:123", 250), dcp::DCPReadError);
138 BOOST_CHECK_THROW (dcp::Time (":23:45:123", 250), dcp::DCPReadError);