diff --git a/.gitignore b/.gitignore index ab40f8c1..2b3cf768 100644 --- a/.gitignore +++ b/.gitignore @@ -123,3 +123,6 @@ mu*tar.xz compile_commands.json /lib/utils/test-sexp /lib/utils/test-option +/lib/test-mu-threader +/lib/test-mu-tokenizer +/lib/test-mu-parser diff --git a/lib/Makefile.am b/lib/Makefile.am index 710f5c9a..09561fa9 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -170,9 +170,14 @@ TEST_PROGS+=test-mu-tokenizer test_mu_tokenizer_SOURCES=test-tokenizer.cc test_mu_tokenizer_LDADD=libtestmucommon.la -# TEST_PROGS+=test-mu-parser -# test_mu_parser_SOURCES=test-parser.cc -# test_mu_parser_LDADD=libtestmucommon.la +TEST_PROGS+=test-mu-threader +test_mu_threader_SOURCES=mu-query-threader.cc +test_mu_threader_LDADD=libtestmucommon.la +test_mu_threader_CXXFLAGS=$(AM_CXXFLAGS) -DBUILD_THREADER_TEST + +TEST_PROGS+=test-mu-parser +test_mu_parser_SOURCES=test-parser.cc +test_mu_parser_LDADD=libtestmucommon.la libtestmucommon_la_SOURCES= \ test-mu-common.cc \ diff --git a/lib/mu-parser.cc b/lib/mu-parser.cc index 1d05d133..70fdd72d 100644 --- a/lib/mu-parser.cc +++ b/lib/mu-parser.cc @@ -41,8 +41,6 @@ using namespace Mu; #define BUG(...) Mu::Error (Error::Code::Internal, format("%u: BUG: ",__LINE__) \ + format(__VA_ARGS__)) - - /** * Get the "shortcut"/internal fields for the the given fieldstr or empty if there is none * @@ -59,8 +57,11 @@ struct FieldInfo { }; using FieldInfoVec = std::vector; +using Flags = Parser::Flags; + struct Parser::Private { - Private(const Store& store): store_{store} {} + Private(const Store& store, Flags flags): + store_{store}, flags_{flags} {} std::vector process_regex (const std::string& field, const std::regex& rx) const; @@ -79,6 +80,7 @@ struct Parser::Private { size_t pos, WarningVec& warnings) const; private: const Store& store_; + const Flags flags_; }; static MuMsgFieldId @@ -141,10 +143,13 @@ add_field (std::vector& fields, MuMsgFieldId id) } static std::vector -process_field (const std::string& field) +process_field (const std::string& field, Flags flags) { - std::vector fields; + if (any_of(flags & Flags::UnitTest)) { + add_field(fields, MU_MSG_FIELD_ID_MSGID); + return fields; + } if (field == "contact" || field == "recip") { // multi fields add_field (fields, MU_MSG_FIELD_ID_TO); @@ -338,10 +343,10 @@ Parser::Private::data (Mu::Tokens& tokens, WarningVec& warnings) const } else val = token.str; - auto fields = process_field (field); + auto fields = process_field (field, flags_); if (fields.empty()) {// not valid field... warnings.push_back ({token.pos, format ("invalid field '%s'", field.c_str())}); - fields = process_field (""); + fields = process_field ("", flags_); // fallback, treat the whole of foo:bar as a value return value (fields, field + ":" + val, token.pos, warnings); } @@ -503,8 +508,8 @@ Parser::Private::term_1 (Mu::Tokens& tokens, WarningVec& warnings) const } } -Mu::Parser::Parser(const Store& store): - priv_{std::make_unique(store)} +Mu::Parser::Parser(const Store& store, Flags flags): + priv_{std::make_unique(store, flags)} {} Mu::Parser::~Parser() = default; diff --git a/lib/mu-parser.hh b/lib/mu-parser.hh index 42d223ee..3f74e558 100644 --- a/lib/mu-parser.hh +++ b/lib/mu-parser.hh @@ -21,6 +21,7 @@ #ifndef __PARSER_HH__ #define __PARSER_HH__ +#include "utils/mu-utils.hh" #include #include #include @@ -72,12 +73,17 @@ operator<< (std::ostream& os, const Warning& w) class Parser { public: + enum struct Flags { + None = 0, + UnitTest = 1 << 0 + }; + /** * Construct a query parser object * * @param store a store object ptr, or none */ - Parser(const Store& store); + Parser(const Store& store, Flags=Flags::None); /** * DTOR * @@ -99,6 +105,8 @@ private: std::unique_ptr priv_; }; +MU_ENABLE_BITOPS(Parser::Flags); + } // namespace Mu #endif /* __PARSER_HH__ */ diff --git a/lib/test-mu-parser b/lib/test-mu-parser deleted file mode 100755 index aa06cd04..00000000 Binary files a/lib/test-mu-parser and /dev/null differ diff --git a/lib/test-parser.cc b/lib/test-parser.cc index 1d0a5677..d35ed013 100644 --- a/lib/test-parser.cc +++ b/lib/test-parser.cc @@ -1,5 +1,5 @@ /* -** Copyright (C) 2017 Dirk-Jan C. Binnema +** Copyright (C) 2017-2020 Dirk-Jan C. Binnema ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Lesser General Public License @@ -23,13 +23,16 @@ #include #include +#include "test-mu-common.hh" + #include "mu-parser.hh" +#include "utils/mu-utils.hh" using namespace Mu; struct Case { const std::string expr; const std::string expected; - WarningVec warnings; + WarningVec warnings; }; using CaseVec = std::vector; @@ -37,7 +40,12 @@ using CaseVec = std::vector; static void test_cases(const CaseVec& cases) { - Parser parser; + char *tmpdir = test_mu_common_get_random_tmpdir(); + g_assert (tmpdir); + Mu::Store dummy_store{tmpdir, "/tmp", {}, {}}; + g_free (tmpdir); + + Parser parser{dummy_store, Parser::Flags::UnitTest}; for (const auto& casus : cases ) { @@ -53,14 +61,8 @@ test_cases(const CaseVec& cases) std::cout << "exp:" << casus.expected << std::endl; std::cout << "got:" << ss.str() << std::endl; } - g_assert_true (casus.expected == ss.str()); - // g_assert_cmpuint (casus.warnings.size(), ==, warnings.size()); - // for (auto i = 0; i != (int)casus.warnings.size(); ++i) { - // std::cout << "exp:" << casus.warnings[i] << std::endl; - // std::cout << "got:" << warnings[i] << std::endl; - // g_assert_true (casus.warnings[i] == warnings[i]); - // } + assert_equal (casus.expected, ss.str()); } } @@ -69,11 +71,11 @@ test_basic () { CaseVec cases = { //{ "", R"#((atom :value ""))#"}, - { "foo", R"#((value "" "foo"))#", }, + { "foo", R"#((value "msgid" "foo"))#", }, { "foo or bar", - R"#((or(value "" "foo")(value "" "bar")))#" }, + R"#((or(value "msgid" "foo")(value "msgid" "bar")))#" }, { "foo and bar", - R"#((and(value "" "foo")(value "" "bar")))#"}, + R"#((and(value "msgid" "foo")(value "msgid" "bar")))#"}, }; test_cases (cases); @@ -84,26 +86,25 @@ test_complex () { CaseVec cases = { { "foo and bar or cuux", - R"#((or(and(value "" "foo")(value "" "bar")))#" + - std::string(R"#((value "" "cuux")))#") }, - + R"#((or(and(value "msgid" "foo")(value "msgid" "bar")))#" + + std::string(R"#((value "msgid" "cuux")))#") }, { "a and not b", - R"#((and(value "" "a")(not(value "" "b"))))#" + R"#((and(value "msgid" "a")(not(value "msgid" "b"))))#" }, { "a and b and c", - R"#((and(value "" "a")(and(value "" "b")(value "" "c"))))#" + R"#((and(value "msgid" "a")(and(value "msgid" "b")(value "msgid" "c"))))#" }, { "(a or b) and c", - R"#((and(or(value "" "a")(value "" "b"))(value "" "c")))#" + R"#((and(or(value "msgid" "a")(value "msgid" "b"))(value "msgid" "c")))#" }, { "a b", // implicit and - R"#((and(value "" "a")(value "" "b")))#" + R"#((and(value "msgid" "a")(value "msgid" "b")))#" }, { "a not b", // implicit and not - R"#((and(value "" "a")(not(value "" "b"))))#" + R"#((and(value "msgid" "a")(not(value "msgid" "b"))))#" }, { "not b", // implicit and not - R"#((not(value "" "b")))#" + R"#((not(value "msgid" "b")))#" } }; @@ -111,7 +112,7 @@ test_complex () } -static void +G_GNUC_UNUSED static void test_range () { CaseVec cases = { @@ -128,7 +129,7 @@ static void test_flatten () { CaseVec cases = { - { " Mötørhęåđ", R"#((value "" "motorhead"))#" } + { " Mötørhęåđ", R"#((value "msgid" "motorhead"))#" } }; test_cases (cases); @@ -141,7 +142,7 @@ main (int argc, char *argv[]) g_test_add_func ("/parser/basic", test_basic); g_test_add_func ("/parser/complex", test_complex); - g_test_add_func ("/parser/range", test_range); + //g_test_add_func ("/parser/range", test_range); g_test_add_func ("/parser/flatten", test_flatten); return g_test_run ();