TestMediaMIMETypes.cpp (12444B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "MediaMIMETypes.h" 8 #include "gtest/gtest.h" 9 10 using namespace mozilla; 11 12 TEST(MediaMIMETypes, DependentMIMEType) 13 { 14 static const struct { 15 const char* mString; 16 DependentMediaMIMEType mDependentMediaMIMEType; 17 } tests[] = {{"audio/mp4", MEDIAMIMETYPE("audio/mp4")}, 18 {"video/mp4", MEDIAMIMETYPE("video/mp4")}, 19 {"application/x-mp4", MEDIAMIMETYPE("application/x-mp4")}}; 20 for (const auto& test : tests) { 21 EXPECT_TRUE(test.mDependentMediaMIMEType.AsDependentString().EqualsASCII( 22 test.mString)); 23 MediaMIMEType mimetype(test.mDependentMediaMIMEType); 24 EXPECT_TRUE(mimetype.AsString().Equals( 25 test.mDependentMediaMIMEType.AsDependentString())); 26 EXPECT_EQ(mimetype, test.mDependentMediaMIMEType); 27 EXPECT_EQ(mimetype, MediaMIMEType(test.mDependentMediaMIMEType)); 28 } 29 } 30 31 TEST(MediaMIMETypes, MakeMediaMIMEType_bad) 32 { 33 static const char* tests[] = {"", " ", "/", "audio", 34 "audio/", "mp4", "/mp4", "a/b"}; 35 36 for (const auto& test : tests) { 37 Maybe<MediaMIMEType> type = MakeMediaMIMEType(test); 38 EXPECT_TRUE(type.isNothing()) 39 << "MakeMediaMIMEType(\"" << test << "\").isNothing()"; 40 } 41 } 42 43 TEST(MediaMIMETypes, MediaMIMEType) 44 { 45 static const struct { 46 const char* mTypeString; 47 const char* mAsString; 48 bool mApplication; 49 bool mAudio; 50 bool mVideo; 51 bool mEqualsLiteralVideoSlashMp4; // tests `== "video/mp4"` 52 } tests[] = { 53 // in AsString app audio video ==v/mp4 54 {"video/mp4", "video/mp4", false, false, true, true}, 55 {"video/mp4; codecs=0", "video/mp4", false, false, true, true}, 56 {"VIDEO/MP4", "video/mp4", false, false, true, true}, 57 {"audio/mp4", "audio/mp4", false, true, false, false}, 58 {"application/x", "application/x", true, false, false, false}}; 59 60 for (const auto& test : tests) { 61 Maybe<MediaMIMEType> type = MakeMediaMIMEType(test.mTypeString); 62 EXPECT_TRUE(type.isSome()) 63 << "MakeMediaMIMEType(\"" << test.mTypeString << "\").isSome()"; 64 EXPECT_TRUE(type->AsString().EqualsASCII(test.mAsString)) 65 << "MakeMediaMIMEType(\"" << test.mTypeString << "\")->AsString() == \"" 66 << test.mAsString << "\""; 67 EXPECT_EQ(test.mApplication, type->HasApplicationMajorType()) 68 << "MakeMediaMIMEType(\"" << test.mTypeString 69 << "\")->HasApplicationMajorType() == " 70 << (test.mApplication ? "true" : "false"); 71 EXPECT_EQ(test.mAudio, type->HasAudioMajorType()) 72 << "MakeMediaMIMEType(\"" << test.mTypeString 73 << "\")->HasAudioMajorType() == " << (test.mAudio ? "true" : "false"); 74 EXPECT_EQ(test.mVideo, type->HasVideoMajorType()) 75 << "MakeMediaMIMEType(\"" << test.mTypeString 76 << "\")->HasVideoMajorType() == " << (test.mVideo ? "true" : "false"); 77 EXPECT_EQ(test.mEqualsLiteralVideoSlashMp4, 78 *type == MEDIAMIMETYPE("video/mp4")) 79 << "*MakeMediaMIMEType(\"" << test.mTypeString 80 << "\") == MEDIAMIMETYPE(\"video/mp4\")"; 81 } 82 } 83 84 TEST(MediaMIMETypes, MediaCodecs) 85 { 86 MediaCodecs empty(""); 87 EXPECT_TRUE(empty.IsEmpty()); 88 EXPECT_TRUE(empty.AsString().EqualsLiteral("")); 89 EXPECT_FALSE(empty.Contains(u""_ns)); 90 EXPECT_FALSE(empty.Contains(u"c1"_ns)); 91 EXPECT_FALSE(empty.ContainsPrefix(u""_ns)); 92 EXPECT_FALSE(empty.ContainsPrefix(u"c1"_ns)); 93 int iterations = 0; 94 for (const auto& codec : empty.Range()) { 95 ++iterations; 96 (void)codec; 97 } 98 EXPECT_EQ(0, iterations); 99 100 MediaCodecs space(" "); 101 EXPECT_FALSE(space.IsEmpty()); 102 EXPECT_TRUE(space.AsString().EqualsLiteral(" ")); 103 EXPECT_TRUE(space.Contains(u""_ns)); 104 EXPECT_FALSE(space.Contains(u"c1"_ns)); 105 EXPECT_TRUE(space.ContainsPrefix(u""_ns)); 106 EXPECT_FALSE(space.ContainsPrefix(u"c"_ns)); 107 EXPECT_FALSE(space.ContainsPrefix(u"c1"_ns)); 108 iterations = 0; 109 for (const auto& codec : space.Range()) { 110 ++iterations; 111 EXPECT_TRUE(codec.IsEmpty()); 112 } 113 EXPECT_EQ(1, iterations); 114 115 MediaCodecs one(" c1 "); 116 EXPECT_FALSE(one.IsEmpty()); 117 EXPECT_TRUE(one.AsString().EqualsLiteral(" c1 ")); 118 EXPECT_FALSE(one.Contains(u""_ns)); 119 EXPECT_TRUE(one.Contains(u"c1"_ns)); 120 EXPECT_TRUE(one.ContainsPrefix(u""_ns)); 121 EXPECT_TRUE(one.ContainsPrefix(u"c"_ns)); 122 EXPECT_TRUE(one.ContainsPrefix(u"c1"_ns)); 123 EXPECT_FALSE(one.ContainsPrefix(u"c1x"_ns)); 124 EXPECT_FALSE(one.ContainsPrefix(u"c1 "_ns)); 125 iterations = 0; 126 for (const auto& codec : one.Range()) { 127 ++iterations; 128 EXPECT_TRUE(codec.EqualsLiteral("c1")); 129 } 130 EXPECT_EQ(1, iterations); 131 132 MediaCodecs two(" c1 , c2 "); 133 EXPECT_FALSE(two.IsEmpty()); 134 EXPECT_TRUE(two.AsString().EqualsLiteral(" c1 , c2 ")); 135 EXPECT_FALSE(two.Contains(u""_ns)); 136 EXPECT_TRUE(two.Contains(u"c1"_ns)); 137 EXPECT_TRUE(two.Contains(u"c2"_ns)); 138 EXPECT_TRUE(two.ContainsPrefix(u""_ns)); 139 EXPECT_TRUE(two.ContainsPrefix(u"c"_ns)); 140 EXPECT_FALSE(two.ContainsPrefix(u"1"_ns)); 141 EXPECT_TRUE(two.ContainsPrefix(u"c1"_ns)); 142 EXPECT_TRUE(two.ContainsPrefix(u"c2"_ns)); 143 EXPECT_FALSE(two.ContainsPrefix(u"c1x"_ns)); 144 EXPECT_FALSE(two.ContainsPrefix(u"c2x"_ns)); 145 iterations = 0; 146 for (const auto& codec : two.Range()) { 147 ++iterations; 148 char buffer[] = "c0"; 149 buffer[1] += iterations; 150 EXPECT_TRUE(codec.EqualsASCII(buffer)); 151 } 152 EXPECT_EQ(2, iterations); 153 154 EXPECT_TRUE(two.ContainsAll(two)); 155 EXPECT_TRUE(two.ContainsAll(one)); 156 EXPECT_FALSE(one.ContainsAll(two)); 157 158 // Check wide char case where both octets/bytes are relevant. Note we don't 159 // use `EqualsLiteral` here because at the time of writing it will place the 160 // literal into a narrow string which then doesn't compare correctly with 161 // the wide representation from MediaCodecs. 162 MediaCodecs euroSign(" € "); // U+20AC 163 EXPECT_FALSE(euroSign.IsEmpty()); 164 EXPECT_TRUE(euroSign.AsString().Equals(u" € "_ns)); 165 EXPECT_FALSE(euroSign.Contains(u""_ns)); 166 EXPECT_TRUE(euroSign.Contains(u"€"_ns)); 167 EXPECT_FALSE(euroSign.Contains(u"€€"_ns)); 168 EXPECT_TRUE(euroSign.ContainsPrefix(u""_ns)); 169 EXPECT_TRUE(euroSign.ContainsPrefix(u"€"_ns)); 170 EXPECT_FALSE(euroSign.ContainsPrefix( 171 u"₭"_ns)); // U+20AD -- ensure second octet is compared 172 EXPECT_FALSE(euroSign.ContainsPrefix( 173 u"↬"_ns)); // U+21AC -- ensure first octet is compared 174 EXPECT_FALSE(euroSign.ContainsPrefix(u"€ "_ns)); 175 iterations = 0; 176 for (const auto& codec : euroSign.Range()) { 177 ++iterations; 178 EXPECT_TRUE(codec.Equals(u"€"_ns)); 179 } 180 EXPECT_EQ(1, iterations); 181 } 182 183 TEST(MediaMIMETypes, MakeMediaExtendedMIMEType_bad) 184 { 185 static const char* tests[] = {"", " ", "/", "audio", 186 "audio/", "mp4", "/mp4", "a/b"}; 187 188 for (const auto& test : tests) { 189 Maybe<MediaExtendedMIMEType> type = MakeMediaExtendedMIMEType(test); 190 EXPECT_TRUE(type.isNothing()) 191 << "MakeMediaExtendedMIMEType(\"" << test << "\").isNothing()"; 192 } 193 } 194 195 TEST(MediaMIMETypes, MediaExtendedMIMEType) 196 { 197 // Some generic tests first. 198 static const struct { 199 const char* mTypeString; 200 const char* mTypeAsString; 201 bool mApplication; 202 bool mAudio; 203 bool mVideo; 204 bool mEqualsLiteralVideoSlashMp4; // tests `== "video/mp4"` 205 bool mHaveCodecs; 206 } tests[] = { 207 // in Type().AsString app audio video ==v/mp4 208 // codecs 209 {"video/mp4", "video/mp4", false, false, true, true, false}, 210 {"video/mp4; codecs=0", "video/mp4", false, false, true, true, true}, 211 {"VIDEO/MP4", "video/mp4", false, false, true, true, false}, 212 {"audio/mp4", "audio/mp4", false, true, false, false, false}, 213 {"video/webm", "video/webm", false, false, true, false, false}, 214 {"audio/webm", "audio/webm", false, true, false, false, false}, 215 {"application/x", "application/x", true, false, false, false, false}}; 216 217 for (const auto& test : tests) { 218 Maybe<MediaExtendedMIMEType> type = 219 MakeMediaExtendedMIMEType(test.mTypeString); 220 EXPECT_TRUE(type.isSome()) 221 << "MakeMediaExtendedMIMEType(\"" << test.mTypeString << "\").isSome()"; 222 EXPECT_TRUE(type->OriginalString().EqualsASCII(test.mTypeString)) 223 << "MakeMediaExtendedMIMEType(\"" << test.mTypeString 224 << "\")->AsString() == \"" << test.mTypeAsString << "\""; 225 EXPECT_TRUE(type->Type().AsString().EqualsASCII(test.mTypeAsString)) 226 << "MakeMediaExtendedMIMEType(\"" << test.mTypeString 227 << "\")->AsString() == \"" << test.mTypeAsString << "\""; 228 EXPECT_EQ(test.mApplication, type->Type().HasApplicationMajorType()) 229 << "MakeMediaExtendedMIMEType(\"" << test.mTypeString 230 << "\")->Type().HasApplicationMajorType() == " 231 << (test.mApplication ? "true" : "false"); 232 EXPECT_EQ(test.mAudio, type->Type().HasAudioMajorType()) 233 << "MakeMediaExtendedMIMEType(\"" << test.mTypeString 234 << "\")->Type().HasAudioMajorType() == " 235 << (test.mAudio ? "true" : "false"); 236 EXPECT_EQ(test.mVideo, type->Type().HasVideoMajorType()) 237 << "MakeMediaExtendedMIMEType(\"" << test.mTypeString 238 << "\")->Type().HasVideoMajorType() == " 239 << (test.mVideo ? "true" : "false"); 240 EXPECT_EQ(test.mEqualsLiteralVideoSlashMp4, 241 type->Type() == MEDIAMIMETYPE("video/mp4")) 242 << "*MakeMediaExtendedMIMEType(\"" << test.mTypeString 243 << "\")->Type() == MEDIAMIMETYPE(\"video/mp4\")"; 244 EXPECT_EQ(test.mHaveCodecs, type->HaveCodecs()) 245 << "MakeMediaExtendedMIMEType(\"" << test.mTypeString 246 << "\")->HaveCodecs() == " << (test.mHaveCodecs ? "true" : "false"); 247 EXPECT_NE(test.mHaveCodecs, type->Codecs().IsEmpty()) 248 << "MakeMediaExtendedMIMEType(\"" << test.mTypeString 249 << "\")->Codecs.IsEmpty() != " << (test.mHaveCodecs ? "true" : "false"); 250 EXPECT_FALSE(type->GetWidth()) << "MakeMediaExtendedMIMEType(\"" 251 << test.mTypeString << "\")->GetWidth()"; 252 EXPECT_FALSE(type->GetHeight()) << "MakeMediaExtendedMIMEType(\"" 253 << test.mTypeString << "\")->GetHeight()"; 254 EXPECT_FALSE(type->GetFramerate()) 255 << "MakeMediaExtendedMIMEType(\"" << test.mTypeString 256 << "\")->GetFramerate()"; 257 EXPECT_FALSE(type->GetBitrate()) << "MakeMediaExtendedMIMEType(\"" 258 << test.mTypeString << "\")->GetBitrate()"; 259 } 260 261 // Test all extra parameters. 262 Maybe<MediaExtendedMIMEType> type = MakeMediaExtendedMIMEType( 263 "video/mp4; codecs=\"a,b\"; width=1024; Height=768; FrameRate=60; " 264 "BITRATE=100000"); 265 EXPECT_TRUE(type->HaveCodecs()); 266 EXPECT_FALSE(type->Codecs().IsEmpty()); 267 EXPECT_TRUE(type->Codecs().AsString().EqualsASCII("a,b")); 268 EXPECT_TRUE(type->Codecs() == "a,b"); 269 EXPECT_TRUE(type->Codecs().Contains(u"a"_ns)); 270 EXPECT_TRUE(type->Codecs().Contains(u"b"_ns)); 271 EXPECT_TRUE(type->Codecs().ContainsPrefix(u"a"_ns)); 272 EXPECT_TRUE(type->Codecs().ContainsPrefix(u"b"_ns)); 273 EXPECT_FALSE(type->Codecs().ContainsPrefix(u"ab"_ns)); 274 EXPECT_FALSE(type->Codecs().ContainsPrefix(u"ba"_ns)); 275 EXPECT_FALSE(type->Codecs().ContainsPrefix(u"a,b"_ns)); 276 EXPECT_TRUE(!!type->GetWidth()); 277 EXPECT_EQ(1024, *type->GetWidth()); 278 EXPECT_TRUE(!!type->GetHeight()); 279 EXPECT_EQ(768, *type->GetHeight()); 280 EXPECT_TRUE(!!type->GetFramerate()); 281 EXPECT_EQ(60, *type->GetFramerate()); 282 EXPECT_TRUE(!!type->GetBitrate()); 283 EXPECT_EQ(100000, *type->GetBitrate()); 284 EXPECT_EQ(5ul, type->GetParameterCount()); 285 286 // Test parameter count variations 287 type = MakeMediaExtendedMIMEType("video/mp4"); 288 EXPECT_EQ(0ul, type->GetParameterCount()); 289 290 type = MakeMediaExtendedMIMEType("video/mp4; codecs=\"a,b\""); 291 EXPECT_EQ(1ul, type->GetParameterCount()); 292 293 type = MakeMediaExtendedMIMEType("video/mp4; codecs=\"a,b\"; width=1024"); 294 EXPECT_EQ(2ul, type->GetParameterCount()); 295 296 type = MakeMediaExtendedMIMEType( 297 "video/mp4; codecs=\"a,b\"; width=1024; Height=768"); 298 EXPECT_EQ(3ul, type->GetParameterCount()); 299 300 type = MakeMediaExtendedMIMEType( 301 "video/mp4; codecs=\"a,b\"; width=1024; Height=768; FrameRate=60"); 302 EXPECT_EQ(4ul, type->GetParameterCount()); 303 }