Mercurial > irccd
changeset 312:a0180b5a150c
Tests: add test for plugin-config, #559
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sat, 22 Oct 2016 15:56:01 +0200 |
parents | fa184c88b2c3 |
children | d2b02e31478d |
files | libirccd/irccd/cmd-plugin-config.cpp libirccd/irccd/cmd-plugin-config.hpp tests/CMakeLists.txt tests/cmd-plugin-config/CMakeLists.txt tests/cmd-plugin-config/main.cpp |
diffstat | 5 files changed, 219 insertions(+), 99 deletions(-) [+] |
line wrap: on
line diff
--- a/libirccd/irccd/cmd-plugin-config.cpp Fri Oct 21 20:28:50 2016 +0200 +++ b/libirccd/irccd/cmd-plugin-config.cpp Sat Oct 22 15:56:01 2016 +0200 @@ -16,12 +16,11 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <iomanip> -#include <iostream> - #include "irccd.hpp" #include "cmd-plugin-config.hpp" #include "service-plugin.hpp" +#include "transport.hpp" +#include "util.hpp" namespace irccd { @@ -29,101 +28,63 @@ namespace { -nlohmann::json execSet(Irccd &irccd, const nlohmann::json &request, const std::string &var, const std::string &value) +void execSet(Irccd &, TransportClient &client, Plugin &plugin, const nlohmann::json &args) { - auto plugin = irccd.plugins().require(request["plugin"].get<std::string>()); - auto config = plugin->config(); + assert(args.count("value") > 0); + + auto var = args.find("variable"); + auto value = args.find("value"); - config[var] = value; - plugin->setConfig(config); + if (var == args.end() || !var->is_string()) + client.error("plugin-config", "missing 'variable' property (string expected)"); + else if (!value->is_string()) + client.error("plugin-config", "invalid 'value' property (string expected)"); + else { + auto config = plugin.config(); - return nullptr; + config[*var] = *value; + plugin.setConfig(config); + client.success("plugin-config"); + } } -nlohmann::json execGet(Irccd &irccd, const nlohmann::json &request, const nlohmann::json::const_iterator &var) +void execGet(Irccd &, TransportClient &client, Plugin &plugin, const nlohmann::json &args) { - auto config = irccd.plugins().require(request["plugin"].get<std::string>())->config(); - - // 'vars' property. - std::map<std::string, nlohmann::json> vars; + auto variables = nlohmann::json::object(); + auto var = args.find("variable"); - if (var != request.end()) - vars.emplace(var->get<std::string>(), config[var->get<std::string>()]); + if (var != args.end() && var->is_string()) + variables[var->get<std::string>()] = plugin.config()[*var]; else - for (const auto &pair : config) - vars.emplace(pair.first, pair.second); + for (const auto &pair : plugin.config()) + variables[pair.first] = pair.second; - return nlohmann::json::object({{ "variables", nlohmann::json(vars) }}); + /* + * Don't put all variables into the response, put them into a sub property + * 'variables' instead. + * + * It's easier for the client to iterate over all. + */ + client.success("plugin-config", { + { "variables", variables } + }); } } // !namespace PluginConfigCommand::PluginConfigCommand() - : Command("plugin-config", "Plugins", "Get or set a plugin config variable") + : Command("plugin-config") { } -std::vector<Command::Arg> PluginConfigCommand::args() const -{ - return { - { "plugin", true }, - { "variable", false }, - { "value", false } - }; -} - -std::vector<Command::Property> PluginConfigCommand::properties() const +void PluginConfigCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) { - return {{ "plugin", { nlohmann::json::value_t::string }}}; -} - -nlohmann::json PluginConfigCommand::request(Irccdctl &, const CommandRequest &args) const -{ - auto object = nlohmann::json::object({ - { "plugin", args.arg(0) } - }); - - if (args.length() >= 2U) { - object.push_back({"variable", args.arg(1)}); - - if (args.length() == 3U) - object.push_back({"value", args.arg(2)}); - } - - return object; -} + auto plugin = irccd.plugins().require(util::json::requireIdentifier(args, "plugin")); -nlohmann::json PluginConfigCommand::exec(Irccd &irccd, const nlohmann::json &request) const -{ - Command::exec(irccd, request); - - auto var = request.find("variable"); - - if (var != request.end() && var->is_string()) - throw InvalidPropertyError("variable", nlohmann::json::value_t::string, var->type()); - - auto value = request.find("value"); - - if (value != request.end()) - return execSet(irccd, request, var->dump(), value->dump()); - - return execGet(irccd, request, var); -} - -void PluginConfigCommand::result(Irccdctl &irccdctl, const nlohmann::json &response) const -{ - Command::result(irccdctl, response); - - auto it = response.find("variables"); - - if (it == response.end() || !it->is_object()) - return; - - if (it->size() > 1U) - for (auto v = it->begin(); v != it->end(); ++v) - std::cout << std::setw(16) << std::left << v.key() << " : " << v->dump() << std::endl; + if (args.count("value") > 0) + execSet(irccd, client, *plugin, args); else - std::cout << it->begin()->dump() << std::endl; + execGet(irccd, client, *plugin, args); } } // !command
--- a/libirccd/irccd/cmd-plugin-config.hpp Fri Oct 21 20:28:50 2016 +0200 +++ b/libirccd/irccd/cmd-plugin-config.hpp Sat Oct 22 15:56:01 2016 +0200 @@ -41,29 +41,9 @@ IRCCD_EXPORT PluginConfigCommand(); /** - * \copydoc Command::args - */ - IRCCD_EXPORT std::vector<Arg> args() const override; - - /** - * \copydoc Command::properties - */ - IRCCD_EXPORT std::vector<Property> properties() const override; - - /** - * \copydoc Command::request - */ - IRCCD_EXPORT nlohmann::json request(Irccdctl &irccdctl, const CommandRequest &args) const override; - - /** * \copydoc Command::exec */ - IRCCD_EXPORT nlohmann::json exec(Irccd &irccd, const nlohmann::json &request) const override; - - /** - * \copydoc Command::result - */ - IRCCD_EXPORT void result(Irccdctl &irccdctl, const nlohmann::json &response) const override; + IRCCD_EXPORT void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; }; } // !command
--- a/tests/CMakeLists.txt Fri Oct 21 20:28:50 2016 +0200 +++ b/tests/CMakeLists.txt Sat Oct 22 15:56:01 2016 +0200 @@ -20,6 +20,7 @@ project(tests) if (WITH_TESTS) + add_subdirectory(cmd-plugin-config) add_subdirectory(cmd-server-cmode) add_subdirectory(cmd-server-cnotice) add_subdirectory(cmd-server-connect)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/cmd-plugin-config/CMakeLists.txt Sat Oct 22 15:56:01 2016 +0200 @@ -0,0 +1,24 @@ +# +# CMakeLists.txt -- CMake build system for irccd +# +# Copyright (c) 2013-2016 David Demelier <markand@malikania.fr> +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +irccd_define_test( + NAME cmd-plugin-config + SOURCES main.cpp + LIBRARIES libirccd libirccdctl +) +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/cmd-plugin-config/main.cpp Sat Oct 22 15:56:01 2016 +0200 @@ -0,0 +1,154 @@ +/* + * main.cpp -- test plugin-config remote command + * + * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <cmd-plugin-config.hpp> +#include <command-tester.hpp> +#include <server-tester.hpp> +#include <service-plugin.hpp> + +using namespace irccd; +using namespace irccd::command; + +namespace { + +struct CustomPlugin : public Plugin { + PluginConfig m_config; + + CustomPlugin(std::string name = "test") + : Plugin(std::move(name), "") + { + } + + PluginConfig config() override + { + return m_config; + } + + void setConfig(PluginConfig config) override + { + m_config = std::move(config); + } +}; + + + +class PluginConfigCommandTest : public CommandTester { +public: + PluginConfigCommandTest() + : CommandTester(std::make_unique<PluginConfigCommand>()) + { + } +}; + +TEST_F(PluginConfigCommandTest, set) +{ + try { + m_irccd.plugins().add(std::make_unique<CustomPlugin>("test")); + m_irccdctl.client().request({ + { "command", "plugin-config" }, + { "plugin", "test" }, + { "variable", "verbosy" }, + { "value", "falsy" } + }); + + poll([&] { + return !m_irccd.plugins().require("test")->config().empty(); + }); + + auto config = m_irccd.plugins().require("test")->config(); + + ASSERT_FALSE(config.empty()); + ASSERT_EQ("falsy", config["verbosy"]); + } catch (const std::exception &ex) { + FAIL() << ex.what(); + } +} + +TEST_F(PluginConfigCommandTest, get) +{ + try { + auto plugin = std::make_unique<CustomPlugin>("test"); + auto json = nlohmann::json(); + + plugin->setConfig({ + { "x1", "10" }, + { "x2", "20" } + }); + + m_irccd.plugins().add(std::move(plugin)); + m_irccdctl.client().request({ + { "command", "plugin-config" }, + { "plugin", "test" }, + { "variable", "x1" } + }); + m_irccdctl.client().onMessage.connect([&] (auto message) { + json = std::move(message); + }); + + poll([&] { + return json.is_object(); + }); + + ASSERT_TRUE(json.is_object()); + ASSERT_EQ("10", json["variables"]["x1"]); + ASSERT_TRUE(json["variables"]["x2"].is_null()); + } catch (const std::exception &ex) { + FAIL() << ex.what(); + } +} + +TEST_F(PluginConfigCommandTest, getAll) +{ + try { + auto plugin = std::make_unique<CustomPlugin>("test"); + auto json = nlohmann::json(); + + plugin->setConfig({ + { "x1", "10" }, + { "x2", "20" } + }); + + m_irccd.plugins().add(std::move(plugin)); + m_irccdctl.client().request({ + { "command", "plugin-config" }, + { "plugin", "test" } + }); + m_irccdctl.client().onMessage.connect([&] (auto message) { + json = std::move(message); + }); + + poll([&] { + return json.is_object(); + }); + + ASSERT_TRUE(json.is_object()); + ASSERT_EQ("10", json["variables"]["x1"]); + ASSERT_EQ("20", json["variables"]["x2"]); + } catch (const std::exception &ex) { + FAIL() << ex.what(); + } +} + +} // !namespace + +int main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +}