command-handler: rework for new sexp
Rework / cleanup the command-handler (and rename for command-parser). Update tests (and integrate with sources)
This commit is contained in:
@ -18,11 +18,6 @@
|
||||
################################################################################
|
||||
# tests
|
||||
#
|
||||
test('test-command-parser',
|
||||
executable('test-command-parser',
|
||||
'test-command-parser.cc',
|
||||
install: false,
|
||||
dependencies: [glib_dep, lib_mu_utils_dep]))
|
||||
test('test-mu-util',
|
||||
executable('test-mu-util',
|
||||
'test-mu-util.c',
|
||||
@ -38,8 +33,3 @@ test('test-mu-utils',
|
||||
'test-utils.cc',
|
||||
install: false,
|
||||
dependencies: [glib_dep, lib_mu_utils_dep]))
|
||||
test('test-sexp',
|
||||
executable('test-sexp',
|
||||
'test-sexp.cc',
|
||||
install: false,
|
||||
dependencies: [glib_dep, lib_mu_utils_dep] ))
|
||||
|
||||
@ -1,149 +0,0 @@
|
||||
/*
|
||||
** Copyright (C) 2022 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
**
|
||||
** 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 <vector>
|
||||
#include <glib.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "mu-command-parser.hh"
|
||||
#include "mu-utils.hh"
|
||||
#include "mu-test-utils.hh"
|
||||
|
||||
using namespace Mu;
|
||||
|
||||
static void
|
||||
test_param_getters()
|
||||
{
|
||||
const auto sexp{Sexp::make_parse(R"((foo :bar 123 :cuux "456" :boo nil :bah true))")};
|
||||
|
||||
if (g_test_verbose())
|
||||
std::cout << sexp << "\n";
|
||||
|
||||
g_assert_cmpint(Command::get_int_or(sexp.list(), ":bar"), ==, 123);
|
||||
assert_equal(Command::get_string_or(sexp.list(), ":bra", "bla"), "bla");
|
||||
assert_equal(Command::get_string_or(sexp.list(), ":cuux"), "456");
|
||||
|
||||
g_assert_true(Command::get_bool_or(sexp.list(), ":boo") == false);
|
||||
g_assert_true(Command::get_bool_or(sexp.list(), ":bah") == true);
|
||||
}
|
||||
|
||||
static bool
|
||||
call(const Command::CommandMap& cmap, const std::string& str)
|
||||
try {
|
||||
const auto sexp{Sexp::make_parse(str)};
|
||||
invoke(cmap, sexp);
|
||||
|
||||
return true;
|
||||
|
||||
} catch (const Error& err) {
|
||||
g_warning("%s", err.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
test_command()
|
||||
{
|
||||
using namespace Command;
|
||||
allow_warnings();
|
||||
|
||||
CommandMap cmap;
|
||||
|
||||
cmap.emplace(
|
||||
"my-command",
|
||||
CommandInfo{ArgMap{{":param1", ArgInfo{Sexp::Type::String, true, "some string"}},
|
||||
{":param2", ArgInfo{Sexp::Type::Number, false, "some integer"}}},
|
||||
"My command,",
|
||||
{}});
|
||||
|
||||
g_assert_true(call(cmap, "(my-command :param1 \"hello\")"));
|
||||
g_assert_true(call(cmap, "(my-command :param1 \"hello\" :param2 123)"));
|
||||
|
||||
g_assert_false(call(cmap, "(my-command :param1 \"hello\" :param2 123 :param3 xxx)"));
|
||||
}
|
||||
|
||||
static void
|
||||
test_command2()
|
||||
{
|
||||
using namespace Command;
|
||||
allow_warnings();
|
||||
|
||||
CommandMap cmap;
|
||||
cmap.emplace("bla",
|
||||
CommandInfo{ArgMap{
|
||||
{":foo", ArgInfo{Sexp::Type::Number, false, "foo"}},
|
||||
{":bar", ArgInfo{Sexp::Type::String, false, "bar"}},
|
||||
},
|
||||
"yeah",
|
||||
[&](const auto& params) {}});
|
||||
|
||||
g_assert_true(call(cmap, "(bla :foo nil)"));
|
||||
g_assert_false(call(cmap, "(bla :foo nil :bla nil)"));
|
||||
}
|
||||
|
||||
static void
|
||||
test_command_fail()
|
||||
{
|
||||
using namespace Command;
|
||||
|
||||
allow_warnings();
|
||||
|
||||
CommandMap cmap;
|
||||
|
||||
cmap.emplace(
|
||||
"my-command",
|
||||
CommandInfo{ArgMap{{":param1", ArgInfo{Sexp::Type::String, true, "some string"}},
|
||||
{":param2", ArgInfo{Sexp::Type::Number, false, "some integer"}}},
|
||||
"My command,",
|
||||
{}});
|
||||
|
||||
g_assert_false(call(cmap, "(my-command)"));
|
||||
g_assert_false(call(cmap, "(my-command2)"));
|
||||
g_assert_false(call(cmap, "(my-command :param1 123 :param2 123)"));
|
||||
g_assert_false(call(cmap, "(my-command :param1 \"hello\" :param2 \"123\")"));
|
||||
}
|
||||
|
||||
static void
|
||||
black_hole()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char* argv[]) try {
|
||||
|
||||
mu_test_init(&argc, &argv);
|
||||
|
||||
g_test_add_func("/utils/command-parser/param-getters", test_param_getters);
|
||||
g_test_add_func("/utils/command-parser/command", test_command);
|
||||
g_test_add_func("/utils/command-parser/command2", test_command2);
|
||||
g_test_add_func("/utils/command-parser/command-fail", test_command_fail);
|
||||
|
||||
g_log_set_handler(
|
||||
NULL,
|
||||
(GLogLevelFlags)(G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION),
|
||||
(GLogFunc)black_hole,
|
||||
NULL);
|
||||
|
||||
return g_test_run();
|
||||
|
||||
} catch (const std::runtime_error& re) {
|
||||
std::cerr << re.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
@ -1,190 +0,0 @@
|
||||
/*
|
||||
** Copyright (C) 2020 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
**
|
||||
** 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 <vector>
|
||||
#include <glib.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "mu-command-parser.hh"
|
||||
#include "mu-utils.hh"
|
||||
#include "mu-test-utils.hh"
|
||||
|
||||
using namespace Mu;
|
||||
|
||||
static bool
|
||||
check_parse(const std::string& expr, const std::string& expected)
|
||||
{
|
||||
try {
|
||||
const auto parsed{to_string(Sexp::make_parse(expr))};
|
||||
assert_equal(parsed, expected);
|
||||
return true;
|
||||
|
||||
} catch (const Error& err) {
|
||||
g_warning("caught exception parsing '%s': %s", expr.c_str(), err.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_parser()
|
||||
{
|
||||
check_parse(":foo-123", ":foo-123");
|
||||
check_parse("foo", "foo");
|
||||
check_parse(R"(12345)", "12345");
|
||||
check_parse(R"(-12345)", "-12345");
|
||||
check_parse(R"((123 bar "cuux"))", "(123 bar \"cuux\")");
|
||||
|
||||
check_parse(R"("foo\"bar\"cuux")", "\"foo\\\"bar\\\"cuux\"");
|
||||
|
||||
check_parse(R"("foo
|
||||
bar")",
|
||||
"\"foo\nbar\"");
|
||||
}
|
||||
|
||||
static void
|
||||
test_list()
|
||||
{
|
||||
const auto nstr{Sexp::make_string("foo")};
|
||||
g_assert_true(nstr.value() == "foo");
|
||||
g_assert_true(nstr.type() == Sexp::Type::String);
|
||||
assert_equal(nstr.to_sexp_string(), "\"foo\"");
|
||||
|
||||
const auto nnum{Sexp::make_number(123)};
|
||||
g_assert_true(nnum.value() == "123");
|
||||
g_assert_true(nnum.type() == Sexp::Type::Number);
|
||||
assert_equal(nnum.to_sexp_string(), "123");
|
||||
|
||||
const auto nsym{Sexp::make_symbol("blub")};
|
||||
g_assert_true(nsym.value() == "blub");
|
||||
g_assert_true(nsym.type() == Sexp::Type::Symbol);
|
||||
assert_equal(nsym.to_sexp_string(), "blub");
|
||||
|
||||
Sexp::List list;
|
||||
list.add(Sexp::make_string("foo"))
|
||||
.add(Sexp::make_number(123))
|
||||
.add(Sexp::make_symbol("blub"));
|
||||
|
||||
const auto nlst = Sexp::make_list(std::move(list));
|
||||
g_assert_true(nlst.list().size() == 3);
|
||||
g_assert_true(nlst.type() == Sexp::Type::List);
|
||||
g_assert_true(nlst.list().at(1).value() == "123");
|
||||
|
||||
assert_equal(nlst.to_sexp_string(), "(\"foo\" 123 blub)");
|
||||
}
|
||||
|
||||
static void
|
||||
test_prop_list()
|
||||
{
|
||||
Sexp::List l1;
|
||||
l1.add_prop(":foo", Sexp::make_string("bar"));
|
||||
Sexp s2{Sexp::make_list(std::move(l1))};
|
||||
assert_equal(s2.to_sexp_string(), "(:foo \"bar\")");
|
||||
g_assert_true(s2.is_prop_list());
|
||||
|
||||
Sexp::List l2;
|
||||
const std::string x{"bar"};
|
||||
l2.add_prop(":foo", Sexp::make_string(x));
|
||||
l2.add_prop(":bar", Sexp::make_number(77));
|
||||
Sexp::List l3;
|
||||
l3.add_prop(":cuux", Sexp::make_list(std::move(l2)));
|
||||
Sexp s3{Sexp::make_list(std::move(l3))};
|
||||
assert_equal(s3.to_sexp_string(), "(:cuux (:foo \"bar\" :bar 77))");
|
||||
}
|
||||
|
||||
static void
|
||||
test_props()
|
||||
{
|
||||
auto sexp2 = Sexp::make_list(Sexp::make_string("foo"),
|
||||
Sexp::make_number(123),
|
||||
Sexp::make_symbol("blub"));
|
||||
|
||||
auto sexp = Sexp::make_prop_list(":foo",
|
||||
Sexp::make_string("bär"),
|
||||
":cuux",
|
||||
Sexp::make_number(123),
|
||||
":flub",
|
||||
Sexp::make_symbol("fnord"),
|
||||
":boo",
|
||||
std::move(sexp2));
|
||||
|
||||
assert_equal(sexp.to_sexp_string(),
|
||||
"(:foo \"b\303\244r\" :cuux 123 :flub fnord :boo (\"foo\" 123 blub))");
|
||||
}
|
||||
|
||||
static void
|
||||
test_prop_list_remove()
|
||||
{
|
||||
{
|
||||
Sexp::List lst;
|
||||
lst.add_prop(":foo", Sexp::make_string("123"))
|
||||
.add_prop(":bar", Sexp::make_number(123));
|
||||
|
||||
assert_equal(Sexp::make_list(std::move(lst)).to_sexp_string(),
|
||||
R"((:foo "123" :bar 123))");
|
||||
}
|
||||
|
||||
{
|
||||
Sexp::List lst;
|
||||
lst.add_prop(":foo", Sexp::make_string("123"))
|
||||
.add_prop(":bar", Sexp::make_number(123));
|
||||
|
||||
assert_equal(Sexp::make_list(Sexp::List{lst}).to_sexp_string(),
|
||||
R"((:foo "123" :bar 123))");
|
||||
|
||||
lst.remove_prop(":bar");
|
||||
|
||||
assert_equal(Sexp::make_list(Sexp::List{lst}).to_sexp_string(),
|
||||
R"((:foo "123"))");
|
||||
|
||||
lst.clear();
|
||||
g_assert_cmpuint(lst.size(), ==, 0);
|
||||
}
|
||||
|
||||
{
|
||||
Sexp::List lst;
|
||||
lst.add(Sexp::make_number(123));
|
||||
Sexp s2{Sexp::make_list(std::move(lst))};
|
||||
g_assert_false(s2.is_prop_list());
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
try {
|
||||
mu_test_init(&argc, &argv);
|
||||
|
||||
if (argc == 2) {
|
||||
std::cout << Sexp::make_parse(argv[1]) << '\n';
|
||||
return 0;
|
||||
}
|
||||
|
||||
g_test_add_func("/utils/sexp/parser", test_parser);
|
||||
g_test_add_func("/utils/sexp/list", test_list);
|
||||
g_test_add_func("/utils/sexp/proplist", test_prop_list);
|
||||
g_test_add_func("/utils/sexp/proplist-remove", test_prop_list_remove);
|
||||
g_test_add_func("/utils/sexp/props", test_props);
|
||||
|
||||
return g_test_run();
|
||||
|
||||
} catch (const std::runtime_error& re) {
|
||||
std::cerr << re.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
Reference in New Issue
Block a user