$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r85456 - in trunk/libs/log: src test/run
From: andrey.semashev_at_[hidden]
Date: 2013-08-25 07:28:23
Author: andysem
Date: 2013-08-25 07:28:23 EDT (Sun, 25 Aug 2013)
New Revision: 85456
URL: http://svn.boost.org/trac/boost/changeset/85456
Log:
Added a test for formatter parser. Fixed a few bugs in the parser.
Added:
   trunk/libs/log/test/run/setup_formatter_parser.cpp   (contents, props changed)
Text files modified: 
   trunk/libs/log/src/formatter_parser.cpp            |     4                                         
   trunk/libs/log/test/run/setup_filter_parser.cpp    |    28 ++++                                    
   trunk/libs/log/test/run/setup_formatter_parser.cpp |   257 ++++++++++++++++++++++++++++++++++++++++
   3 files changed, 286 insertions(+), 3 deletions(-)
Modified: trunk/libs/log/src/formatter_parser.cpp
==============================================================================
--- trunk/libs/log/src/formatter_parser.cpp	Sun Aug 25 05:46:36 2013	(r85455)
+++ trunk/libs/log/src/formatter_parser.cpp	2013-08-25 07:28:23 EDT (Sun, 25 Aug 2013)	(r85456)
@@ -267,7 +267,7 @@
         if (p == end)
             BOOST_LOG_THROW_DESCR(parse_error, "Invalid attribute placeholder arguments description in the formatter string");
         if (*p == constants::char_paren_bracket_right)
-            return p;
+            return ++p;
 
         while (true)
         {
@@ -282,7 +282,7 @@
                 c = *p;
                 if (encoding::isspace(c) || c == constants::char_equal)
                     break;
-                if (!encoding::isalnum(c))
+                if (!encoding::isalnum(c) && c != constants::char_underline)
                     BOOST_LOG_THROW_DESCR(parse_error, "Placeholder argument name is invalid");
             }
 
Modified: trunk/libs/log/test/run/setup_filter_parser.cpp
==============================================================================
--- trunk/libs/log/test/run/setup_filter_parser.cpp	Sun Aug 25 05:46:36 2013	(r85455)
+++ trunk/libs/log/test/run/setup_filter_parser.cpp	2013-08-25 07:28:23 EDT (Sun, 25 Aug 2013)	(r85456)
@@ -610,7 +610,7 @@
     typedef base_type::string_type string_type;
 
 public:
-    explicit test_filter_factory(logging::attribute_name const& name) : m_name(name), m_rel(custom)
+    explicit test_filter_factory(logging::attribute_name const& name) : m_name(name), m_rel(custom), m_called(false)
     {
     }
 
@@ -628,10 +628,17 @@
         m_custom_rel = rel;
     }
 
+    void check_called()
+    {
+        BOOST_CHECK(m_called);
+        m_called = false;
+    }
+
     logging::filter on_exists_test(logging::attribute_name const& name)
     {
         BOOST_CHECK_EQUAL(m_name, name);
         BOOST_CHECK_EQUAL(m_rel, exists);
+        m_called = true;
         return logging::filter();
     }
     logging::filter on_equality_relation(logging::attribute_name const& name, string_type const& arg)
@@ -639,6 +646,7 @@
         BOOST_CHECK_EQUAL(m_name, name);
         BOOST_CHECK_EQUAL(m_rel, equality);
         BOOST_CHECK_EQUAL(m_arg, arg);
+        m_called = true;
         return logging::filter();
     }
     logging::filter on_inequality_relation(logging::attribute_name const& name, string_type const& arg)
@@ -646,6 +654,7 @@
         BOOST_CHECK_EQUAL(m_name, name);
         BOOST_CHECK_EQUAL(m_rel, inequality);
         BOOST_CHECK_EQUAL(m_arg, arg);
+        m_called = true;
         return logging::filter();
     }
     logging::filter on_less_relation(logging::attribute_name const& name, string_type const& arg)
@@ -653,6 +662,7 @@
         BOOST_CHECK_EQUAL(m_name, name);
         BOOST_CHECK_EQUAL(m_rel, less);
         BOOST_CHECK_EQUAL(m_arg, arg);
+        m_called = true;
         return logging::filter();
     }
     logging::filter on_greater_relation(logging::attribute_name const& name, string_type const& arg)
@@ -660,6 +670,7 @@
         BOOST_CHECK_EQUAL(m_name, name);
         BOOST_CHECK_EQUAL(m_rel, greater);
         BOOST_CHECK_EQUAL(m_arg, arg);
+        m_called = true;
         return logging::filter();
     }
     logging::filter on_less_or_equal_relation(logging::attribute_name const& name, string_type const& arg)
@@ -667,6 +678,7 @@
         BOOST_CHECK_EQUAL(m_name, name);
         BOOST_CHECK_EQUAL(m_rel, less_or_equal);
         BOOST_CHECK_EQUAL(m_arg, arg);
+        m_called = true;
         return logging::filter();
     }
     logging::filter on_greater_or_equal_relation(logging::attribute_name const& name, string_type const& arg)
@@ -674,6 +686,7 @@
         BOOST_CHECK_EQUAL(m_name, name);
         BOOST_CHECK_EQUAL(m_rel, greater_or_equal);
         BOOST_CHECK_EQUAL(m_arg, arg);
+        m_called = true;
         return logging::filter();
     }
     logging::filter on_custom_relation(logging::attribute_name const& name, string_type const& rel, string_type const& arg)
@@ -682,6 +695,7 @@
         BOOST_CHECK_EQUAL(m_rel, custom);
         BOOST_CHECK_EQUAL(m_custom_rel, rel);
         BOOST_CHECK_EQUAL(m_arg, arg);
+        m_called = true;
         return logging::filter();
     }
 
@@ -690,6 +704,7 @@
     relation_type m_rel;
     string_type m_arg;
     string_type m_custom_rel;
+    bool m_called;
 };
 
 } // namespace
@@ -704,46 +719,57 @@
     BOOST_TEST_CHECKPOINT("filter_factory::exists");
     factory->expect_relation(test_filter_factory::exists, "");
     logging::parse_filter("%MyCustomAttr%");
+    factory->check_called();
 
     BOOST_TEST_CHECKPOINT("filter_factory::equality");
     factory->expect_relation(test_filter_factory::equality, "15");
     logging::parse_filter("%MyCustomAttr% = 15");
+    factory->check_called();
 
     BOOST_TEST_CHECKPOINT("filter_factory::equality");
     factory->expect_relation(test_filter_factory::equality, "hello");
     logging::parse_filter("%MyCustomAttr% = hello");
+    factory->check_called();
 
     BOOST_TEST_CHECKPOINT("filter_factory::equality");
     factory->expect_relation(test_filter_factory::equality, "hello");
     logging::parse_filter("%MyCustomAttr% = \"hello\"");
+    factory->check_called();
 
     BOOST_TEST_CHECKPOINT("filter_factory::equality");
     factory->expect_relation(test_filter_factory::equality, "hello\nworld");
     logging::parse_filter("%MyCustomAttr% = \"hello\\nworld\"");
+    factory->check_called();
 
     BOOST_TEST_CHECKPOINT("filter_factory::inequality");
     factory->expect_relation(test_filter_factory::inequality, "hello");
     logging::parse_filter("%MyCustomAttr% != \"hello\"");
+    factory->check_called();
 
     BOOST_TEST_CHECKPOINT("filter_factory::less");
     factory->expect_relation(test_filter_factory::less, "hello");
     logging::parse_filter("%MyCustomAttr% < \"hello\"");
+    factory->check_called();
 
     BOOST_TEST_CHECKPOINT("filter_factory::greater");
     factory->expect_relation(test_filter_factory::greater, "hello");
     logging::parse_filter("%MyCustomAttr% > \"hello\"");
+    factory->check_called();
 
     BOOST_TEST_CHECKPOINT("filter_factory::less_or_equal");
     factory->expect_relation(test_filter_factory::less_or_equal, "hello");
     logging::parse_filter("%MyCustomAttr% <= \"hello\"");
+    factory->check_called();
 
     BOOST_TEST_CHECKPOINT("filter_factory::greater_or_equal");
     factory->expect_relation(test_filter_factory::greater_or_equal, "hello");
     logging::parse_filter("%MyCustomAttr% >= \"hello\"");
+    factory->check_called();
 
     BOOST_TEST_CHECKPOINT("filter_factory::custom");
     factory->expect_relation("my_relation", "hello");
     logging::parse_filter("%MyCustomAttr% my_relation \"hello\"");
+    factory->check_called();
 }
 
 // Tests for invalid filters
Added: trunk/libs/log/test/run/setup_formatter_parser.cpp
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/libs/log/test/run/setup_formatter_parser.cpp	2013-08-25 07:28:23 EDT (Sun, 25 Aug 2013)	(r85456)
@@ -0,0 +1,257 @@
+/*
+ *          Copyright Andrey Semashev 2007 - 2013.
+ * Distributed under the Boost Software License, Version 1.0.
+ *    (See accompanying file LICENSE_1_0.txt or copy at
+ *          http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file   setup_formatter_parser.cpp
+ * \author Andrey Semashev
+ * \date   25.08.2013
+ *
+ * \brief  This header contains tests for the formatter parser.
+ */
+
+#define BOOST_TEST_MODULE setup_formatter_parser
+
+#include <string>
+#include <boost/test/unit_test.hpp>
+#include <boost/log/utility/setup/formatter_parser.hpp>
+
+#if !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS) && !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)
+
+#include <boost/shared_ptr.hpp>
+#include <boost/log/exceptions.hpp>
+#include <boost/log/core/record.hpp>
+#include <boost/log/core/record_view.hpp>
+#include <boost/log/attributes/constant.hpp>
+#include <boost/log/attributes/attribute_set.hpp>
+#include <boost/log/attributes/attribute_value_set.hpp>
+#include <boost/log/utility/formatting_ostream.hpp>
+#include <boost/log/expressions/formatter.hpp>
+#include "make_record.hpp"
+
+namespace logging = boost::log;
+namespace attrs = logging::attributes;
+
+typedef logging::attribute_set attr_set;
+typedef logging::attribute_value_set attr_values;
+typedef logging::record_view record_view;
+
+typedef logging::basic_formatting_ostream< char > osstream;
+typedef logging::basic_formatter< char > formatter;
+
+// Tests for simple attribute placeholders in formatters
+BOOST_AUTO_TEST_CASE(attr_placeholders)
+{
+    attrs::constant< int > attr1(10);
+    attrs::constant< std::string > attr2("hello");
+    attr_set set1;
+
+    set1["MyAttr"] = attr1;
+    set1["MyStr"] = attr2;
+
+    record_view rec = make_record_view(set1);
+
+    {
+        formatter f = logging::parse_formatter("String literal");
+        std::string str1, str2;
+        osstream strm1(str1), strm2(str2);
+        f(rec, strm1);
+        strm2 << "String literal";
+        BOOST_CHECK_EQUAL(strm1.str(), strm2.str());
+    }
+    {
+        formatter f = logging::parse_formatter("MyAttr: %MyAttr%, MyStr: %MyStr%");
+        std::string str1, str2;
+        osstream strm1(str1), strm2(str2);
+        f(rec, strm1);
+        strm2 << "MyAttr: " << attr1.get() << ", MyStr: " << attr2.get();
+        BOOST_CHECK_EQUAL(strm1.str(), strm2.str());
+    }
+    {
+        formatter f = logging::parse_formatter("MyAttr: % MyAttr %, MyStr: % MyStr %");
+        std::string str1, str2;
+        osstream strm1(str1), strm2(str2);
+        f(rec, strm1);
+        strm2 << "MyAttr: " << attr1.get() << ", MyStr: " << attr2.get();
+        BOOST_CHECK_EQUAL(strm1.str(), strm2.str());
+    }
+    {
+        formatter f = logging::parse_formatter("%MyAttr%%MyStr%");
+        std::string str1, str2;
+        osstream strm1(str1), strm2(str2);
+        f(rec, strm1);
+        strm2 << attr1.get() << attr2.get();
+        BOOST_CHECK_EQUAL(strm1.str(), strm2.str());
+    }
+    {
+        formatter f = logging::parse_formatter("MyAttr: %MyAttr%, MissingAttr: %MissingAttr%");
+        std::string str1, str2;
+        osstream strm1(str1), strm2(str2);
+        f(rec, strm1);
+        strm2 << "MyAttr: " << attr1.get() << ", MissingAttr: ";
+        BOOST_CHECK_EQUAL(strm1.str(), strm2.str());
+    }
+}
+
+namespace {
+
+class test_formatter_factory :
+    public logging::formatter_factory< char >
+{
+private:
+    typedef logging::formatter_factory< char > base_type;
+
+public:
+    typedef base_type::string_type string_type;
+    typedef base_type::args_map args_map;
+    typedef base_type::formatter_type formatter_type;
+
+public:
+    explicit test_formatter_factory(logging::attribute_name const& name) : m_name(name), m_called(false)
+    {
+    }
+
+    void expect_args(args_map const& args)
+    {
+        m_args = args;
+    }
+
+    void check_called()
+    {
+        BOOST_CHECK(m_called);
+        m_called = false;
+    }
+
+    formatter_type create_formatter(logging::attribute_name const& name, args_map const& args)
+    {
+        BOOST_CHECK_EQUAL(m_name, name);
+        BOOST_CHECK_EQUAL(m_args.size(), args.size());
+
+        for (args_map::const_iterator it = m_args.begin(), end = m_args.end(); it != end; ++it)
+        {
+            args_map::const_iterator parsed_it = args.find(it->first);
+            if (parsed_it != args.end())
+            {
+                BOOST_TEST_CHECKPOINT(("Arg: " + it->first));
+                BOOST_CHECK_EQUAL(it->second, parsed_it->second);
+            }
+            else
+            {
+                BOOST_ERROR(("Arg not found: " + it->first));
+            }
+        }
+
+        m_called = true;
+        return formatter_type();
+    }
+
+private:
+    logging::attribute_name m_name;
+    args_map m_args;
+    bool m_called;
+};
+
+} // namespace
+
+// Tests for formatter factory
+BOOST_AUTO_TEST_CASE(formatter_factory)
+{
+    logging::attribute_name attr_name("MyCustomAttr");
+    boost::shared_ptr< test_formatter_factory > factory(new test_formatter_factory(attr_name));
+    logging::register_formatter_factory(attr_name, factory);
+
+    {
+        BOOST_TEST_CHECKPOINT("formatter 1");
+        test_formatter_factory::args_map args;
+        factory->expect_args(args);
+        logging::parse_formatter("Hello: %MyCustomAttr%");
+        factory->check_called();
+    }
+    {
+        BOOST_TEST_CHECKPOINT("formatter 2");
+        test_formatter_factory::args_map args;
+        factory->expect_args(args);
+        logging::parse_formatter("Hello: %MyCustomAttr()%");
+        factory->check_called();
+    }
+    {
+        BOOST_TEST_CHECKPOINT("formatter 3");
+        test_formatter_factory::args_map args;
+        factory->expect_args(args);
+        logging::parse_formatter("Hello: %MyCustomAttr ( ) %");
+        factory->check_called();
+    }
+    {
+        BOOST_TEST_CHECKPOINT("formatter 4");
+        test_formatter_factory::args_map args;
+        args["param1"] = "10";
+        factory->expect_args(args);
+        logging::parse_formatter("Hello: %MyCustomAttr(param1=10)%");
+        factory->check_called();
+    }
+    {
+        BOOST_TEST_CHECKPOINT("formatter 5");
+        test_formatter_factory::args_map args;
+        args["param1"] = "10";
+        factory->expect_args(args);
+        logging::parse_formatter("Hello: % MyCustomAttr ( param1 = 10 ) % ");
+        factory->check_called();
+    }
+    {
+        BOOST_TEST_CHECKPOINT("formatter 6");
+        test_formatter_factory::args_map args;
+        args["param1"] = " 10 ";
+        factory->expect_args(args);
+        logging::parse_formatter("Hello: %MyCustomAttr(param1=\" 10 \")%");
+        factory->check_called();
+    }
+    {
+        BOOST_TEST_CHECKPOINT("formatter 7");
+        test_formatter_factory::args_map args;
+        args["param1"] = "10";
+        args["param2"] = "abcd";
+        factory->expect_args(args);
+        logging::parse_formatter("Hello: %MyCustomAttr(param1 = 10, param2 = abcd)%");
+        factory->check_called();
+    }
+    {
+        BOOST_TEST_CHECKPOINT("formatter 8");
+        test_formatter_factory::args_map args;
+        args["param1"] = "10";
+        args["param2"] = "abcd";
+        factory->expect_args(args);
+        logging::parse_formatter("Hello: %MyCustomAttr(param1=10,param2=abcd)%");
+        factory->check_called();
+    }
+    {
+        BOOST_TEST_CHECKPOINT("formatter 9");
+        test_formatter_factory::args_map args;
+        args["param1"] = "10";
+        args["param2"] = "abcd";
+        args["param_last"] = "-2.2";
+        factory->expect_args(args);
+        logging::parse_formatter("Hello: %MyCustomAttr(param1 = 10, param2 = \"abcd\", param_last = -2.2)%");
+        factory->check_called();
+    }
+}
+
+// Tests for invalid formatters
+BOOST_AUTO_TEST_CASE(invalid)
+{
+    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_formatter("MyStr%"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(%"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr)%"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param%"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param=%"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param)%"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param=)%"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(=value)%"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param,param2)%"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param=value,)%"), logging::parse_error);
+    BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param=value,param2)%"), logging::parse_error);
+}
+
+#endif // !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS) && !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)