/* ** Copyright (C) 2017 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 ** as published by the Free Software Foundation; either version 2.1 ** of the License, or (at your option) any later version. ** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Lesser General Public License for more details. ** ** You should have received a copy of the GNU Lesser General Public ** License along with this library; if not, write to the Free ** Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA ** 02110-1301, USA. */ #include #include #include #include #include "mu-tokenizer.hh" struct Case { const char *str; const Mu::Tokens tokens; }; using CaseVec = std::vector; using namespace Mu; using TT = Token::Type; static void test_cases(const CaseVec& cases) { for (const auto& casus : cases ) { const auto tokens = tokenize (casus.str); g_assert_cmpuint ((guint)tokens.size(),==,(guint)casus.tokens.size()); for (size_t u = 0; u != tokens.size(); ++u) { if (g_test_verbose()) { std::cerr << "case " << u << " " << casus.str << std::endl; std::cerr << "exp: '" << casus.tokens[u] << "'" << std::endl; std::cerr << "got: '" << tokens[u] << "'" << std::endl; } g_assert_true (tokens[u] == casus.tokens[u]); } } } static void test_basic () { CaseVec cases = { { "", {} }, { "foo", Tokens{Token{3, TT::Data, "foo"}}}, { "foo bar cuux", Tokens{Token{3, TT::Data, "foo"}, Token{7, TT::Data, "bar"}, Token{12, TT::Data, "cuux"}}}, { "\"foo bar\"", Tokens{ Token{9, TT::Data, "foo bar"}}}, // ie. ignore missing closing '"' { "\"foo bar", Tokens{ Token{8, TT::Data, "foo bar"}}}, }; test_cases (cases); } static void test_specials () { CaseVec cases = { { ")*(", Tokens{Token{1, TT::Close, ")"}, Token{2, TT::Data, "*"}, Token{3, TT::Open, "("}}}, { "\")*(\"", Tokens{Token{5, TT::Data, ")*("}}}, }; test_cases (cases); } static void test_ops () { CaseVec cases = { { "foo and bar oR cuux XoR fnorb", Tokens{Token{3, TT::Data, "foo"}, Token{7, TT::And, "and"}, Token{11, TT::Data, "bar"}, Token{14, TT::Or, "oR"}, Token{19, TT::Data, "cuux"}, Token{23, TT::Xor, "XoR"}, Token{29, TT::Data, "fnorb"}}}, { "NOT (aap or mies)", Tokens{Token{3, TT::Not, "NOT"}, Token{5, TT::Open, "("}, Token{8, TT::Data, "aap"}, Token{11, TT::Or, "or"}, Token{16, TT::Data, "mies"}, Token{17, TT::Close, ")"}}} }; test_cases (cases); } static void test_escape () { CaseVec cases = { { "foo\"bar\"", Tokens{Token{8, TT::Data, "foobar"}}}, { "\"fnorb\"", Tokens{Token{7, TT::Data, "fnorb"}}}, { "\\\"fnorb\\\"", Tokens{Token{9, TT::Data, "fnorb"}}}, { "foo\\\"bar\\\"", Tokens{Token{10, TT::Data, "foobar"}}} }; test_cases (cases); } static void test_to_string () { std::stringstream ss; for (auto&& t: tokenize ("foo and bar xor not cuux or fnorb")) ss << t << ' '; g_assert_true (ss.str() == "3: [foo] 7: [and] 11: [bar] " "15: [xor] 19: [not] 24: [cuux] " "27: [or] 33: [fnorb] "); } int main (int argc, char *argv[]) { g_test_init (&argc, &argv, NULL); g_test_add_func ("/tokens/basic", test_basic); g_test_add_func ("/tokens/specials", test_specials); g_test_add_func ("/tokens/ops", test_ops); g_test_add_func ("/tokens/escape", test_escape); g_test_add_func ("/tokens/to-string", test_to_string); return g_test_run (); }