diff --git a/mpd/base/xml/xml_node_unittest.cc b/mpd/base/xml/xml_node_unittest.cc new file mode 100644 index 0000000000..7793f3fb63 --- /dev/null +++ b/mpd/base/xml/xml_node_unittest.cc @@ -0,0 +1,99 @@ +#include "base/logging.h" +#include "base/strings/string_util.h" +#include "mpd/base/xml/xml_node.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/libxml/src/include/libxml/tree.h" + +namespace dash_packager { +namespace xml { + +namespace { + +// TODO(rkuroiwa): Add XmlStringCompare() that does not care about the +// prettiness of the string representation of the XML. We currently use +// CollapseWhitespaceASCII() with carefully handcrafted expectations so that we +// can compare the result. + +// Template so that it works for ContentProtectionXml and +// ContentProtectionXml::Element. +template +void AddAttribute(const std::string& name, + const std::string& value, + XmlElement* content_protection_xml) { + MediaInfo::ContentProtectionXml::AttributeNameValuePair* attribute = + content_protection_xml->add_attributes(); + attribute->set_name(name); + attribute->set_value(value); +} + +std::string GetDocAsFlatString(xmlDocPtr doc) { + static const int kFlatFormat = 0; + int doc_str_size = 0; + xmlChar* doc_str = NULL; + xmlDocDumpFormatMemoryEnc(doc, &doc_str, &doc_str_size, "UTF-8", kFlatFormat); + DCHECK(doc_str); + + std::string output(doc_str, doc_str + doc_str_size); + xmlFree(doc_str); + return output; +} + +// Ownership transfers, IOW this function will release the resource for |node|. +// Returns |node| in string format. +std::string GetStringFormat(ScopedXmlPtr::type node) { + xml::ScopedXmlPtr::type doc(xmlNewDoc(BAD_CAST "")); + + // Because you cannot easily get the string format of a xmlNodePtr, it gets + // attached to a temporary xml doc. + xmlDocSetRootElement(doc.get(), node.release()); + std::string doc_str = GetDocAsFlatString(doc.get()); + + // GetDocAsFlatString() adds + // + // to the first line. So this removes the first line. + const size_t first_newline_char_pos = doc_str.find('\n'); + DCHECK_NE(first_newline_char_pos, std::string::npos); + return doc_str.substr(first_newline_char_pos + 1); +} + +} // namespace + +TEST(Representation, AddContentProtectionXml) { + static const char kExpectedRepresentaionString[] = + "\n\ + \n\ + \n\ + \n\ + "; + + MediaInfo media_info; + MediaInfo::ContentProtectionXml* content_protection_xml = + media_info.add_content_protections(); + content_protection_xml->set_scheme_id_uri("http://www.foo.com/drm"); + content_protection_xml->set_value("somevalue"); + AddAttribute("a", "1", content_protection_xml); + AddAttribute("b", "2", content_protection_xml); + + MediaInfo::ContentProtectionXml::Element* subelement = + content_protection_xml->add_subelements(); + subelement->set_name("TestSubElement"); + AddAttribute("c", "3", subelement); + AddAttribute("d", "4", subelement); + + RepresentationXmlNode representation; + ASSERT_TRUE( + representation.AddContentProtectionElementsFromMediaInfo(media_info)); + + std::string representation_xml_string = + GetStringFormat(representation.PassScopedPtr()); + // Compare with expected output (both flattened). + ASSERT_EQ(CollapseWhitespaceASCII(kExpectedRepresentaionString, true), + CollapseWhitespaceASCII(representation_xml_string, true)); +} + +} // namespace xml +} // namespace dash_packager diff --git a/mpd/mpd.gyp b/mpd/mpd.gyp index df4f1aaad3..600388076c 100644 --- a/mpd/mpd.gyp +++ b/mpd/mpd.gyp @@ -55,6 +55,7 @@ 'type': 'executable', 'sources': [ 'base/mpd_builder_unittest.cc', + 'base/xml/xml_node_unittest.cc', ], 'dependencies': [ '../base/base.gyp:base',