97ac25374da8a135e3e6c7f38e46c099f93749f3
[dcpomatic.git] / test / create_cli_test.cc
1 /*
2     Copyright (C) 2019-2021 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 #include "lib/create_cli.h"
22 #include "lib/ratio.h"
23 #include "lib/dcp_content_type.h"
24 #include "test.h"
25 #include <boost/test/unit_test.hpp>
26 #include <boost/tokenizer.hpp>
27 #include <boost/algorithm/string/predicate.hpp>
28 #include <iostream>
29
30 using std::string;
31
32 static CreateCLI
33 run (string cmd)
34 {
35         /* This approximates the logic which splits command lines up into argc/argv */
36
37         boost::escaped_list_separator<char> els ("", " ", "\"\'");
38         boost::tokenizer<boost::escaped_list_separator<char> > tok (cmd, els);
39
40         std::vector<char*> argv(256);
41         int argc = 0;
42
43         for (boost::tokenizer<boost::escaped_list_separator<char> >::iterator i = tok.begin(); i != tok.end(); ++i) {
44                 argv[argc++] = strdup (i->c_str());
45         }
46
47         CreateCLI cc (argc, argv.data());
48
49         for (int i = 0; i < argc; ++i) {
50                 free (argv[i]);
51         }
52
53         return cc;
54 }
55
56 BOOST_AUTO_TEST_CASE (create_cli_test)
57 {
58         CreateCLI cc = run ("dcpomatic2_create --version");
59         BOOST_CHECK (!cc.error);
60         BOOST_CHECK (cc.version);
61
62         cc = run ("dcpomatic2_create --versionX");
63         BOOST_REQUIRE (cc.error);
64         BOOST_CHECK (boost::algorithm::starts_with(*cc.error, "dcpomatic2_create: unrecognised option '--versionX'"));
65
66         cc = run ("dcpomatic2_create --help");
67         BOOST_REQUIRE (cc.error);
68
69         cc = run ("dcpomatic2_create -h");
70         BOOST_REQUIRE (cc.error);
71
72         cc = run ("dcpomatic2_create x --name frobozz --template bar");
73         BOOST_CHECK (!cc.error);
74         BOOST_CHECK_EQUAL (cc.name, "frobozz");
75         BOOST_REQUIRE (cc.template_name);
76         BOOST_CHECK_EQUAL (*cc.template_name, "bar");
77
78         cc = run ("dcpomatic2_create x --dcp-content-type FTR");
79         BOOST_CHECK (!cc.error);
80         BOOST_CHECK_EQUAL (cc.dcp_content_type, DCPContentType::from_isdcf_name("FTR"));
81
82         cc = run ("dcpomatic2_create x --dcp-frame-rate 30");
83         BOOST_CHECK (!cc.error);
84         BOOST_REQUIRE (cc.dcp_frame_rate);
85         BOOST_CHECK_EQUAL (*cc.dcp_frame_rate, 30);
86
87         cc = run ("dcpomatic2_create x --container-ratio 185");
88         BOOST_CHECK (!cc.error);
89         BOOST_CHECK_EQUAL (cc.container_ratio, Ratio::from_id("185"));
90
91         cc = run ("dcpomatic2_create x --container-ratio XXX");
92         BOOST_CHECK (cc.error);
93
94         cc = run ("dcpomatic2_create x --still-length 42");
95         BOOST_CHECK (!cc.error);
96         BOOST_CHECK_EQUAL (cc.still_length, 42);
97
98         cc = run ("dcpomatic2_create x --standard SMPTE");
99         BOOST_CHECK (!cc.error);
100         BOOST_CHECK_EQUAL (cc.standard, dcp::Standard::SMPTE);
101
102         cc = run ("dcpomatic2_create x --standard interop");
103         BOOST_CHECK (!cc.error);
104         BOOST_CHECK_EQUAL (cc.standard, dcp::Standard::INTEROP);
105
106         cc = run ("dcpomatic2_create x --standard SMPTEX");
107         BOOST_CHECK (cc.error);
108
109         cc = run ("dcpomatic2_create x --config foo/bar");
110         BOOST_CHECK (!cc.error);
111         BOOST_REQUIRE (cc.config_dir);
112         BOOST_CHECK_EQUAL (*cc.config_dir, "foo/bar");
113
114         cc = run ("dcpomatic2_create x --output fred/jim");
115         BOOST_CHECK (!cc.error);
116         BOOST_REQUIRE (cc.output_dir);
117         BOOST_CHECK_EQUAL (*cc.output_dir, "fred/jim");
118
119         cc = run ("dcpomatic2_create x --outputX fred/jim");
120         BOOST_CHECK (cc.error);
121
122         cc = run ("dcpomatic2_create --config foo/bar --still-length 42 --output flaps fred jim sheila");
123         BOOST_CHECK (!cc.error);
124         BOOST_REQUIRE (cc.config_dir);
125         BOOST_CHECK_EQUAL (*cc.config_dir, "foo/bar");
126         BOOST_CHECK_EQUAL (cc.still_length, 42);
127         BOOST_REQUIRE (cc.output_dir);
128         BOOST_CHECK_EQUAL (*cc.output_dir, "flaps");
129         BOOST_REQUIRE_EQUAL (cc.content.size(), 3U);
130         BOOST_CHECK_EQUAL (cc.content[0].path, "fred");
131         BOOST_CHECK_EQUAL (cc.content[0].frame_type, VideoFrameType::TWO_D);
132         BOOST_CHECK_EQUAL (cc.content[1].path, "jim");
133         BOOST_CHECK_EQUAL (cc.content[1].frame_type, VideoFrameType::TWO_D);
134         BOOST_CHECK_EQUAL (cc.content[2].path, "sheila");
135         BOOST_CHECK_EQUAL (cc.content[2].frame_type, VideoFrameType::TWO_D);
136
137         cc = run ("dcpomatic2_create --left-eye left.mp4 --right-eye right.mp4");
138         BOOST_REQUIRE_EQUAL (cc.content.size(), 2U);
139         BOOST_CHECK_EQUAL (cc.content[0].path, "left.mp4");
140         BOOST_CHECK_EQUAL (cc.content[0].frame_type, VideoFrameType::THREE_D_LEFT);
141         BOOST_CHECK_EQUAL (cc.content[1].path, "right.mp4");
142         BOOST_CHECK_EQUAL (cc.content[1].frame_type, VideoFrameType::THREE_D_RIGHT);
143         BOOST_CHECK_EQUAL (cc.fourk, false);
144
145         cc = run ("dcpomatic2_create --twok foo.mp4");
146         BOOST_REQUIRE_EQUAL (cc.content.size(), 1U);
147         BOOST_CHECK_EQUAL (cc.content[0].path, "foo.mp4");
148         BOOST_CHECK_EQUAL (cc.twok, true);
149         BOOST_CHECK (!cc.error);
150
151         cc = run ("dcpomatic2_create --fourk foo.mp4");
152         BOOST_REQUIRE_EQUAL (cc.content.size(), 1U);
153         BOOST_CHECK_EQUAL (cc.content[0].path, "foo.mp4");
154         BOOST_CHECK_EQUAL (cc.fourk, true);
155         BOOST_CHECK (!cc.error);
156
157         cc = run ("dcpomatic2_create --j2k-bandwidth 120 foo.mp4");
158         BOOST_REQUIRE_EQUAL (cc.content.size(), 1U);
159         BOOST_CHECK_EQUAL (cc.content[0].path, "foo.mp4");
160         BOOST_REQUIRE (cc.j2k_bandwidth);
161         BOOST_CHECK_EQUAL (*cc.j2k_bandwidth, 120000000);
162         BOOST_CHECK (!cc.error);
163
164         cc = run ("dcpomatic2_create --channel L fred.wav --channel R jim.wav sheila.wav");
165         BOOST_REQUIRE_EQUAL (cc.content.size(), 3U);
166         BOOST_CHECK_EQUAL (cc.content[0].path, "fred.wav");
167         BOOST_CHECK (cc.content[0].channel);
168         BOOST_CHECK (*cc.content[0].channel == dcp::Channel::LEFT);
169         BOOST_CHECK_EQUAL (cc.content[1].path, "jim.wav");
170         BOOST_CHECK (cc.content[1].channel);
171         BOOST_CHECK (*cc.content[1].channel == dcp::Channel::RIGHT);
172         BOOST_CHECK_EQUAL (cc.content[2].path, "sheila.wav");
173         BOOST_CHECK (!cc.content[2].channel);
174
175         cc = run ("dcpomatic2_create --channel foo fred.wav");
176         BOOST_REQUIRE (cc.error);
177         BOOST_CHECK (boost::algorithm::starts_with(*cc.error, "dcpomatic2_create: foo is not valid for --channel"));
178
179         cc = run ("dcpomatic2_create fred.wav --gain -6 jim.wav --gain 2 sheila.wav");
180         BOOST_REQUIRE_EQUAL (cc.content.size(), 3U);
181         BOOST_CHECK_EQUAL (cc.content[0].path, "fred.wav");
182         BOOST_CHECK (!cc.content[0].gain);
183         BOOST_CHECK_EQUAL (cc.content[1].path, "jim.wav");
184         BOOST_CHECK_CLOSE (*cc.content[1].gain, -6, 0.001);
185         BOOST_CHECK_EQUAL (cc.content[2].path, "sheila.wav");
186         BOOST_CHECK_CLOSE (*cc.content[2].gain, 2, 0.001);
187 }