From a7efe6277afa77eb010fa764178f47bf50a963f5 Mon Sep 17 00:00:00 2001 From: liuchang0812 Date: Fri, 13 Jan 2017 13:49:41 +0800 Subject: [PATCH] common/xmlformatter: turn on underscored by default, add unittest Signed-off-by: liuchang0812 --- src/common/Formatter.cc | 67 +++++------ src/common/Formatter.h | 9 +- src/test/common/CMakeLists.txt | 6 + src/test/common/test_xmlformatter.cc | 165 +++++++++++++++++++++++++++ 4 files changed, 212 insertions(+), 35 deletions(-) create mode 100644 src/test/common/test_xmlformatter.cc diff --git a/src/common/Formatter.cc b/src/common/Formatter.cc index 0a3fdf76120..0bbbdd361ec 100644 --- a/src/common/Formatter.cc +++ b/src/common/Formatter.cc @@ -34,10 +34,6 @@ #include -static char tolower_underscore(const char b) { - return ' ' == b ? '_' : std::tolower(b); -} - // ----------------------- namespace ceph { @@ -326,9 +322,10 @@ void JSONFormatter::write_raw_data(const char *data) const char *XMLFormatter::XML_1_DTD = ""; -XMLFormatter::XMLFormatter(bool pretty, bool lowercased_underscored) +XMLFormatter::XMLFormatter(bool pretty, bool lowercased, bool underscored) : m_pretty(pretty), - m_lowercased_underscored(lowercased_underscored) + m_lowercased(lowercased), + m_underscored(underscored) { reset(); } @@ -410,10 +407,8 @@ void XMLFormatter::close_section() finish_pending_string(); std::string section = m_sections.back(); - if (m_lowercased_underscored) { - std::transform(section.begin(), section.end(), section.begin(), - tolower_underscore); - } + std::transform(section.begin(), section.end(), section.begin(), + [this](char c) { return this->to_lower_underscore(c); }); m_sections.pop_back(); print_spaces(); m_ss << ""; @@ -424,9 +419,9 @@ void XMLFormatter::close_section() void XMLFormatter::dump_unsigned(const char *name, uint64_t u) { std::string e(name); - if (m_lowercased_underscored) { - std::transform(e.begin(), e.end(), e.begin(), tolower_underscore); - } + std::transform(e.begin(), e.end(), e.begin(), + [this](char c) { return this->to_lower_underscore(c); }); + print_spaces(); m_ss << "<" << e << ">" << u << ""; if (m_pretty) @@ -436,9 +431,9 @@ void XMLFormatter::dump_unsigned(const char *name, uint64_t u) void XMLFormatter::dump_int(const char *name, int64_t u) { std::string e(name); - if (m_lowercased_underscored) { - std::transform(e.begin(), e.end(), e.begin(), tolower_underscore); - } + std::transform(e.begin(), e.end(), e.begin(), + [this](char c) { return this->to_lower_underscore(c); }); + print_spaces(); m_ss << "<" << e << ">" << u << ""; if (m_pretty) @@ -448,9 +443,9 @@ void XMLFormatter::dump_int(const char *name, int64_t u) void XMLFormatter::dump_float(const char *name, double d) { std::string e(name); - if (m_lowercased_underscored) { - std::transform(e.begin(), e.end(), e.begin(), tolower_underscore); - } + std::transform(e.begin(), e.end(), e.begin(), + [this](char c) { return this->to_lower_underscore(c); }); + print_spaces(); m_ss << "<" << e << ">" << d << ""; if (m_pretty) @@ -460,9 +455,9 @@ void XMLFormatter::dump_float(const char *name, double d) void XMLFormatter::dump_string(const char *name, const std::string& s) { std::string e(name); - if (m_lowercased_underscored) { - std::transform(e.begin(), e.end(), e.begin(), tolower_underscore); - } + std::transform(e.begin(), e.end(), e.begin(), + [this](char c) { return this->to_lower_underscore(c); }); + print_spaces(); m_ss << "<" << e << ">" << escape_xml_str(s.c_str()) << ""; if (m_pretty) @@ -472,9 +467,9 @@ void XMLFormatter::dump_string(const char *name, const std::string& s) void XMLFormatter::dump_string_with_attrs(const char *name, const std::string& s, const FormatterAttrs& attrs) { std::string e(name); - if (m_lowercased_underscored) { - std::transform(e.begin(), e.end(), e.begin(), tolower_underscore); - } + std::transform(e.begin(), e.end(), e.begin(), + [this](char c) { return this->to_lower_underscore(c); }); + std::string attrs_str; get_attrs_str(&attrs, attrs_str); print_spaces(); @@ -495,11 +490,10 @@ void XMLFormatter::dump_format_va(const char* name, const char *ns, bool quoted, { char buf[LARGE_SIZE]; vsnprintf(buf, LARGE_SIZE, fmt, ap); - std::string e(name); - if (m_lowercased_underscored) { - std::transform(e.begin(), e.end(), e.begin(), tolower_underscore); - } + std::transform(e.begin(), e.end(), e.begin(), + [this](char c) { return this->to_lower_underscore(c); }); + print_spaces(); if (ns) { m_ss << "<" << e << " xmlns=\"" << ns << "\">" << buf << ""; @@ -544,9 +538,8 @@ void XMLFormatter::open_section_in_ns(const char *name, const char *ns, const Fo } std::string e(name); - if (m_lowercased_underscored) { - std::transform(e.begin(), e.end(), e.begin(), tolower_underscore); - } + std::transform(e.begin(), e.end(), e.begin(), + [this](char c) { return this->to_lower_underscore(c); }); if (ns) { m_ss << "<" << e << attrs_str << " xmlns=\"" << ns << "\">"; @@ -588,6 +581,16 @@ std::string XMLFormatter::escape_xml_str(const char *str) return std::string(&escaped[0]); } +char XMLFormatter::to_lower_underscore(char c) const +{ + if (m_underscored && c == ' ') { + return '_'; + } else if (m_lowercased) { + return std::tolower(c); + } + return c; +} + TableFormatter::TableFormatter(bool keyval) : m_keyval(keyval) { reset(); diff --git a/src/common/Formatter.h b/src/common/Formatter.h index 6aeb05deb45..d2c3df26d84 100644 --- a/src/common/Formatter.h +++ b/src/common/Formatter.h @@ -136,7 +136,7 @@ namespace ceph { class XMLFormatter : public Formatter { public: static const char *XML_1_DTD; - XMLFormatter(bool pretty = false, bool lowercased_underscored = false); + XMLFormatter(bool pretty = false, bool lowercased = false, bool underscored = true); virtual void set_status(int status, const char* status_name) {} virtual void output_header(); @@ -163,17 +163,20 @@ namespace ceph { void open_array_section_with_attrs(const char *name, const FormatterAttrs& attrs); void open_object_section_with_attrs(const char *name, const FormatterAttrs& attrs); void dump_string_with_attrs(const char *name, const std::string& s, const FormatterAttrs& attrs); + protected: void open_section_in_ns(const char *name, const char *ns, const FormatterAttrs *attrs); void finish_pending_string(); void print_spaces(); static std::string escape_xml_str(const char *str); void get_attrs_str(const FormatterAttrs *attrs, std::string& attrs_str); + char to_lower_underscore(char c) const; std::stringstream m_ss, m_pending_string; std::deque m_sections; - bool m_pretty; - bool m_lowercased_underscored; + const bool m_pretty; + const bool m_lowercased; + const bool m_underscored; std::string m_pending_string_name; bool m_header_done; }; diff --git a/src/test/common/CMakeLists.txt b/src/test/common/CMakeLists.txt index f8ebe478089..7ba5cc98245 100644 --- a/src/test/common/CMakeLists.txt +++ b/src/test/common/CMakeLists.txt @@ -152,6 +152,12 @@ add_executable(unittest_tableformatter add_ceph_unittest(unittest_tableformatter ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/unittest_tableformatter) target_link_libraries(unittest_tableformatter global) +add_executable(unittest_xmlformatter + test_xmlformatter.cc + ) +add_ceph_unittest(unittest_xmlformatter ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/unittest_xmlformatter) +target_link_libraries(unittest_xmlformatter ceph-common) + # unittest_bit_vector add_executable(unittest_bit_vector test_bit_vector.cc diff --git a/src/test/common/test_xmlformatter.cc b/src/test/common/test_xmlformatter.cc new file mode 100644 index 00000000000..9ac6dde456e --- /dev/null +++ b/src/test/common/test_xmlformatter.cc @@ -0,0 +1,165 @@ +#include "gtest/gtest.h" + +#include "common/Formatter.h" +#include +#include + +using namespace ceph; + + +TEST(xmlformatter, oneline) +{ + + std::stringstream sout; + XMLFormatter formatter; + formatter.dump_int("integer", 10); + formatter.dump_float("float", 10.0); + formatter.dump_string("string", "string"); + formatter.flush(sout); + std::string cmp = "1010string"; + EXPECT_EQ(cmp, sout.str()); +} + +TEST(xmlformatter, multiline) +{ + std::stringstream sout; + XMLFormatter formatter; + formatter.dump_int("integer", 10); + formatter.dump_float("float", 10.0); + formatter.dump_string("string", "string"); + formatter.dump_int("integer", 20); + formatter.dump_float("float", 20.0); + formatter.dump_string("string", "string"); + + std::string cmp = "" + "1010string" + "2020string"; + + formatter.flush(sout); + EXPECT_EQ(cmp, sout.str()); +} + +TEST(xmlformatter, multiflush) +{ + std::stringstream sout1; + std::stringstream sout2; + XMLFormatter formatter; + formatter.dump_int("integer", 10); + formatter.dump_float("float", 10.0); + formatter.dump_string("string", "string"); + formatter.flush(sout1); + + std::string cmp = "" + "10" + "10" + "string"; + + EXPECT_EQ(cmp, sout1.str()); + + formatter.dump_int("integer", 20); + formatter.dump_float("float", 20.0); + formatter.dump_string("string", "string"); + formatter.flush(sout2); + + cmp = "" + "20" + "20" + "string"; + + EXPECT_EQ(cmp, sout2.str()); +} + +TEST(xmlformatter, pretty) +{ + std::stringstream sout; + XMLFormatter formatter( + true, // pretty + false, // lowercased + false); // underscored + formatter.open_object_section("xml"); + formatter.dump_int("Integer", 10); + formatter.dump_float("Float", 10.0); + formatter.dump_string("String", "String"); + formatter.close_section(); + formatter.flush(sout); + std::string cmp = "" + "\n" + " 10\n" + " 10\n" + " String\n" + "\n\n"; + EXPECT_EQ(cmp, sout.str()); +} + +TEST(xmlformatter, lowercased) +{ + std::stringstream sout; + XMLFormatter formatter( + false, // pretty + true, // lowercased + false); // underscored + formatter.dump_int("Integer", 10); + formatter.dump_float("Float", 10.0); + formatter.dump_string("String", "String"); + formatter.flush(sout); + std::string cmp = "" + "10" + "10" + "String"; + EXPECT_EQ(cmp, sout.str()); +} + +TEST(xmlformatter, underscored) +{ + std::stringstream sout; + XMLFormatter formatter( + false, // pretty + false, // lowercased + true); // underscored + formatter.dump_int("Integer Item", 10); + formatter.dump_float("Float Item", 10.0); + formatter.dump_string("String Item", "String"); + formatter.flush(sout); + std::string cmp = "" + "10" + "10" + "String"; + + EXPECT_EQ(cmp, sout.str()); +} + +TEST(xmlformatter, lowercased_underscored) +{ + std::stringstream sout; + XMLFormatter formatter( + false, // pretty + true, // lowercased + true); // underscored + formatter.dump_int("Integer Item", 10); + formatter.dump_float("Float Item", 10.0); + formatter.dump_string("String Item", "String"); + formatter.flush(sout); + std::string cmp = "" + "10" + "10" + "String"; + EXPECT_EQ(cmp, sout.str()); +} + +TEST(xmlformatter, pretty_lowercased_underscored) +{ + std::stringstream sout; + XMLFormatter formatter( + true, // pretty + true, // lowercased + true); // underscored + formatter.dump_int("Integer Item", 10); + formatter.dump_float("Float Item", 10.0); + formatter.dump_string("String Item", "String"); + formatter.flush(sout); + std::string cmp = "" + "10\n" + "10\n" + "String\n\n"; + EXPECT_EQ(cmp, sout.str()); +}