3 #include "../aspectratio.h" 4 #include "../backuphelper.h" 5 #include "../diagnostics.h" 6 #include "../exceptions.h" 8 #include "../mediafileinfo.h" 9 #include "../mediaformat.h" 10 #include "../positioninset.h" 11 #include "../progressfeedback.h" 12 #include "../signature.h" 14 #include "../tagtarget.h" 16 #include <c++utilities/conversion/stringbuilder.h> 17 #include <c++utilities/io/catchiofailure.h> 18 #include <c++utilities/tests/testutils.h> 21 #include <cppunit/TestFixture.h> 22 #include <cppunit/extensions/HelperMacros.h> 39 CPPUNIT_TEST(testSize);
40 CPPUNIT_TEST(testTagTarget);
41 CPPUNIT_TEST(testSignature);
42 CPPUNIT_TEST(testMargin);
43 CPPUNIT_TEST(testAspectRatio);
44 CPPUNIT_TEST(testMediaFormat);
45 CPPUNIT_TEST(testPositionInSet);
46 CPPUNIT_TEST(testProgressFeedback);
47 CPPUNIT_TEST(testAbortableProgressFeedback);
48 CPPUNIT_TEST(testDiagnostics);
50 CPPUNIT_TEST(testBackupFile);
52 CPPUNIT_TEST_SUITE_END();
59 void testStatusProvider();
63 void testAspectRatio();
64 void testMediaFormat();
65 void testPositionInSet();
66 void testProgressFeedback();
67 void testAbortableProgressFeedback();
68 void testDiagnostics();
70 void testBackupFile();
86 static_assert(
Size().isNull(),
"Size::isNull()");
87 static_assert(!
Size(3, 4).isNull(),
"Size::isNull()");
88 static_assert(
Size(3, 4).resolution() == 12,
"Size::resolution");
90 Size size(1920, 1080);
91 CPPUNIT_ASSERT_EQUAL(
"width: 1920, height: 1080"s, size.
toString());
92 CPPUNIT_ASSERT_EQUAL(
"1080p"s,
string(size.
abbreviation()));
95 CPPUNIT_ASSERT_EQUAL(
"720p"s,
string(size.
abbreviation()));
101 CPPUNIT_ASSERT(target.
isEmpty());
102 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"default level is 50", 50ul, target.
level());
103 CPPUNIT_ASSERT_EQUAL(
"level 50"s, target.
toString(TagTargetLevel::Unspecified));
104 target =
TagTarget(30, { 1, 2, 3 }, { 4 }, { 5, 6 }, { 7, 8, 9 });
105 CPPUNIT_ASSERT(!target.isEmpty());
106 const auto mapping = [](uint64 level) {
return level == 30 ?
TagTargetLevel::Track : TagTargetLevel::Unspecified; };
107 CPPUNIT_ASSERT_EQUAL(
108 "level 30 'track, song, chapter', track 1, track 2, track 3, chapter 4, edition 5, edition 6, attachment 7, attachment 8, attachment 9"s,
109 target.toString(mapping));
111 CPPUNIT_ASSERT_EQUAL(
"level 40, track 1, track 2, track 3, chapter 4, edition 5, edition 6, attachment 7, attachment 8, attachment 9"s,
112 target.toString(mapping));
113 target.setLevelName(
"test");
114 CPPUNIT_ASSERT_EQUAL(
"level 40 'test', track 1, track 2, track 3, chapter 4, edition 5, edition 6, attachment 7, attachment 8, attachment 9"s,
115 target.toString(mapping));
116 CPPUNIT_ASSERT(target ==
TagTarget(40, { 1, 2, 3 }, { 4 }, { 5, 6 }, { 7, 8, 9 }));
118 CPPUNIT_ASSERT(target.isEmpty());
123 const unsigned char xzHead[12] = { 0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00, 0x00, 0x04, 0xe6, 0xd6, 0xb4, 0x46 };
126 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Unknown,
parseSignature(reinterpret_cast<const char *>(xzHead), 3));
127 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Unknown,
parseSignature(reinterpret_cast<const char *>(xzHead), 2));
128 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Unknown,
parseSignature(reinterpret_cast<const char *>(xzHead), 0));
130 const auto containerFormat =
parseSignature(reinterpret_cast<const char *>(xzHead),
sizeof(xzHead));
139 static_assert(
Margin().isNull(),
"empty margin");
140 static_assert(!
Margin(0, 2).isNull(),
"non-empty margin");
142 CPPUNIT_ASSERT_EQUAL(
"top: 1; left: 2; bottom: 3; right: 4"s,
Margin(1, 2, 3, 4).toString());
147 static_assert(!
AspectRatio().isValid(),
"invalid aspect ratio");
148 static_assert(
AspectRatio(16, 9).isValid(),
"valid aspect ratio");
149 static_assert(
AspectRatio(16, 9).isExtended(),
"extended aspect ratio");
152 CPPUNIT_ASSERT_EQUAL(static_cast<uint16>(16), ratio.
numerator);
153 CPPUNIT_ASSERT_EQUAL(static_cast<uint16>(11), ratio.
denominator);
155 CPPUNIT_ASSERT_EQUAL(static_cast<uint16>(0), ratio2.
numerator);
156 CPPUNIT_ASSERT_EQUAL(static_cast<uint16>(0), ratio2.
denominator);
163 CPPUNIT_ASSERT_EQUAL(
"Advanced Audio Coding"s,
string(aac.
name()));
164 CPPUNIT_ASSERT_EQUAL(
"AAC"s,
string(aac.
abbreviation()));
171 CPPUNIT_ASSERT_EQUAL(
"Advanced Audio Coding Low Complexity Profile"s,
string(aac.
name()));
172 CPPUNIT_ASSERT_EQUAL(
"MPEG-4 AAC-LC"s,
string(aac.
abbreviation()));
174 CPPUNIT_ASSERT_EQUAL(
"Spectral Band Replication / HE-AAC"s,
string(aac.
extensionName()));
180 CPPUNIT_ASSERT(empty.
isNull());
181 CPPUNIT_ASSERT_EQUAL(0, empty.
position());
182 CPPUNIT_ASSERT_EQUAL(0, empty.
total());
183 CPPUNIT_ASSERT_EQUAL(
""s, empty.
toString());
186 CPPUNIT_ASSERT(!oneOfThree.isNull());
187 CPPUNIT_ASSERT_EQUAL(1, oneOfThree.position());
188 CPPUNIT_ASSERT_EQUAL(3, oneOfThree.total());
189 CPPUNIT_ASSERT_EQUAL(
"1/3"s, oneOfThree.toString());
192 CPPUNIT_ASSERT(!posOnly.isNull());
193 CPPUNIT_ASSERT_EQUAL(5, posOnly.position());
194 CPPUNIT_ASSERT_EQUAL(0, posOnly.total());
195 CPPUNIT_ASSERT_EQUAL(
"5"s, posOnly.toString());
198 CPPUNIT_ASSERT(!totalOnly.isNull());
199 CPPUNIT_ASSERT_EQUAL(0, totalOnly.position());
200 CPPUNIT_ASSERT_EQUAL(5, totalOnly.total());
201 CPPUNIT_ASSERT_EQUAL(
"/5"s, totalOnly.toString());
206 unsigned int steps = 0;
208 unsigned int stepPercentage;
209 unsigned int overallPercentage = 0;
214 step = progress.
step();
222 CPPUNIT_ASSERT_EQUAL(0u, steps);
224 CPPUNIT_ASSERT_EQUAL(0u, steps);
225 CPPUNIT_ASSERT_EQUAL(25u, overallPercentage);
227 CPPUNIT_ASSERT_EQUAL(1u, steps);
228 CPPUNIT_ASSERT_EQUAL(
"foo"s, step);
229 CPPUNIT_ASSERT_EQUAL(45u, stepPercentage);
230 CPPUNIT_ASSERT_EQUAL(25u, overallPercentage);
232 CPPUNIT_ASSERT_EQUAL(1u, steps);
233 CPPUNIT_ASSERT_EQUAL(
"foo"s, step);
234 CPPUNIT_ASSERT_EQUAL(60u, stepPercentage);
235 CPPUNIT_ASSERT_EQUAL(25u, overallPercentage);
237 CPPUNIT_ASSERT_EQUAL(1u, steps);
238 CPPUNIT_ASSERT_EQUAL(
"foo"s, step);
239 CPPUNIT_ASSERT_EQUAL(75u, stepPercentage);
240 CPPUNIT_ASSERT_EQUAL(25u, overallPercentage);
245 unsigned int steps = 0;
247 unsigned int stepPercentage;
248 unsigned int overallPercentage = 0;
253 step = progress.
step();
262 CPPUNIT_ASSERT_NO_THROW_MESSAGE(
"stop does nothing if not aborted", progress.
stopIfAborted());
263 CPPUNIT_ASSERT_EQUAL(0u, steps);
265 CPPUNIT_ASSERT_EQUAL(0u, steps);
266 CPPUNIT_ASSERT_EQUAL(25u, overallPercentage);
268 CPPUNIT_ASSERT_EQUAL(1u, steps);
269 CPPUNIT_ASSERT_EQUAL(
"foo"s, step);
270 CPPUNIT_ASSERT_EQUAL(45u, stepPercentage);
271 CPPUNIT_ASSERT_EQUAL(25u, overallPercentage);
272 CPPUNIT_ASSERT_NO_THROW_MESSAGE(
"next step continues if not aborted", progress.
nextStepOrStop(
"bar", 33));
273 CPPUNIT_ASSERT_EQUAL(2u, steps);
274 CPPUNIT_ASSERT_EQUAL(
"bar"s, step);
275 CPPUNIT_ASSERT_EQUAL(33u, stepPercentage);
276 CPPUNIT_ASSERT_EQUAL(25u, overallPercentage);
280 CPPUNIT_ASSERT_EQUAL(2u, steps);
281 CPPUNIT_ASSERT_EQUAL(
"bar"s, step);
282 CPPUNIT_ASSERT_EQUAL(33u, stepPercentage);
283 CPPUNIT_ASSERT_EQUAL(25u, overallPercentage);
290 diag.emplace_back(DiagLevel::Warning,
"warning msg",
"context");
291 CPPUNIT_ASSERT_EQUAL(DiagLevel::Warning, diag.
level());
292 CPPUNIT_ASSERT(!diag.
has(DiagLevel::Critical));
293 diag.emplace_back(DiagLevel::Critical,
"critical msg",
"context");
294 CPPUNIT_ASSERT_EQUAL(DiagLevel::Critical, diag.
level());
295 CPPUNIT_ASSERT(diag.
has(DiagLevel::Critical));
299 void UtilitiesTests::testBackupFile()
301 using namespace BackupHelper;
309 const auto workingDir(file.containingDirectory());
313 string backupPath1, backupPath2;
314 NativeFileStream backupStream1, backupStream2;
316 CPPUNIT_ASSERT_EQUAL(workingDir +
"/unsupported.bin.bak", backupPath1);
319 file.stream().open(file.path(), ios_base::out);
320 file.stream() <<
"test1" << endl;
324 CPPUNIT_ASSERT_EQUAL(workingDir +
"/unsupported.bin.1.bak", backupPath2);
327 backupStream2.close();
328 remove(backupPath2.data());
329 file.stream().open(file.path(), ios_base::out);
330 file.stream() <<
"test2" << endl;
336 CPPUNIT_FAIL(
"renaming failed because backup dir does not exist");
338 const char *what = catchIoFailure();
339 CPPUNIT_ASSERT(strstr(what,
"Unable to rename original file before rewriting it."));
341 backupStream2.clear();
342 workingCopyPathMode(
"bak/unsupported.bin", WorkingCopyMode::NoCopy);
344 CPPUNIT_ASSERT_EQUAL(workingDir +
"/bak/unsupported.bin", backupPath2);
347 backupStream2.close();
348 CPPUNIT_ASSERT_EQUAL(0,
remove(backupPath2.data()));
349 CPPUNIT_ASSERT_EQUAL(0,
remove(argsToString(workingDir %
'/' +
backupDirectory()).data()));
352 backupStream1.seekg(0, ios_base::end);
353 CPPUNIT_ASSERT_EQUAL(41_st, static_cast<size_t>(backupStream1.tellg()));
360 file.stream().seekg(0x1D);
361 CPPUNIT_ASSERT_EQUAL(0x34_st, static_cast<size_t>(file.stream().get()));
373 CPPUNIT_ASSERT_THROW(
375 CPPUNIT_ASSERT(diag.
level() < DiagLevel::Critical);
376 CPPUNIT_ASSERT(!diag.empty());
377 CPPUNIT_ASSERT_EQUAL(
"Rewriting the file to apply changed tag information has been aborted."s, diag.front().message());
378 CPPUNIT_ASSERT_EQUAL(
"The original file has been restored."s, diag.back().message());
388 CPPUNIT_ASSERT(diag.
level() >= DiagLevel::Critical);
389 CPPUNIT_ASSERT_EQUAL(
"Rewriting the file to apply changed tag information failed."s, diag.front().message());
390 CPPUNIT_ASSERT_EQUAL(
"The original file has been restored."s, diag.back().message());
396 throwIoFailure(
"simulated IO failure");
401 CPPUNIT_FAIL(
"IO failure not rethrown");
405 CPPUNIT_ASSERT(diag.
level() >= DiagLevel::Critical);
406 CPPUNIT_ASSERT_EQUAL(
"An IO error occured when rewriting the file to apply changed tag information."s, diag.front().message());
407 CPPUNIT_ASSERT_EQUAL(
"The original file has been restored."s, diag.back().message());
410 CPPUNIT_ASSERT_EQUAL(0,
remove(file.path().data()));
The Margin class defines the four margins of a rectangle.
StringType toString() const
Returns the string representation of the current PositionInSet.
std::string toString(const std::function< TagTargetLevel(uint64)> &tagTargetMapping) const
Returns the string representation of the current instance.
const char * abbreviation() const
Returns an abbreviation for the current instance, eg.
void updateStepPercentage(byte stepPercentage)
Updates the current step percentage and invokes the second callback specified on construction (or the...
void setWidth(uint32 value)
Sets the width.
The ProgressFeedback class provides feedback about an ongoing operation via callbacks.
void stopIfAborted() const
Throws an OperationAbortedException if aborted.
constexpr int32 position() const
Returns the element position of the current instance.
uint64 level() const
Returns the level.
The PositionInSet class describes the position of an element in a set which consists of a certain num...
TAG_PARSER_EXPORT std::string & backupDirectory()
Returns the directory used to store backup files.
The UtilitiesTests class tests various utility classes and functions of the tagparser library...
void updateStepPercentageFromFraction(double stepPercentage)
Updates the current step percentage and invokes the second callback specified on construction (or the...
bool isAborted() const
Returns whether the operation has been aborted via tryToAbort().
constexpr int32 total() const
Returns the total element count of the current instance.
void setHeight(uint32 value)
Sets the height.
The Size class defines the size of a two-dimensional object using integer point precision.
byte stepPercentage() const
Returns the percentage of the current step (initially 0, supposed to be a value from 0 to 100)...
byte overallPercentage() const
Returns the overall percentage (initially 0, supposed to be a value from 0 to 100).
Contains utility classes helping to read and write streams.
DiagLevel level() const
Returns the worst diag level present in the container.
TAG_PARSER_EXPORT const char * containerFormatName(ContainerFormat containerFormat)
Returns the name of the specified container format as C-style string.
void testAbortableProgressFeedback()
bool isEmpty() const
Returns an indication whether the target is empty.
void tryToAbort()
Aborts the operation.
The TagTarget class specifies the target of a tag.
TAG_PARSER_EXPORT void restoreOriginalFileFromBackupFile(const std::string &originalPath, const std::string &backupPath, IoUtilities::NativeFileStream &originalStream, IoUtilities::NativeFileStream &backupStream)
TAG_PARSER_EXPORT const char * containerFormatAbbreviation(ContainerFormat containerFormat, MediaType mediaType=MediaType::Unknown, unsigned int version=0)
Returns the abbreviation of the container format as C-style string considering the specified media ty...
void updateOverallPercentage(byte overallPercentage)
Updates the overall percentage and invokes the second callback specified on construction (or the firs...
void testProgressFeedback()
The AbortableProgressFeedback class provides feedback about an ongoing operation via callbacks...
CPPUNIT_TEST_SUITE_REGISTRATION(UtilitiesTests)
constexpr bool isNull() const
Returns an indication whether both the element position and total element count is 0...
void updateStep(const std::string &step, byte stepPercentage=0)
Updates the current step and invokes the first callback specified on construction.
TAG_PARSER_EXPORT void handleFailureAfterFileModified(MediaFileInfo &mediaFileInfo, const std::string &backupPath, IoUtilities::NativeFileStream &outputStream, IoUtilities::NativeFileStream &backupStream, Diagnostics &diag, const std::string &context="making file")
std::string toString() const
Returns the string representation of the current size.
bool has(DiagLevel level) const
Returns whether there's at least one DiagMessage which is at least as worse as level.
TAG_PARSER_EXPORT ContainerFormat parseSignature(const char *buffer, int bufferSize)
Parses the signature read from the specified buffer.
const std::string & step() const
Returns the name of the current step (initially empty).
The class inherits from std::exception and serves as base class for exceptions thrown by the elements...
The exception that is thrown when an operation has been stopped and thus not successfully completed b...
TAG_PARSER_EXPORT void createBackupFile(const std::string &originalPath, std::string &backupPath, IoUtilities::NativeFileStream &originalStream, IoUtilities::NativeFileStream &backupStream)
TAG_PARSER_EXPORT const char * containerFormatSubversion(ContainerFormat containerFormat)
Returns the subversion of the container format as C-style string.
Contains all classes and functions of the TagInfo library.
void nextStepOrStop(const std::string &step, byte stepPercentage=0)
Throws an OperationAbortedException if aborted; otherwise the data for the next step is set...
The AspectRatio struct defines an aspect ratio.
The Diagnostics class is a container for DiagMessage.