Add --channel option to dcpomatic_create.
[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         char** argv = new char*[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);
48
49         for (int i = 0; i < argc; ++i) {
50                 free (argv[i]);
51         }
52
53         delete[] argv;
54
55         return cc;
56 }
57
58 BOOST_AUTO_TEST_CASE (create_cli_test)
59 {
60         CreateCLI cc = run ("dcpomatic2_create --version");
61         BOOST_CHECK (!cc.error);
62         BOOST_CHECK (cc.version);
63
64         cc = run ("dcpomatic2_create --versionX");
65         BOOST_REQUIRE (cc.error);
66         BOOST_CHECK (boost::algorithm::starts_with(*cc.error, "dcpomatic2_create: unrecognised option '--versionX'"));
67
68         cc = run ("dcpomatic2_create --help");
69         BOOST_REQUIRE (cc.error);
70
71         cc = run ("dcpomatic2_create -h");
72         BOOST_REQUIRE (cc.error);
73
74         cc = run ("dcpomatic2_create x --name frobozz --template bar");
75         BOOST_CHECK (!cc.error);
76         BOOST_CHECK_EQUAL (cc.name, "frobozz");
77         BOOST_REQUIRE (cc.template_name);
78         BOOST_CHECK_EQUAL (*cc.template_name, "bar");
79
80         cc = run ("dcpomatic2_create x --dcp-content-type FTR");
81         BOOST_CHECK (!cc.error);
82         BOOST_CHECK_EQUAL (cc.dcp_content_type, DCPContentType::from_isdcf_name("FTR"));
83
84         cc = run ("dcpomatic2_create x --dcp-frame-rate 30");
85         BOOST_CHECK (!cc.error);
86         BOOST_REQUIRE (cc.dcp_frame_rate);
87         BOOST_CHECK_EQUAL (*cc.dcp_frame_rate, 30);
88
89         cc = run ("dcpomatic2_create x --container-ratio 185");
90         BOOST_CHECK (!cc.error);
91         BOOST_CHECK_EQUAL (cc.container_ratio, Ratio::from_id("185"));
92
93         cc = run ("dcpomatic2_create x --container-ratio XXX");
94         BOOST_CHECK (cc.error);
95
96         cc = run ("dcpomatic2_create x --still-length 42");
97         BOOST_CHECK (!cc.error);
98         BOOST_CHECK_EQUAL (cc.still_length, 42);
99
100         cc = run ("dcpomatic2_create x --standard SMPTE");
101         BOOST_CHECK (!cc.error);
102         BOOST_CHECK_EQUAL (cc.standard, dcp::Standard::SMPTE);
103
104         cc = run ("dcpomatic2_create x --standard interop");
105         BOOST_CHECK (!cc.error);
106         BOOST_CHECK_EQUAL (cc.standard, dcp::Standard::INTEROP);
107
108         cc = run ("dcpomatic2_create x --standard SMPTEX");
109         BOOST_CHECK (cc.error);
110
111         cc = run ("dcpomatic2_create x --config foo/bar");
112         BOOST_CHECK (!cc.error);
113         BOOST_REQUIRE (cc.config_dir);
114         BOOST_CHECK_EQUAL (*cc.config_dir, "foo/bar");
115
116         cc = run ("dcpomatic2_create x --output fred/jim");
117         BOOST_CHECK (!cc.error);
118         BOOST_REQUIRE (cc.output_dir);
119         BOOST_CHECK_EQUAL (*cc.output_dir, "fred/jim");
120
121         cc = run ("dcpomatic2_create x --outputX fred/jim");
122         BOOST_CHECK (cc.error);
123
124         cc = run ("dcpomatic2_create --config foo/bar --still-length 42 --output flaps fred jim sheila");
125         BOOST_CHECK (!cc.error);
126         BOOST_REQUIRE (cc.config_dir);
127         BOOST_CHECK_EQUAL (*cc.config_dir, "foo/bar");
128         BOOST_CHECK_EQUAL (cc.still_length, 42);
129         BOOST_REQUIRE (cc.output_dir);
130         BOOST_CHECK_EQUAL (*cc.output_dir, "flaps");
131         BOOST_REQUIRE_EQUAL (cc.content.size(), 3U);
132         BOOST_CHECK_EQUAL (cc.content[0].path, "fred");
133         BOOST_CHECK_EQUAL (cc.content[0].frame_type, VideoFrameType::TWO_D);
134         BOOST_CHECK_EQUAL (cc.content[1].path, "jim");
135         BOOST_CHECK_EQUAL (cc.content[1].frame_type, VideoFrameType::TWO_D);
136         BOOST_CHECK_EQUAL (cc.content[2].path, "sheila");
137         BOOST_CHECK_EQUAL (cc.content[2].frame_type, VideoFrameType::TWO_D);
138
139         cc = run ("dcpomatic2_create --left-eye left.mp4 --right-eye right.mp4");
140         BOOST_REQUIRE_EQUAL (cc.content.size(), 2U);
141         BOOST_CHECK_EQUAL (cc.content[0].path, "left.mp4");
142         BOOST_CHECK_EQUAL (cc.content[0].frame_type, VideoFrameType::THREE_D_LEFT);
143         BOOST_CHECK_EQUAL (cc.content[1].path, "right.mp4");
144         BOOST_CHECK_EQUAL (cc.content[1].frame_type, VideoFrameType::THREE_D_RIGHT);
145         BOOST_CHECK_EQUAL (cc.fourk, false);
146
147         cc = run ("dcpomatic2_create --fourk foo.mp4");
148         BOOST_REQUIRE_EQUAL (cc.content.size(), 1U);
149         BOOST_CHECK_EQUAL (cc.content[0].path, "foo.mp4");
150         BOOST_CHECK_EQUAL (cc.fourk, true);
151         BOOST_CHECK (!cc.error);
152
153         cc = run ("dcpomatic2_create --j2k-bandwidth 120 foo.mp4");
154         BOOST_REQUIRE_EQUAL (cc.content.size(), 1U);
155         BOOST_CHECK_EQUAL (cc.content[0].path, "foo.mp4");
156         BOOST_REQUIRE (cc.j2k_bandwidth);
157         BOOST_CHECK_EQUAL (*cc.j2k_bandwidth, 120000000);
158         BOOST_CHECK (!cc.error);
159
160         cc = run ("dcpomatic2_create --channel L fred.wav --channel R jim.wav sheila.wav");
161         BOOST_REQUIRE_EQUAL (cc.content.size(), 3U);
162         BOOST_CHECK_EQUAL (cc.content[0].path, "fred.wav");
163         BOOST_CHECK (cc.content[0].channel);
164         BOOST_CHECK (*cc.content[0].channel == dcp::Channel::LEFT);
165         BOOST_CHECK_EQUAL (cc.content[1].path, "jim.wav");
166         BOOST_CHECK (cc.content[1].channel);
167         BOOST_CHECK (*cc.content[1].channel == dcp::Channel::RIGHT);
168         BOOST_CHECK_EQUAL (cc.content[2].path, "sheila.wav");
169         BOOST_CHECK (!cc.content[2].channel);
170
171         cc = run ("dcpomatic2_create --channel foo fred.wav");
172         BOOST_REQUIRE (cc.error);
173         BOOST_CHECK (boost::algorithm::starts_with(*cc.error, "dcpomatic2_create: foo is not valid for --channel"));
174 }