Tag Parser  6.4.1
C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
tagvalue.cpp
Go to the documentation of this file.
1 #include "./helper.h"
2 
3 #include "../tagvalue.h"
4 #include "../id3/id3genres.h"
5 
6 #include <c++utilities/conversion/conversionexception.h>
7 #include <c++utilities/chrono/format.h>
8 using namespace TestUtilities;
9 
10 #include <cppunit/TestFixture.h>
11 #include <cppunit/extensions/HelperMacros.h>
12 
13 using namespace std;
14 using namespace Media;
15 using namespace ConversionUtilities;
16 using namespace ChronoUtilities;
17 
18 using namespace CPPUNIT_NS;
19 
23 class TagValueTests : public TestFixture {
24  CPPUNIT_TEST_SUITE(TagValueTests);
25  CPPUNIT_TEST(testBasics);
26  CPPUNIT_TEST(testBinary);
27  CPPUNIT_TEST(testInteger);
28  CPPUNIT_TEST(testPositionInSet);
29  CPPUNIT_TEST(testTimeSpan);
30  CPPUNIT_TEST(testDateTime);
31  CPPUNIT_TEST(testString);
32  CPPUNIT_TEST(testEqualityOperator);
33  CPPUNIT_TEST_SUITE_END();
34 
35 public:
36  void setUp();
37  void tearDown();
38 
39  void testBasics();
40  void testBinary();
41  void testInteger();
42  void testPositionInSet();
43  void testTimeSpan();
44  void testDateTime();
45  void testString();
46  void testEqualityOperator();
47 };
48 
50 
52 {
53 }
54 
56 {
57 }
58 
60 {
61  CPPUNIT_ASSERT(TagValue::empty().isEmpty());
62  CPPUNIT_ASSERT_EQUAL(TagDataType::Undefined, TagValue().type());
63 }
64 
66 {
67  const TagValue binary("123", 3, TagDataType::Binary);
68  CPPUNIT_ASSERT_EQUAL(TagDataType::Binary, binary.type());
69  CPPUNIT_ASSERT_EQUAL("123"s, string(binary.dataPointer(), binary.dataSize()));
70  CPPUNIT_ASSERT_THROW(binary.toString(), ConversionException);
71  CPPUNIT_ASSERT_THROW(binary.toInteger(), ConversionException);
72  CPPUNIT_ASSERT_THROW(binary.toPositionInSet(), ConversionException);
73  CPPUNIT_ASSERT_THROW(binary.toStandardGenreIndex(), ConversionException);
74 }
75 
77 {
78  // positive number
79  TagValue integer(42);
80  CPPUNIT_ASSERT(!integer.isEmpty());
81  CPPUNIT_ASSERT_EQUAL(TagDataType::Integer, integer.type());
82  CPPUNIT_ASSERT_EQUAL(static_cast<int32>(42), integer.toInteger());
83  CPPUNIT_ASSERT_EQUAL("42"s, integer.toString());
84  integer.assignInteger(2);
85  CPPUNIT_ASSERT_EQUAL("Country"s, string(Id3Genres::stringFromIndex(integer.toStandardGenreIndex())));
86 
87  // negative number
88  integer.assignInteger(-25);
89  CPPUNIT_ASSERT_EQUAL("-25"s, integer.toString());
90  CPPUNIT_ASSERT_EQUAL(PositionInSet(-25), integer.toPositionInSet());
91  CPPUNIT_ASSERT_THROW(integer.toStandardGenreIndex(), ConversionException);
92 
93  // zero
94  integer.assignInteger(0);
95  CPPUNIT_ASSERT_MESSAGE("explicitely assigned zero not considered empty", !integer.isEmpty());
96  CPPUNIT_ASSERT_EQUAL("0"s, integer.toString());
97  CPPUNIT_ASSERT_EQUAL(DateTime(), integer.toDateTime());
98  CPPUNIT_ASSERT_EQUAL(TimeSpan(), integer.toTimeSpan());
99 
100  // empty value treatet as zero when using to...() methods
101  integer.clearData();
102  CPPUNIT_ASSERT_MESSAGE("cleared vale considered empty", integer.isEmpty());
103  CPPUNIT_ASSERT_EQUAL_MESSAGE("only date (but not type) cleared"s, TagDataType::Integer, integer.type());
104  CPPUNIT_ASSERT_EQUAL(static_cast<int32>(0), integer.toInteger());
105  CPPUNIT_ASSERT_EQUAL(string(), integer.toString());
106  CPPUNIT_ASSERT_EQUAL(DateTime(), integer.toDateTime());
107  CPPUNIT_ASSERT_EQUAL(TimeSpan(), integer.toTimeSpan());
108 }
109 
111 {
112  const TagValue test(PositionInSet(4, 23));
113  CPPUNIT_ASSERT_EQUAL(PositionInSet(4, 23), test.toPositionInSet());
114  CPPUNIT_ASSERT_THROW(test.toInteger(), ConversionException);
115  CPPUNIT_ASSERT_EQUAL("4/23"s, test.toString());
116  CPPUNIT_ASSERT_THROW(test.toStandardGenreIndex(), ConversionException);
117  CPPUNIT_ASSERT_THROW(test.toDateTime(), ConversionException);
118  CPPUNIT_ASSERT_THROW(test.toTimeSpan(), ConversionException);
119 }
120 
122 {
123  const TimeSpan fiveMinutes(TimeSpan::fromMinutes(5));
124  TagValue timeSpan;
125  timeSpan.assignTimeSpan(fiveMinutes);
126  CPPUNIT_ASSERT_EQUAL(fiveMinutes, timeSpan.toTimeSpan());
127  CPPUNIT_ASSERT_EQUAL(fiveMinutes.toString(), timeSpan.toString());
128  CPPUNIT_ASSERT_THROW(timeSpan.toInteger(), ConversionException);
129  CPPUNIT_ASSERT_THROW(timeSpan.toDateTime(), ConversionException);
130  CPPUNIT_ASSERT_THROW(timeSpan.toPositionInSet(), ConversionException);
131 }
132 
134 {
135  const DateTime now(DateTime::now());
136  TagValue dateTime;
137  dateTime.assignDateTime(now);
138  CPPUNIT_ASSERT_EQUAL(now, dateTime.toDateTime());
139  CPPUNIT_ASSERT_EQUAL(now.toString(), dateTime.toString());
140  CPPUNIT_ASSERT_THROW(dateTime.toInteger(), ConversionException);
141  CPPUNIT_ASSERT_THROW(dateTime.toTimeSpan(), ConversionException);
142  CPPUNIT_ASSERT_THROW(dateTime.toPositionInSet(), ConversionException);
143 }
144 
146 {
147  CPPUNIT_ASSERT_EQUAL("15\xe4"s, TagValue("15ä", 4, TagTextEncoding::Utf8).toString(TagTextEncoding::Latin1));
148  CPPUNIT_ASSERT_EQUAL("15ä"s, TagValue("15ä", 4, TagTextEncoding::Utf8).toString(TagTextEncoding::Utf8));
149  CPPUNIT_ASSERT_EQUAL("\x31\0\x35\0"s, TagValue(15).toString(TagTextEncoding::Utf16LittleEndian));
150  CPPUNIT_ASSERT_EQUAL("\0\x31\0\x35"s, TagValue(15).toString(TagTextEncoding::Utf16BigEndian));
151  CPPUNIT_ASSERT_EQUAL(15, TagValue("\0\x31\0\x35"s, TagTextEncoding::Utf16BigEndian).toInteger());
152  CPPUNIT_ASSERT_EQUAL_MESSAGE("original encoding preserved",
153  "15ä"s, TagValue("15ä", 4, TagTextEncoding::Utf8).toString(TagTextEncoding::Unspecified));
154  CPPUNIT_ASSERT_EQUAL_MESSAGE("original encoding preserved",
155  "\0\x31\0\x35"s, TagValue("\0\x31\0\x35", 4, TagTextEncoding::Utf16BigEndian).toString(TagTextEncoding::Unspecified));
156  CPPUNIT_ASSERT_EQUAL_MESSAGE("UTF-8 BOM truncated",
157  "täst"s, TagValue("\xef\xbb\xbftäst", 8, TagTextEncoding::Utf8).toString(TagTextEncoding::Unspecified));
158  CPPUNIT_ASSERT_EQUAL_MESSAGE("UTF-16 LE BOM truncated",
159  "\0t\0\xe4\0s\0t"s, TagValue("\xff\xfe\0t\0\xe4\0s\0t", 10, TagTextEncoding::Utf16LittleEndian).toString(TagTextEncoding::Unspecified));
160  CPPUNIT_ASSERT_EQUAL_MESSAGE("UTF-16 BE BOM truncated",
161  "t\0\xe4\0s\0t\0"s, TagValue("\xfe\xfft\0\xe4\0s\0t\0", 10, TagTextEncoding::Utf16BigEndian).toString(TagTextEncoding::Unspecified));
162  CPPUNIT_ASSERT_EQUAL_MESSAGE("conversion via c'tor",
163  "15\xe4"s, TagValue("\xef\xbb\xbf\x31\x35ä", 7, TagTextEncoding::Utf8, TagTextEncoding::Latin1).toString(TagTextEncoding::Unspecified));
164  CPPUNIT_ASSERT_EQUAL_MESSAGE("conversion to int", -15, TagValue(" - 156", 5, TagTextEncoding::Utf8).toInteger());
165  CPPUNIT_ASSERT_EQUAL_MESSAGE("conversion to int", 15, TagValue("\0\x31\0\x35", 4, TagTextEncoding::Utf16BigEndian).toInteger());
166  CPPUNIT_ASSERT_THROW_MESSAGE("failing conversion to int", TagValue("15ä", 4, TagTextEncoding::Utf8).toInteger(), ConversionException);
167  CPPUNIT_ASSERT_EQUAL_MESSAGE("conversion to pos", PositionInSet(4, 15), TagValue("4 / 15", 6, TagTextEncoding::Utf8).toPositionInSet());
168  CPPUNIT_ASSERT_EQUAL_MESSAGE("conversion to pos", PositionInSet(15), TagValue("\0\x31\0\x35", 4, TagTextEncoding::Utf16BigEndian).toPositionInSet());
169  CPPUNIT_ASSERT_THROW_MESSAGE("failing conversion pos", TagValue("a4 / 15", 7, TagTextEncoding::Utf8).toPositionInSet(), ConversionException);
170  CPPUNIT_ASSERT_EQUAL_MESSAGE("conversion to date", DateTime::fromDate(2004, 4, 15), TagValue("2004-04-15", 10, TagTextEncoding::Utf8).toDateTime());
171  CPPUNIT_ASSERT_THROW_MESSAGE("failing conversion to date", TagValue("_", 1, TagTextEncoding::Utf8).toDateTime(), ConversionException);
172  CPPUNIT_ASSERT_EQUAL_MESSAGE("conversion to time span", TimeSpan::fromHours(1.5), TagValue("01:30:00", 10, TagTextEncoding::Utf8).toTimeSpan());
173  CPPUNIT_ASSERT_THROW_MESSAGE("failing conversion to time span", TagValue("_", 1, TagTextEncoding::Utf8).toTimeSpan(), ConversionException);
174  CPPUNIT_ASSERT_EQUAL_MESSAGE("conversion to genre from index", 15, TagValue("\0\x31\0\x35", 4, TagTextEncoding::Utf16BigEndian).toStandardGenreIndex());
175  CPPUNIT_ASSERT_EQUAL_MESSAGE("conversion to genre from name", 2, TagValue("Country", 7, TagTextEncoding::Latin1).toStandardGenreIndex());
176  CPPUNIT_ASSERT_THROW_MESSAGE("failing conversion to genre", TagValue("Kountry", 7, TagTextEncoding::Latin1).toStandardGenreIndex(), ConversionException);
177 }
178 
180 {
181  CPPUNIT_ASSERT_MESSAGE("equality requires identical types or identical string representation"s,
182  TagValue(0) != TagValue::empty());
183  CPPUNIT_ASSERT_EQUAL_MESSAGE("types might differ"s,
184  TagValue(15), TagValue(15));
185  CPPUNIT_ASSERT_EQUAL_MESSAGE("types might differ"s,
186  TagValue("15", 2, TagTextEncoding::Latin1), TagValue(15));
187  CPPUNIT_ASSERT_MESSAGE("encoding must be equal if relevant for types"s,
188  TagValue("\0\x31\0\x35", 4, TagTextEncoding::Utf16BigEndian) != TagValue("15", 2, TagTextEncoding::Latin1));
189  CPPUNIT_ASSERT_EQUAL_MESSAGE("encoding is ignored when not relevant for types"s,
190  TagValue("\0\x31\0\x35", 4, TagTextEncoding::Utf16BigEndian), TagValue(15));
191 
192  // meta-data
193  TagValue withDescription(15);
194  withDescription.setDescription("test");
195  CPPUNIT_ASSERT_MESSAGE("meta-data must be equal"s, withDescription != TagValue(15));
196  TagValue withDescription2(withDescription);
197  CPPUNIT_ASSERT_EQUAL(withDescription, withDescription2);
198  withDescription2.setMimeType("foo/bar");
199  CPPUNIT_ASSERT(withDescription != withDescription2);
200  withDescription.setMimeType(withDescription2.mimeType());
201  CPPUNIT_ASSERT_EQUAL(withDescription, withDescription2);
202 }
The TagValue class wraps values of different types.
Definition: tagvalue.h:64
void setDescription(const std::string &value, TagTextEncoding encoding=TagTextEncoding::Latin1)
Sets the description.
Definition: tagvalue.h:400
bool isEmpty() const
Returns an indication whether an value is assigned.
Definition: tagvalue.h:344
int32 toInteger() const
Converts the value of the current TagValue object to its equivalent integer representation.
Definition: tagvalue.cpp:164
int toStandardGenreIndex() const
Converts the value of the current TagValue object to its equivalent standard genre index...
Definition: tagvalue.cpp:200
char * dataPointer() const
Returns a pointer to the raw data assigned to the current instance.
Definition: tagvalue.h:376
The TagValueTests class tests the TagValue class.
Definition: tagvalue.cpp:23
STL namespace.
void assignTimeSpan(ChronoUtilities::TimeSpan value)
Assigns the given TimeSpan value.
Definition: tagvalue.h:292
void setUp()
Definition: tagvalue.cpp:51
void assignDateTime(ChronoUtilities::DateTime value)
Assigns the given DateTime value.
Definition: tagvalue.h:300
The PositionInSet class describes the position of an element in a set which consists of a certain num...
Definition: positioninset.h:20
TagDataType type() const
Returns the type of the assigned value.
Definition: tagvalue.h:308
void testBinary()
Definition: tagvalue.cpp:65
void clearData()
Clears the assigned data.
Definition: tagvalue.h:355
ChronoUtilities::DateTime toDateTime() const
Converts the value of the current TagValue object to its equivalent DateTime representation.
Definition: tagvalue.cpp:309
void testDateTime()
Definition: tagvalue.cpp:133
void assignInteger(int value)
Assigns the given integer value.
Definition: tagvalue.cpp:620
PositionInSet toPositionInSet() const
Converts the value of the current TagValue object to its equivalent PositionInSet representation...
Definition: tagvalue.cpp:243
void testTimeSpan()
Definition: tagvalue.cpp:121
void tearDown()
Definition: tagvalue.cpp:55
void testInteger()
Definition: tagvalue.cpp:76
CPPUNIT_TEST_SUITE_REGISTRATION(TagValueTests)
void testBasics()
Definition: tagvalue.cpp:59
ChronoUtilities::TimeSpan toTimeSpan() const
Converts the value of the current TagValue object to its equivalent TimeSpan representation.
Definition: tagvalue.cpp:281
void testPositionInSet()
Definition: tagvalue.cpp:110
Contains all classes and functions of the TagInfo library.
Definition: exceptions.h:9
void testString()
Definition: tagvalue.cpp:145
void setMimeType(const std::string &value)
Sets the MIME type.
Definition: tagvalue.h:422
const std::string & mimeType() const
Returns the MIME type.
Definition: tagvalue.h:411
void testEqualityOperator()
Definition: tagvalue.cpp:179
size_t dataSize() const
Returns the size of the assigned value in bytes.
Definition: tagvalue.h:365
std::string toString(TagTextEncoding encoding=TagTextEncoding::Unspecified) const
Converts the value of the current TagValue object to its equivalent std::string representation.
Definition: tagvalue.h:320