Clarify some documentation slightly.
[dcpomatic.git] / test / file_naming_test.cc
1 /*
2     Copyright (C) 2016-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
22 /** @file  test/file_naming_test.cc
23  *  @brief Test how files in DCPs are named.
24  *  @ingroup feature
25  */
26
27
28 #include "test.h"
29 #include "lib/config.h"
30 #include "lib/content_factory.h"
31 #include "lib/dcp_content_type.h"
32 #include "lib/ffmpeg_content.h"
33 #include "lib/film.h"
34 #include "lib/video_content.h"
35 #ifdef DCPOMATIC_WINDOWS
36 #include <boost/locale.hpp>
37 #endif
38 #include <boost/test/unit_test.hpp>
39 #include <boost/regex.hpp>
40
41
42 using std::make_shared;
43 using std::string;
44
45
46 static
47 string
48 mxf_regex(string part) {
49 #ifdef DCPOMATIC_WINDOWS
50         /* Windows replaces . in filenames with _ */
51         return String::compose(".*flat_%1_png_.*\\.mxf", part);
52 #else
53         return String::compose(".*flat_%1\\.png_.*\\.mxf", part);
54 #endif
55 };
56
57
58
59 BOOST_AUTO_TEST_CASE (file_naming_test)
60 {
61         ConfigRestorer cr;
62         Config::instance()->set_dcp_asset_filename_format (dcp::NameFormat("%c"));
63
64         auto r = make_shared<FFmpegContent>("test/data/flat_red.png");
65         auto g = make_shared<FFmpegContent>("test/data/flat_green.png");
66         auto b = make_shared<FFmpegContent>("test/data/flat_blue.png");
67         auto film = new_test_film("file_naming_test", { r, g, b });
68         film->set_video_frame_rate (24);
69
70         r->set_position (film, dcpomatic::DCPTime::from_seconds(0));
71         r->set_video_frame_rate(film, 24);
72         r->video->set_length (24);
73         g->set_position (film, dcpomatic::DCPTime::from_seconds(1));
74         g->set_video_frame_rate(film, 24);
75         g->video->set_length (24);
76         b->set_position (film, dcpomatic::DCPTime::from_seconds(2));
77         b->set_video_frame_rate(film, 24);
78         b->video->set_length (24);
79
80         film->set_reel_type (ReelType::BY_VIDEO_CONTENT);
81         film->write_metadata ();
82         make_and_verify_dcp (
83                 film,
84                 {
85                         dcp::VerificationNote::Code::MISSING_FFMC_IN_FEATURE,
86                         dcp::VerificationNote::Code::MISSING_FFEC_IN_FEATURE
87                 });
88
89         int got[3] = { 0, 0, 0 };
90         for (auto i: boost::filesystem::directory_iterator(film->file(film->dcp_name()))) {
91                 if (boost::regex_match(i.path().string(), boost::regex(mxf_regex("red")))) {
92                         ++got[0];
93                 } else if (boost::regex_match(i.path().string(), boost::regex(mxf_regex("green")))) {
94                         ++got[1];
95                 } else if (boost::regex_match(i.path().string(), boost::regex(mxf_regex("blue")))) {
96                         ++got[2];
97                 }
98         }
99
100         for (int i = 0; i < 3; ++i) {
101                 BOOST_CHECK (got[i] == 2);
102         }
103 }
104
105
106 BOOST_AUTO_TEST_CASE (file_naming_test2)
107 {
108         ConfigRestorer cr;
109
110         Config::instance()->set_dcp_asset_filename_format (dcp::NameFormat ("%c"));
111
112 #ifdef DCPOMATIC_WINDOWS
113         /* This is necessary so that the UTF8 string constant below gets converted properly */
114         std::locale::global(boost::locale::generator().generate(""));
115         boost::filesystem::path::imbue(std::locale());
116 #endif
117
118         auto r = make_shared<FFmpegContent>("test/data/flät_red.png");
119         auto g = make_shared<FFmpegContent>("test/data/flat_green.png");
120         auto b = make_shared<FFmpegContent>("test/data/flat_blue.png");
121         auto film = new_test_film("file_naming_test2", { r, g, b });
122
123         r->set_position (film, dcpomatic::DCPTime::from_seconds(0));
124         r->set_video_frame_rate(film, 24);
125         r->video->set_length (24);
126         g->set_position (film, dcpomatic::DCPTime::from_seconds(1));
127         g->set_video_frame_rate(film, 24);
128         g->video->set_length (24);
129         b->set_position (film, dcpomatic::DCPTime::from_seconds(2));
130         b->set_video_frame_rate(film, 24);
131         b->video->set_length (24);
132
133         film->set_reel_type (ReelType::BY_VIDEO_CONTENT);
134         make_and_verify_dcp (
135                 film,
136                 {
137                         dcp::VerificationNote::Code::MISSING_FFMC_IN_FEATURE,
138                         dcp::VerificationNote::Code::MISSING_FFEC_IN_FEATURE
139                 });
140
141         int got[3] = { 0, 0, 0 };
142         for (auto i: boost::filesystem::directory_iterator (film->file(film->dcp_name()))) {
143                 if (boost::regex_match(i.path().string(), boost::regex(mxf_regex("red")))) {
144                         ++got[0];
145                 } else if (boost::regex_match(i.path().string(), boost::regex(mxf_regex("green")))) {
146                         ++got[1];
147                 } else if (boost::regex_match(i.path().string(), boost::regex(mxf_regex("blue")))) {
148                         ++got[2];
149                 }
150         }
151
152         for (int i = 0; i < 3; ++i) {
153                 BOOST_CHECK (got[i] == 2);
154         }
155 }
156
157
158 BOOST_AUTO_TEST_CASE (subtitle_file_naming)
159 {
160         ConfigRestorer cr;
161
162         Config::instance()->set_dcp_asset_filename_format(dcp::NameFormat("%t ostrabagalous %c"));
163
164         auto content = content_factory("test/data/15s.srt");
165         auto film = new_test_film("subtitle_file_naming", content);
166         film->set_interop(false);
167
168         make_and_verify_dcp (
169                 film,
170                 {
171                         dcp::VerificationNote::Code::MISSING_CPL_METADATA,
172                         dcp::VerificationNote::Code::MISSING_SUBTITLE_LANGUAGE,
173                         dcp::VerificationNote::Code::INVALID_SUBTITLE_FIRST_TEXT_TIME,
174                 });
175
176         int got = 0;
177
178         for (auto i: boost::filesystem::directory_iterator(film->file(film->dcp_name()))) {
179                 if (boost::regex_match(i.path().filename().string(), boost::regex("sub_ostrabagalous_15s.*\\.mxf"))) {
180                         ++got;
181                 }
182         }
183
184         BOOST_CHECK_EQUAL(got, 1);
185 }
186
187
188 BOOST_AUTO_TEST_CASE(remove_bad_characters_from_template)
189 {
190         ConfigRestorer cr;
191
192         /* %z is not recognised, so the % should be discarded so it won't trip
193          * an invalid URI check in make_and_verify_dcp
194          */
195         Config::instance()->set_dcp_asset_filename_format(dcp::NameFormat("%c%z"));
196
197         auto content = content_factory("test/data/flat_red.png");
198         auto film = new_test_film("remove_bad_characters_from_template", content);
199         make_and_verify_dcp(
200                 film,
201                 {
202                         dcp::VerificationNote::Code::MISSING_FFMC_IN_FEATURE,
203                         dcp::VerificationNote::Code::MISSING_FFEC_IN_FEATURE
204                 });
205 }
206