changeset 830:4f7e46e593fe

tests: use command directly, closes #991 @4h
author David Demelier <markand@malikania.fr>
date Mon, 11 Feb 2019 20:30:00 +0100
parents 963feffc07fe
children 7b012c42660c
files libirccd-daemon/irccd/daemon.hpp libirccd-test/CMakeLists.txt libirccd-test/irccd/test.hpp libirccd-test/irccd/test/command_fixture.cpp libirccd-test/irccd/test/command_fixture.hpp libirccd-test/irccd/test/mock_stream.cpp libirccd-test/irccd/test/mock_stream.hpp libirccd-test/irccd/test/mock_transport_client.hpp tests/src/libirccd-daemon/command-plugin-config/main.cpp tests/src/libirccd-daemon/command-plugin-info/main.cpp tests/src/libirccd-daemon/command-plugin-list/main.cpp tests/src/libirccd-daemon/command-plugin-load/main.cpp tests/src/libirccd-daemon/command-plugin-reload/main.cpp tests/src/libirccd-daemon/command-plugin-unload/main.cpp tests/src/libirccd-daemon/command-rule-add/main.cpp tests/src/libirccd-daemon/command-rule-edit/main.cpp tests/src/libirccd-daemon/command-rule-info/main.cpp tests/src/libirccd-daemon/command-rule-list/main.cpp tests/src/libirccd-daemon/command-rule-move/main.cpp tests/src/libirccd-daemon/command-rule-remove/main.cpp tests/src/libirccd-daemon/command-server-connect/main.cpp tests/src/libirccd-daemon/command-server-disconnect/main.cpp tests/src/libirccd-daemon/command-server-info/main.cpp tests/src/libirccd-daemon/command-server-invite/main.cpp tests/src/libirccd-daemon/command-server-join/main.cpp tests/src/libirccd-daemon/command-server-kick/main.cpp tests/src/libirccd-daemon/command-server-list/main.cpp tests/src/libirccd-daemon/command-server-me/main.cpp tests/src/libirccd-daemon/command-server-message/main.cpp tests/src/libirccd-daemon/command-server-mode/main.cpp tests/src/libirccd-daemon/command-server-nick/main.cpp tests/src/libirccd-daemon/command-server-notice/main.cpp tests/src/libirccd-daemon/command-server-part/main.cpp tests/src/libirccd-daemon/command-server-reconnect/main.cpp tests/src/libirccd-daemon/command-server-topic/main.cpp
diffstat 35 files changed, 879 insertions(+), 841 deletions(-) [+]
line wrap: on
line diff
--- a/libirccd-daemon/irccd/daemon.hpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/libirccd-daemon/irccd/daemon.hpp	Mon Feb 11 20:30:00 2019 +0100
@@ -26,22 +26,22 @@
 
 #include "sysconfig.hpp"
 
-#include "daemon/server_service.hpp"
+#include "daemon/bot.hpp"
+#include "daemon/dynlib_plugin.hpp"
+#include "daemon/irc.hpp"
+#include "daemon/logger.hpp"
 #include "daemon/plugin.hpp"
 #include "daemon/plugin_service.hpp"
-#include "daemon/command.hpp"
+#include "daemon/rule.hpp"
 #include "daemon/rule_service.hpp"
-#include "daemon/bot.hpp"
-#include "daemon/rule.hpp"
-#include "daemon/logger.hpp"
+#include "daemon/rule_util.hpp"
+#include "daemon/server.hpp"
+#include "daemon/server_service.hpp"
+#include "daemon/server_util.hpp"
 #include "daemon/transport_client.hpp"
-#include "daemon/rule_util.hpp"
-#include "daemon/server_util.hpp"
-#include "daemon/transport_util.hpp"
+#include "daemon/transport_command.hpp"
 #include "daemon/transport_server.hpp"
 #include "daemon/transport_service.hpp"
-#include "daemon/dynlib_plugin.hpp"
-#include "daemon/irc.hpp"
-#include "daemon/server.hpp"
+#include "daemon/transport_util.hpp"
 
 #endif // !IRCCD_DAEMON_HPP
--- a/libirccd-test/CMakeLists.txt	Thu Feb 07 11:42:49 2019 +0100
+++ b/libirccd-test/CMakeLists.txt	Mon Feb 11 20:30:00 2019 +0100
@@ -37,6 +37,8 @@
 	${libirccd-test_SOURCE_DIR}/irccd/test/mock_plugin.hpp
 	${libirccd-test_SOURCE_DIR}/irccd/test/mock_server.cpp
 	${libirccd-test_SOURCE_DIR}/irccd/test/mock_server.hpp
+	${libirccd-test_SOURCE_DIR}/irccd/test/mock_stream.cpp
+	${libirccd-test_SOURCE_DIR}/irccd/test/mock_stream.hpp
 	${libirccd-test_SOURCE_DIR}/irccd/test/test_plugin_loader.cpp
 	${libirccd-test_SOURCE_DIR}/irccd/test/test_plugin_loader.hpp
 )
--- a/libirccd-test/irccd/test.hpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/libirccd-test/irccd/test.hpp	Mon Feb 11 20:30:00 2019 +0100
@@ -36,6 +36,7 @@
 #include "test/mock.hpp"
 #include "test/mock_plugin.hpp"
 #include "test/mock_server.hpp"
+#include "test/mock_stream.hpp"
 #include "test/test_plugin_loader.hpp"
 
 #endif // !IRCCD_TEST_HPP
--- a/libirccd-test/irccd/test/command_fixture.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/libirccd-test/irccd/test/command_fixture.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -16,8 +16,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <irccd/acceptor.hpp>
-#include <irccd/connector.hpp>
+#include <stdexcept>
 
 #include <irccd/daemon/transport_command.hpp>
 #include <irccd/daemon/transport_server.hpp>
@@ -25,114 +24,18 @@
 
 #include "command_fixture.hpp"
 
-namespace asio = boost::asio;
-namespace posix_time = boost::posix_time;
-
 namespace irccd::test {
 
-auto command_fixture::recv(asio::deadline_timer& timer) -> result
-{
-	result r;
-
-	ctl_->recv([&] (auto code, auto message) {
-		r.first = message;
-		r.second = code;
-	});
-
-	while (!r.first.is_object() && !r.second) {
-		ctx_.poll();
-		ctx_.reset();
-	}
-
-	timer.cancel();
-
-	return r;
-}
-
-auto command_fixture::wait_command(const std::string& cmd) -> result
-{
-	result r;
-	asio::deadline_timer timer(bot_.get_service());
-
-	timer.expires_from_now(posix_time::seconds(30));
-	timer.async_wait([] (auto code) {
-		if (code != asio::error::operation_aborted)
-			throw std::runtime_error("operation timed out");
-	});
-
-	for (;;) {
-		r = recv(timer);
-
-		if (r.second)
-			break;
-		if (r.first.is_object() &&
-		    r.first["command"].is_string() &&
-		    r.first["command"].get<std::string>() == cmd)
-			break;
-
-		ctx_.poll();
-		ctx_.reset();
-	}
-
-	return r;
-}
-
-auto command_fixture::request(nlohmann::json json) -> result
-{
-	ctl_->send(json, [] (auto code) {
-		if (code)
-			throw std::system_error(std::move(code));
-	});
-
-	return wait_command(json["command"].get<std::string>());
-}
-
 command_fixture::command_fixture()
 	: server_(new mock_server(ctx_, "test", "localhost"))
 	, plugin_(new mock_plugin("test"))
+	, stream_(new mock_stream)
+	, client_(new daemon::transport_client({}, stream_))
 {
-	asio::ip::tcp::endpoint ep(asio::ip::tcp::v4(), 0U);
-	asio::ip::tcp::acceptor raw_acceptor(bot_.get_service(), std::move(ep));
-
-	auto service = std::to_string(raw_acceptor.local_endpoint().port());
-	auto acceptor = std::make_unique<ip_acceptor>(bot_.get_service(), std::move(raw_acceptor));
-	auto connector = std::make_unique<ip_connector>(bot_.get_service(), "127.0.0.1", service, true, false);
-
 	// 1. Add all commands.
 	for (const auto& f : daemon::transport_command::registry())
 		bot_.transports().get_commands().push_back(f());
 
-	// 2. Create controller and transport server.
-	ctl_ = std::make_unique<ctl::controller>(std::move(connector));
-	bot_.transports().add(std::make_unique<daemon::transport_server>(std::move(acceptor)));
-
-	// 3. Wait for controller to connect.
-	asio::deadline_timer timer(ctx_);
-
-	timer.expires_from_now(posix_time::seconds(10));
-	timer.async_wait([] (auto code) {
-		if (code && code != asio::error::operation_aborted)
-			throw std::system_error(make_error_code(std::errc::timed_out));
-	});
-
-	bool connected = false;
-
-	ctl_->connect([&] (auto code, auto) {
-		timer.cancel();
-
-		if (code)
-			throw std::system_error(code);
-
-		connected = true;
-	});
-
-	/**
-	 * Irccd will block indefinitely since transport_service will wait for any
-	 * new client again, so we need to check with a boolean.
-	 */
-	while (!connected)
-		ctx_.poll();
-
 	bot_.servers().add(server_);
 	bot_.plugins().add(plugin_);
 	server_->disconnect();
@@ -140,4 +43,28 @@
 	plugin_->clear();
 }
 
+auto command_fixture::request(nlohmann::json json) -> nlohmann::json
+{
+	const auto& list = bot_.transports().get_commands();
+	const auto cmd = std::find_if(list.begin(), list.end(), [&] (const auto& c) {
+		return c->get_name() == json["command"].template get<std::string>();
+	});
+
+	if (cmd == list.end())
+		throw std::runtime_error("command not found");
+
+	try {
+		(*cmd)->exec(bot_, *client_, json);
+	} catch (const std::system_error& ex) {
+		client_->error(ex.code(), (*cmd)->get_name());
+	}
+
+	const auto& queue = stream_->find("send");
+
+	if (queue.size() > 0)
+		return nlohmann::json::parse(std::any_cast<std::string>(queue[0][0]));
+
+	return nullptr;
+}
+
 } // !irccd::test
--- a/libirccd-test/irccd/test/command_fixture.hpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/libirccd-test/irccd/test/command_fixture.hpp	Mon Feb 11 20:30:00 2019 +0100
@@ -27,12 +27,12 @@
 #include <irccd/daemon/plugin_service.hpp>
 #include <irccd/daemon/rule_service.hpp>
 #include <irccd/daemon/server_service.hpp>
-
-#include <irccd/ctl/controller.hpp>
+#include <irccd/daemon/transport_client.hpp>
 
 #include "irccd_fixture.hpp"
 #include "mock_server.hpp"
 #include "mock_plugin.hpp"
+#include "mock_stream.hpp"
 
 namespace irccd::test {
 
@@ -45,32 +45,6 @@
 class command_fixture : public irccd_fixture {
 protected:
 	/**
-	 * \brief Result for request function.
-	 */
-	using result = std::pair<nlohmann::json, std::error_code>;
-
-	/**
-	 * Block for the next message.
-	 *
-	 * \param timer the timer to cancel on completion
-	 * \return the next message
-	 */
-	auto recv(boost::asio::deadline_timer& timer) -> result;
-
-	/**
-	 * Block for the next command with a maximum timeout.
-	 *
-	 * \return the result
-	 * \throw std::runtime_error after 30 seconds
-	 */
-	auto wait_command(const std::string& cmd) -> result;
-
-	/**
-	 * \brief Irccd controller
-	 */
-	std::unique_ptr<ctl::controller> ctl_;
-
-	/**
 	 * \brief Mock server object.
 	 */
 	std::shared_ptr<mock_server> server_;
@@ -81,6 +55,15 @@
 	std::shared_ptr<mock_plugin> plugin_;
 
 	/**
+	 * \brief The fake transport_client stream.
+	 */
+	std::shared_ptr<mock_stream> stream_;
+	/**
+	 * \brief Client sending request.
+	 */
+	std::shared_ptr<daemon::transport_client> client_;
+
+	/**
 	 * Constructor.
 	 */
 	command_fixture();
@@ -89,9 +72,9 @@
 	 * Get result from irccd.
 	 *
 	 * \param json the request
-	 * \return the result/error pair
+	 * \return the json message sent (if any)
 	 */
-	auto request(nlohmann::json json) -> result;
+	auto request(nlohmann::json json) -> nlohmann::json;
 };
 
 } // !irccd::test
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libirccd-test/irccd/test/mock_stream.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -0,0 +1,34 @@
+/*
+ * mock_stream.cpp -- mock stream
+ *
+ * Copyright (c) 2013-2019 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 "mock_stream.hpp"
+
+namespace irccd::test {
+
+void mock_stream::recv(recv_handler handler)
+{
+	push("recv", {handler});
+}
+
+void mock_stream::send(const nlohmann::json& json, send_handler handler)
+{
+	push("send", {json.dump(0), handler});
+	handler({});
+}
+
+} // !irccd::test
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libirccd-test/irccd/test/mock_stream.hpp	Mon Feb 11 20:30:00 2019 +0100
@@ -0,0 +1,51 @@
+/*
+ * mock_stream.hpp -- mock stream
+ *
+ * Copyright (c) 2013-2019 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.
+ */
+
+#ifndef IRCCD_TEST_MOCK_STREAM_HPP
+#define IRCCD_TEST_MOCK_STREAM_HPP
+
+/**
+ * \file mock_stream.hpp
+ * \brief Mock stream.
+ */
+
+#include <irccd/stream.hpp>
+
+#include "mock.hpp"
+
+namespace irccd::test {
+
+/**
+ * \brief Mock stream.
+ */
+class mock_stream : public stream, public mock {
+public:
+	/**
+	 * \copydoc stream::recv
+	 */
+	void recv(recv_handler handler) override;
+
+	/**
+	 * \copydoc stream::send
+	 */
+	void send(const nlohmann::json& json, send_handler handler) override;
+};
+
+} // !irccd::test
+
+#endif // !IRCCD_TEST_MOCK_STREAM_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libirccd-test/irccd/test/mock_transport_client.hpp	Mon Feb 11 20:30:00 2019 +0100
@@ -0,0 +1,10 @@
+#ifndef IRCCD_TEST_MOCK_TRANSPORT_CLIENT_HPP
+#define IRCCD_TEST_MOCK_TRANSPORT_CLIENT_HPP
+
+namespace irccd::test {
+
+class
+
+} // !irccd::test
+
+#endif // !IRCCD_TEST_MOCK_TRANSPORT_CLIENT_HPP
--- a/tests/src/libirccd-daemon/command-plugin-config/main.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/tests/src/libirccd-daemon/command-plugin-config/main.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -34,7 +34,7 @@
 
 BOOST_AUTO_TEST_CASE(set)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "plugin-config" },
 		{ "plugin",     "test"          },
 		{ "variable",   "verbosy"       },
@@ -43,7 +43,8 @@
 
 	const auto config = bot_.plugins().require("test")->get_options();
 
-	BOOST_TEST(!code);
+	BOOST_TEST(json.size() == 1U);
+	BOOST_TEST(json["command"].get<std::string>() == "plugin-config");
 	BOOST_TEST(!config.empty());
 	BOOST_TEST(config.at("verbosy") == "falsy");
 }
@@ -59,13 +60,14 @@
 	bot_.plugins().clear();
 	bot_.plugins().add(std::move(plugin));
 
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "plugin-config" },
 		{ "plugin",     "test"          },
 		{ "variable",   "x1"            }
 	});
 
-	BOOST_TEST(!code);
+	BOOST_TEST(json.size() == 2U);
+	BOOST_TEST(json["command"].get<std::string>() == "plugin-config");
 	BOOST_TEST(json["variables"]["x1"].get<std::string>() == "10");
 	BOOST_TEST(json["variables"].count("x2") == 0U);
 }
@@ -81,12 +83,13 @@
 	bot_.plugins().clear();
 	bot_.plugins().add(std::move(plugin));
 
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "plugin-config" },
 		{ "plugin",     "test"          }
 	});
 
-	BOOST_TEST(!code);
+	BOOST_TEST(json.size() == 2U);
+	BOOST_TEST(json["command"].get<std::string>() == "plugin-config");
 	BOOST_TEST(json["variables"]["x1"].get<std::string>() == "10");
 	BOOST_TEST(json["variables"]["x2"].get<std::string>() == "20");
 }
@@ -95,23 +98,25 @@
 
 BOOST_AUTO_TEST_CASE(invalid_identifier)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command", "plugin-config" }
 	});
 
-	BOOST_TEST(code == plugin_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "plugin-config");
 	BOOST_TEST(json["error"].get<int>() == plugin_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "plugin");
 }
 
 BOOST_AUTO_TEST_CASE(not_found)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "plugin-config" },
 		{ "plugin",     "unknown"       }
 	});
 
-	BOOST_TEST(code == plugin_error::not_found);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "plugin-config");
 	BOOST_TEST(json["error"].get<int>() == plugin_error::not_found);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "plugin");
 }
--- a/tests/src/libirccd-daemon/command-plugin-info/main.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/tests/src/libirccd-daemon/command-plugin-info/main.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -21,25 +21,21 @@
 
 #include <irccd/test/command_fixture.hpp>
 
-using irccd::test::command_fixture;
-using irccd::test::mock_plugin;
-
-using irccd::daemon::plugin_error;
-
 namespace irccd {
 
 namespace {
 
-BOOST_FIXTURE_TEST_SUITE(plugin_info_test_suite, command_fixture)
+BOOST_FIXTURE_TEST_SUITE(plugin_info_test_suite, test::command_fixture)
 
 BOOST_AUTO_TEST_CASE(basic)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "plugin-info"   },
 		{ "plugin",     "test"          },
 	});
 
-	BOOST_TEST(!code);
+	BOOST_TEST(json.size() == 5U);
+	BOOST_TEST(json["command"].get<std::string>() == "plugin-info");
 	BOOST_TEST(json["author"].get<std::string>() == "David Demelier <markand@malikania.fr>");
 	BOOST_TEST(json["license"].get<std::string>() == "ISC");
 	BOOST_TEST(json["summary"].get<std::string>() == "mock plugin");
@@ -50,24 +46,26 @@
 
 BOOST_AUTO_TEST_CASE(invalid_identifier)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command", "plugin-info" }
 	});
 
-	BOOST_TEST(code == plugin_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == plugin_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "plugin-info");
+	BOOST_TEST(json["error"].get<int>() == daemon::plugin_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "plugin");
 }
 
 BOOST_AUTO_TEST_CASE(not_found)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "plugin-info"   },
 		{ "plugin",     "unknown"       }
 	});
 
-	BOOST_TEST(code == plugin_error::not_found);
-	BOOST_TEST(json["error"].get<int>() == plugin_error::not_found);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "plugin-info");
+	BOOST_TEST(json["error"].get<int>() == daemon::plugin_error::not_found);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "plugin");
 }
 
--- a/tests/src/libirccd-daemon/command-plugin-list/main.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/tests/src/libirccd-daemon/command-plugin-list/main.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -21,20 +21,17 @@
 
 #include <irccd/test/command_fixture.hpp>
 
-using irccd::test::command_fixture;
-using irccd::test::mock_plugin;
-
 namespace irccd {
 
 namespace {
 
-class plugin_list_fixture : public command_fixture {
+class plugin_list_fixture : public test::command_fixture {
 public:
 	plugin_list_fixture()
 	{
 		bot_.plugins().clear();
-		bot_.plugins().add(std::make_unique<mock_plugin>("t1"));
-		bot_.plugins().add(std::make_unique<mock_plugin>("t2"));
+		bot_.plugins().add(std::make_unique<test::mock_plugin>("t1"));
+		bot_.plugins().add(std::make_unique<test::mock_plugin>("t2"));
 	}
 };
 
@@ -42,12 +39,12 @@
 
 BOOST_AUTO_TEST_CASE(basic)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command", "plugin-list" }
 	});
 
-	BOOST_TEST(!code);
-	BOOST_TEST(json.is_object());
+	BOOST_TEST(json.size() == 2U);
+	BOOST_TEST(json["command"].get<std::string>() == "plugin-list");
 	BOOST_TEST(json["list"][0].get<std::string>() == "t1");
 	BOOST_TEST(json["list"][1].get<std::string>() == "t2");
 }
--- a/tests/src/libirccd-daemon/command-plugin-load/main.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/tests/src/libirccd-daemon/command-plugin-load/main.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -21,24 +21,16 @@
 
 #include <irccd/test/command_fixture.hpp>
 
-using irccd::test::command_fixture;
-using irccd::test::mock_plugin;
-
-using irccd::daemon::bot;
-using irccd::daemon::plugin;
-using irccd::daemon::plugin_error;
-using irccd::daemon::plugin_loader;
-
 namespace irccd {
 
 namespace {
 
-class plugin_load_fixture : public command_fixture {
+class plugin_load_fixture : public test::command_fixture {
 public:
 	plugin_load_fixture()
 	{
 		bot_.plugins().clear();
-		bot_.plugins().add(std::make_unique<mock_plugin>("already"));
+		bot_.plugins().add(std::make_unique<test::mock_plugin>("already"));
 	}
 };
 
@@ -48,12 +40,13 @@
 
 BOOST_AUTO_TEST_CASE(basic)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "plugin-load"   },
 		{ "plugin",     "mock"          }
 	});
 
-	BOOST_TEST(!code);
+	BOOST_TEST(json.size() == 1U);
+	BOOST_TEST(json["command"].get<std::string>() == "plugin-load");
 	BOOST_TEST(bot_.plugins().has("mock"));
 }
 
@@ -61,48 +54,52 @@
 
 BOOST_AUTO_TEST_CASE(invalid_identifier)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command", "plugin-load" }
 	});
 
-	BOOST_TEST(code == plugin_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == plugin_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "plugin-load");
+	BOOST_TEST(json["error"].get<int>() == daemon::plugin_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "plugin");
 }
 
 BOOST_AUTO_TEST_CASE(not_found)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "plugin-load"   },
 		{ "plugin",     "unknown"       }
 	});
 
-	BOOST_TEST(code == plugin_error::not_found);
-	BOOST_TEST(json["error"].get<int>() == plugin_error::not_found);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "plugin-load");
+	BOOST_TEST(json["error"].get<int>() == daemon::plugin_error::not_found);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "plugin");
 }
 
 BOOST_AUTO_TEST_CASE(already_exists)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "plugin-load"   },
 		{ "plugin",     "already"       }
 	});
 
-	BOOST_TEST(code == plugin_error::already_exists);
-	BOOST_TEST(json["error"].get<int>() == plugin_error::already_exists);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "plugin-load");
+	BOOST_TEST(json["error"].get<int>() == daemon::plugin_error::already_exists);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "plugin");
 }
 
 BOOST_AUTO_TEST_CASE(exec_error)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "plugin-load"   },
 		{ "plugin",     "broken"        }
 	});
 
-	BOOST_TEST(code == plugin_error::exec_error);
-	BOOST_TEST(json["error"].get<int>() == plugin_error::exec_error);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "plugin-load");
+	BOOST_TEST(json["error"].get<int>() == daemon::plugin_error::exec_error);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "plugin");
 }
 
--- a/tests/src/libirccd-daemon/command-plugin-reload/main.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/tests/src/libirccd-daemon/command-plugin-reload/main.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -22,28 +22,19 @@
 #include <irccd/test/broken_plugin.hpp>
 #include <irccd/test/command_fixture.hpp>
 
-using irccd::test::broken_plugin;
-using irccd::test::command_fixture;
-using irccd::test::mock_plugin;
-
-using irccd::daemon::bot;
-using irccd::daemon::plugin;
-using irccd::daemon::plugin_error;
-using irccd::daemon::plugin_loader;
-
 namespace irccd {
 
 namespace {
 
-class plugin_reload_fixture : public command_fixture {
+class plugin_reload_fixture : public test::command_fixture {
 protected:
-	std::shared_ptr<mock_plugin> plugin_{new mock_plugin("test")};
+	std::shared_ptr<test::mock_plugin> plugin_{new test::mock_plugin("test")};
 
 	plugin_reload_fixture()
 	{
 		bot_.plugins().clear();
 		bot_.plugins().add(plugin_);
-		bot_.plugins().add(std::make_unique<broken_plugin>("broken"));
+		bot_.plugins().add(std::make_unique<test::broken_plugin>("broken"));
 	}
 };
 
@@ -51,12 +42,13 @@
 
 BOOST_AUTO_TEST_CASE(basic)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "plugin-reload" },
 		{ "plugin",     "test"          }
 	});
 
-	BOOST_TEST(!code);
+	BOOST_TEST(json.size() == 1U);
+	BOOST_TEST(json["command"].get<std::string>() == "plugin-reload");
 	BOOST_TEST(plugin_->find("handle_reload").size() == 1U);
 }
 
@@ -64,36 +56,39 @@
 
 BOOST_AUTO_TEST_CASE(invalid_identifier)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command", "plugin-reload" }
 	});
 
-	BOOST_TEST(code == plugin_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == plugin_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "plugin-reload");
+	BOOST_TEST(json["error"].get<int>() == daemon::plugin_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "plugin");
 }
 
 BOOST_AUTO_TEST_CASE(not_found)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "plugin-reload" },
 		{ "plugin",     "unknown"       }
 	});
 
-	BOOST_TEST(code == plugin_error::not_found);
-	BOOST_TEST(json["error"].get<int>() == plugin_error::not_found);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "plugin-reload");
+	BOOST_TEST(json["error"].get<int>() == daemon::plugin_error::not_found);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "plugin");
 }
 
 BOOST_AUTO_TEST_CASE(exec_error)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "plugin-reload" },
 		{ "plugin",     "broken"        }
 	});
 
-	BOOST_TEST(code == plugin_error::exec_error);
-	BOOST_TEST(json["error"].get<int>() == plugin_error::exec_error);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "plugin-reload");
+	BOOST_TEST(json["error"].get<int>() == daemon::plugin_error::exec_error);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "plugin");
 }
 
--- a/tests/src/libirccd-daemon/command-plugin-unload/main.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/tests/src/libirccd-daemon/command-plugin-unload/main.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -22,28 +22,19 @@
 #include <irccd/test/broken_plugin.hpp>
 #include <irccd/test/command_fixture.hpp>
 
-using irccd::test::broken_plugin;
-using irccd::test::command_fixture;
-using irccd::test::mock_plugin;
-
-using irccd::daemon::bot;
-using irccd::daemon::plugin;
-using irccd::daemon::plugin_error;
-using irccd::daemon::plugin_loader;
-
 namespace irccd {
 
 namespace {
 
-class plugin_unload_fixture : public command_fixture {
+class plugin_unload_fixture : public test::command_fixture {
 protected:
-	std::shared_ptr<mock_plugin> plugin_{new mock_plugin("test")};
+	std::shared_ptr<test::mock_plugin> plugin_{new test::mock_plugin("test")};
 
 	plugin_unload_fixture()
 	{
 		bot_.plugins().clear();
 		bot_.plugins().add(plugin_);
-		bot_.plugins().add(std::make_unique<broken_plugin>("broken"));
+		bot_.plugins().add(std::make_unique<test::broken_plugin>("broken"));
 	}
 };
 
@@ -51,12 +42,13 @@
 
 BOOST_AUTO_TEST_CASE(basic)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "plugin-unload" },
 		{ "plugin",     "test"          }
 	});
 
-	BOOST_TEST(!code);
+	BOOST_TEST(json.size() == 1U);
+	BOOST_TEST(json["command"].get<std::string>() == "plugin-unload");
 	BOOST_TEST(plugin_->find("handle_unload").size() == 1U);
 }
 
@@ -64,36 +56,39 @@
 
 BOOST_AUTO_TEST_CASE(invalid_identifier)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command", "plugin-unload" }
 	});
 
-	BOOST_TEST(code == plugin_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == plugin_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "plugin-unload");
+	BOOST_TEST(json["error"].get<int>() == daemon::plugin_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "plugin");
 }
 
 BOOST_AUTO_TEST_CASE(not_found)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "plugin-unload" },
 		{ "plugin",     "unknown"       }
 	});
 
-	BOOST_TEST(code == plugin_error::not_found);
-	BOOST_TEST(json["error"].get<int>() == plugin_error::not_found);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "plugin-unload");
+	BOOST_TEST(json["error"].get<int>() == daemon::plugin_error::not_found);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "plugin");
 }
 
 BOOST_AUTO_TEST_CASE(exec_error)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "plugin-unload" },
 		{ "plugin",     "broken"        }
 	});
 
-	BOOST_TEST(code == plugin_error::exec_error);
-	BOOST_TEST(json["error"].get<int>() == plugin_error::exec_error);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "plugin-unload");
+	BOOST_TEST(json["error"].get<int>() == daemon::plugin_error::exec_error);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "plugin");
 	BOOST_TEST(!bot_.plugins().has("broken"));
 }
--- a/tests/src/libirccd-daemon/command-rule-add/main.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/tests/src/libirccd-daemon/command-rule-add/main.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -23,15 +23,11 @@
 
 #include <irccd/test/command_fixture.hpp>
 
-using irccd::test::command_fixture;
-
-using irccd::daemon::rule_error;
-
 namespace irccd {
 
 namespace {
 
-BOOST_FIXTURE_TEST_SUITE(rule_add_fixture_suite, command_fixture)
+BOOST_FIXTURE_TEST_SUITE(rule_add_fixture_suite, test::command_fixture)
 
 BOOST_AUTO_TEST_CASE(basic)
 {
@@ -42,15 +38,17 @@
 		{ "plugins",    { "p1", "p2" }      },
 		{ "events",     { "onMessage" }     },
 		{ "action",     "accept"            },
-		{ "index",      0                   }
+		{ "index",      0U                  }
 	});
 
-	const auto [json, code] = request({
+	stream_->clear();
+
+	const auto json = request({
 		{ "command", "rule-list" }
 	});
 
-	BOOST_TEST(!code);
-	BOOST_TEST(json.is_object());
+	BOOST_TEST(json.size() == 2U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-list");
 
 	auto servers = json["list"][0]["servers"];
 	auto channels = json["list"][0]["channels"];
@@ -76,7 +74,7 @@
 		{ "plugins",    { "p1" }            },
 		{ "events",     { "onMessage" }     },
 		{ "action",     "accept"            },
-		{ "index",      0                   }
+		{ "index",      0U                  }
 	});
 
 	request({
@@ -86,15 +84,17 @@
 		{ "plugins",    { "p2" }            },
 		{ "events",     { "onMessage" }     },
 		{ "action",     "drop"              },
-		{ "index",      1                   }
+		{ "index",      1U                  }
 	});
 
-	const auto [json, code] = request({
+	stream_->clear();
+
+	const auto json = request({
 		{ "command", "rule-list" }
 	});
 
-	BOOST_TEST(!code);
-	BOOST_TEST(json.is_object());
+	BOOST_TEST(json.size() == 2U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-list");
 	BOOST_TEST(json["list"].size() == 2U);
 
 	// Rule 0.
@@ -130,13 +130,14 @@
 
 BOOST_AUTO_TEST_CASE(invalid_action)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "rule-add"  },
 		{ "action",     "unknown"   }
 	});
 
-	BOOST_TEST(code == rule_error::invalid_action);
-	BOOST_TEST(json["error"].get<int>() == rule_error::invalid_action);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-add");
+	BOOST_TEST(json["error"].get<int>() == daemon::rule_error::invalid_action);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "rule");
 }
 
--- a/tests/src/libirccd-daemon/command-rule-edit/main.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/tests/src/libirccd-daemon/command-rule-edit/main.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -23,26 +23,21 @@
 
 #include <irccd/test/command_fixture.hpp>
 
-using irccd::test::command_fixture;
-
-using irccd::daemon::rule;
-using irccd::daemon::rule_error;
-
 namespace irccd {
 
 namespace {
 
-class rule_edit_fixture : public command_fixture {
+class rule_edit_fixture : public test::command_fixture {
 public:
 	rule_edit_fixture()
 	{
-		bot_.rules().add(rule{
+		bot_.rules().add(daemon::rule{
 			{ "s1", "s2" },
 			{ "c1", "c2" },
 			{ "o1", "o2" },
 			{ "p1", "p2" },
 			{ "onMessage", "onCommand" },
-			rule::action_type::drop
+			daemon::rule::action_type::drop
 		});
 	}
 };
@@ -54,16 +49,18 @@
 	request({
 		{ "command",        "rule-edit"     },
 		{ "add-servers",    { "new-s3" }    },
-		{ "index",          0               }
+		{ "index",          0U              }
 	});
 
-	const auto [json, code] = request({
+	stream_->clear();
+
+	const auto json = request({
 		{ "command",        "rule-info"     },
-		{ "index",          0               }
+		{ "index",          0U              }
 	});
 
-	BOOST_TEST(!code);
-	BOOST_TEST(json.is_object());
+	BOOST_TEST(json.size() == 7U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-info");
 	BOOST_TEST(json_util::contains(json["servers"], "s1"));
 	BOOST_TEST(json_util::contains(json["servers"], "s2"));
 	BOOST_TEST(json_util::contains(json["servers"], "new-s3"));
@@ -81,16 +78,18 @@
 	request({
 		{ "command",        "rule-edit"     },
 		{ "add-channels",   { "new-c3" }    },
-		{ "index",          0               }
+		{ "index",          0U              }
 	});
 
-	const auto [json, code] = request({
+	stream_->clear();
+
+	const auto json = request({
 		{ "command",        "rule-info"     },
-		{ "index",          0               }
+		{ "index",          0U              }
 	});
 
-	BOOST_TEST(!code);
-	BOOST_TEST(json.is_object());
+	BOOST_TEST(json.size() == 7U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-info");
 	BOOST_TEST(json_util::contains(json["servers"], "s1"));
 	BOOST_TEST(json_util::contains(json["servers"], "s2"));
 	BOOST_TEST(json_util::contains(json["channels"], "c1"));
@@ -108,16 +107,18 @@
 	request({
 		{ "command",        "rule-edit"     },
 		{ "add-plugins",    { "new-p3" }    },
-		{ "index",          0               }
+		{ "index",          0U              }
 	});
 
-	const auto [json, code] = request({
+	stream_->clear();
+
+	const auto json = request({
 		{ "command",        "rule-info"     },
-		{ "index",          0               }
+		{ "index",          0U              }
 	});
 
-	BOOST_TEST(!code);
-	BOOST_TEST(json.is_object());
+	BOOST_TEST(json.size() == 7U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-info");
 	BOOST_TEST(json_util::contains(json["servers"], "s1"));
 	BOOST_TEST(json_util::contains(json["servers"], "s2"));
 	BOOST_TEST(json_util::contains(json["channels"], "c1"));
@@ -135,16 +136,18 @@
 	request({
 		{ "command",        "rule-edit"     },
 		{ "add-events",     { "onQuery" }   },
-		{ "index",          0               }
+		{ "index",          0U              }
 	});
 
-	const auto [json, code] = request({
+	stream_->clear();
+
+	const auto json = request({
 		{ "command",        "rule-info"     },
-		{ "index",          0               }
+		{ "index",          0U              }
 	});
 
-	BOOST_TEST(!code);
-	BOOST_TEST(json.is_object());
+	BOOST_TEST(json.size() == 7U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-info");
 	BOOST_TEST(json_util::contains(json["servers"], "s1"));
 	BOOST_TEST(json_util::contains(json["servers"], "s2"));
 	BOOST_TEST(json_util::contains(json["channels"], "c1"));
@@ -163,16 +166,18 @@
 		{ "command",        "rule-edit"     },
 		{ "add-servers",    { "new-s3" }    },
 		{ "add-events",     { "onQuery" }   },
-		{ "index",          0               }
+		{ "index",          0U              }
 	});
 
-	const auto [json, code] = request({
+	stream_->clear();
+
+	const auto json = request({
 		{ "command",        "rule-info"     },
-		{ "index",          0               }
+		{ "index",          0U              }
 	});
 
-	BOOST_TEST(!code);
-	BOOST_TEST(json.is_object());
+	BOOST_TEST(json.size() == 7U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-info");
 	BOOST_TEST(json_util::contains(json["servers"], "s1"));
 	BOOST_TEST(json_util::contains(json["servers"], "s2"));
 	BOOST_TEST(json_util::contains(json["servers"], "new-s3"));
@@ -191,16 +196,18 @@
 	request({
 		{ "command",        "rule-edit"     },
 		{ "action",         "accept"        },
-		{ "index",          0               }
+		{ "index",          0U              }
 	});
 
-	const auto [json, code] = request({
+	stream_->clear();
+
+	const auto json = request({
 		{ "command",        "rule-info"     },
-		{ "index",          0               }
+		{ "index",          0U              }
 	});
 
-	BOOST_TEST(!code);
-	BOOST_TEST(json.is_object());
+	BOOST_TEST(json.size() == 7U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-info");
 	BOOST_TEST(json_util::contains(json["servers"], "s1"));
 	BOOST_TEST(json_util::contains(json["servers"], "s2"));
 	BOOST_TEST(json_util::contains(json["channels"], "c1"));
@@ -217,16 +224,18 @@
 	request({
 		{ "command",        "rule-edit"     },
 		{ "remove-servers", { "s2" }        },
-		{ "index",          0               }
+		{ "index",          0U              }
 	});
 
-	const auto [json, code] = request({
+	stream_->clear();
+
+	const auto json = request({
 		{ "command",        "rule-info"     },
-		{ "index",          0               }
+		{ "index",          0U              }
 	});
 
-	BOOST_TEST(!code);
-	BOOST_TEST(json.is_object());
+	BOOST_TEST(json.size() == 7U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-info");
 	BOOST_TEST(json_util::contains(json["servers"], "s1"));
 	BOOST_TEST(!json_util::contains(json["servers"], "s2"));
 	BOOST_TEST(json_util::contains(json["channels"], "c1"));
@@ -243,16 +252,18 @@
 	request({
 		{ "command",        "rule-edit"     },
 		{ "remove-channels", { "c2" }       },
-		{ "index",          0               }
+		{ "index",          0U              }
 	});
 
-	const auto [json, code] = request({
+	stream_->clear();
+
+	const auto json = request({
 		{ "command",        "rule-info"     },
-		{ "index",          0               }
+		{ "index",          0U              }
 	});
 
-	BOOST_TEST(!code);
-	BOOST_TEST(json.is_object());
+	BOOST_TEST(json.size() == 7U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-info");
 	BOOST_TEST(json_util::contains(json["servers"], "s1"));
 	BOOST_TEST(json_util::contains(json["servers"], "s2"));
 	BOOST_TEST(json_util::contains(json["channels"], "c1"));
@@ -269,16 +280,18 @@
 	request({
 		{ "command",        "rule-edit"     },
 		{ "remove-plugins", { "p2" }        },
-		{ "index",          0               }
+		{ "index",          0U              }
 	});
 
-	const auto [json, code] = request({
+	stream_->clear();
+
+	const auto json = request({
 		{ "command",        "rule-info"     },
-		{ "index",          0               }
+		{ "index",          0U              }
 	});
 
-	BOOST_TEST(!code);
-	BOOST_TEST(json.is_object());
+	BOOST_TEST(json.size() == 7U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-info");
 	BOOST_TEST(json_util::contains(json["servers"], "s1"));
 	BOOST_TEST(json_util::contains(json["servers"], "s2"));
 	BOOST_TEST(json_util::contains(json["channels"], "c1"));
@@ -295,16 +308,18 @@
 	request({
 		{ "command",        "rule-edit"     },
 		{ "remove-events",  { "onCommand" } },
-		{ "index",          0               }
+		{ "index",          0U              }
 	});
 
-	const auto [json, code] = request({
+	stream_->clear();
+
+	const auto json = request({
 		{ "command",        "rule-info"     },
-		{ "index",          0               }
+		{ "index",          0U              }
 	});
 
-	BOOST_TEST(!code);
-	BOOST_TEST(json.is_object());
+	BOOST_TEST(json.size() == 7U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-info");
 	BOOST_TEST(json_util::contains(json["servers"], "s1"));
 	BOOST_TEST(json_util::contains(json["servers"], "s2"));
 	BOOST_TEST(json_util::contains(json["channels"], "c1"));
@@ -322,16 +337,18 @@
 		{ "command",        "rule-edit"     },
 		{ "remove-servers", { "s2" }        },
 		{ "remove-events",  { "onCommand" } },
-		{ "index",          0               }
+		{ "index",          0U              }
 	});
 
-	const auto [json, code] = request({
+	stream_->clear();
+
+	const auto json = request({
 		{ "command",        "rule-info"     },
-		{ "index",          0               }
+		{ "index",          0U              }
 	});
 
-	BOOST_TEST(!code);
-	BOOST_TEST(json.is_object());
+	BOOST_TEST(json.size() == 7U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-info");
 	BOOST_TEST(json_util::contains(json["servers"], "s1"));
 	BOOST_TEST(!json_util::contains(json["servers"], "s2"));
 	BOOST_TEST(json_util::contains(json["channels"], "c1"));
@@ -347,53 +364,57 @@
 
 BOOST_AUTO_TEST_CASE(invalid_index_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "rule-edit" },
 		{ "index",      -100        },
 		{ "action",     "drop"      }
 	});
 
-	BOOST_TEST(code == rule_error::invalid_index);
-	BOOST_TEST(json["error"].get<int>() == rule_error::invalid_index);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-edit");
+	BOOST_TEST(json["error"].get<int>() == daemon::rule_error::invalid_index);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "rule");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_index_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "rule-edit" },
-		{ "index",      100         },
+		{ "index",      100U        },
 		{ "action",     "drop"      }
 	});
 
-	BOOST_TEST(code == rule_error::invalid_index);
-	BOOST_TEST(json["error"].get<int>() == rule_error::invalid_index);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-edit");
+	BOOST_TEST(json["error"].get<int>() == daemon::rule_error::invalid_index);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "rule");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_index_3)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "rule-edit" },
 		{ "index",      "notaint"   },
 		{ "action",     "drop"      }
 	});
 
-	BOOST_TEST(code == rule_error::invalid_index);
-	BOOST_TEST(json["error"].get<int>() == rule_error::invalid_index);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-edit");
+	BOOST_TEST(json["error"].get<int>() == daemon::rule_error::invalid_index);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "rule");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_action)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "rule-edit" },
-		{ "index",      0           },
+		{ "index",      0U          },
 		{ "action",     "unknown"   }
 	});
 
-	BOOST_TEST(code == rule_error::invalid_action);
-	BOOST_TEST(json["error"].get<int>() == rule_error::invalid_action);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-edit");
+	BOOST_TEST(json["error"].get<int>() == daemon::rule_error::invalid_action);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "rule");
 }
 
--- a/tests/src/libirccd-daemon/command-rule-info/main.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/tests/src/libirccd-daemon/command-rule-info/main.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -23,34 +23,29 @@
 
 #include <irccd/test/command_fixture.hpp>
 
-using irccd::test::command_fixture;
-
-using irccd::daemon::rule;
-using irccd::daemon::rule_error;
-
 namespace irccd {
 
 namespace {
 
-class rule_info_fixture : public command_fixture {
+class rule_info_fixture : public test::command_fixture {
 public:
 	rule_info_fixture()
 	{
-		bot_.rules().add(rule{
+		bot_.rules().add(daemon::rule{
 			{ "s1", "s2" },
 			{ "c1", "c2" },
 			{ "o1", "o2" },
 			{ "p1", "p2" },
 			{ "onMessage", "onCommand" },
-			rule::action_type::drop
+			daemon::rule::action_type::drop
 		});
-		bot_.rules().add(rule{
+		bot_.rules().add(daemon::rule{
 			{ "s1", },
 			{ "c1", },
 			{ "o1", },
 			{ "p1", },
 			{ "onMessage", },
-			rule::action_type::accept
+			daemon::rule::action_type::accept
 		});
 	}
 };
@@ -59,9 +54,9 @@
 
 BOOST_AUTO_TEST_CASE(basic)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "rule-info" },
-		{ "index",      0           }
+		{ "index",      0U          }
 	});
 
 	auto servers = json["servers"];
@@ -69,7 +64,8 @@
 	auto plugins = json["plugins"];
 	auto events = json["events"];
 
-	BOOST_TEST(!code);
+	BOOST_TEST(json.size() == 7U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-info");
 	BOOST_TEST(json_util::contains(servers, "s1"));
 	BOOST_TEST(json_util::contains(servers, "s2"));
 	BOOST_TEST(json_util::contains(channels, "c1"));
@@ -85,37 +81,40 @@
 
 BOOST_AUTO_TEST_CASE(invalid_index_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "rule-info" },
 		{ "index",      -100        }
 	});
 
-	BOOST_TEST(code == rule_error::invalid_index);
-	BOOST_TEST(json["error"].get<int>() == rule_error::invalid_index);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-info");
+	BOOST_TEST(json["error"].get<int>() == daemon::rule_error::invalid_index);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "rule");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_index_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "rule-info" },
-		{ "index",      100         }
+		{ "index",      100U        }
 	});
 
-	BOOST_TEST(code == rule_error::invalid_index);
-	BOOST_TEST(json["error"].get<int>() == rule_error::invalid_index);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-info");
+	BOOST_TEST(json["error"].get<int>() == daemon::rule_error::invalid_index);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "rule");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_index_3)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "rule-info" },
 		{ "index",      "notaint"   }
 	});
 
-	BOOST_TEST(code == rule_error::invalid_index);
-	BOOST_TEST(json["error"].get<int>() == rule_error::invalid_index);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-info");
+	BOOST_TEST(json["error"].get<int>() == daemon::rule_error::invalid_index);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "rule");
 }
 
--- a/tests/src/libirccd-daemon/command-rule-list/main.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/tests/src/libirccd-daemon/command-rule-list/main.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -23,34 +23,29 @@
 
 #include <irccd/test/command_fixture.hpp>
 
-using irccd::test::command_fixture;
-
-using irccd::daemon::rule;
-using irccd::daemon::rule_error;
-
 namespace irccd {
 
 namespace {
 
-class rule_list_fixture : public command_fixture {
+class rule_list_fixture : public test::command_fixture {
 public:
 	rule_list_fixture()
 	{
-		bot_.rules().add(rule{
+		bot_.rules().add(daemon::rule{
 			{ "s1", "s2" },
 			{ "c1", "c2" },
 			{ "o1", "o2" },
 			{ "p1", "p2" },
 			{ "onMessage", "onCommand" },
-			rule::action_type::drop
+			daemon::rule::action_type::drop
 		});
-		bot_.rules().add(rule{
+		bot_.rules().add(daemon::rule{
 			{ "s1", },
 			{ "c1", },
 			{ "o1", },
 			{ "p1", },
 			{ "onMessage", },
-			rule::action_type::accept
+			daemon::rule::action_type::accept
 		});
 	}
 };
@@ -59,10 +54,10 @@
 
 BOOST_AUTO_TEST_CASE(basic)
 {
-	const auto [json, code] = request({{ "command", "rule-list" }});
+	const auto json = request({{ "command", "rule-list" }});
 
-	BOOST_TEST(!code);
-	BOOST_TEST(json.is_object());
+	BOOST_TEST(json.size() == 2U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-list");
 	BOOST_TEST(json["list"].is_array());
 	BOOST_TEST(json["list"].size() == 2U);
 
@@ -104,10 +99,10 @@
 	bot_.rules().remove(0);
 	bot_.rules().remove(0);
 
-	const auto [json, code] = request({{ "command", "rule-list" }});
+	const auto json = request({{ "command", "rule-list" }});
 
-	BOOST_TEST(!code);
-	BOOST_TEST(json.is_object());
+	BOOST_TEST(json.size() == 2U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-list");
 	BOOST_TEST(json["list"].is_array());
 	BOOST_TEST(json["list"].empty());
 }
--- a/tests/src/libirccd-daemon/command-rule-move/main.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/tests/src/libirccd-daemon/command-rule-move/main.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -23,42 +23,37 @@
 
 #include <irccd/test/command_fixture.hpp>
 
-using irccd::test::command_fixture;
-
-using irccd::daemon::rule;
-using irccd::daemon::rule_error;
-
 namespace irccd {
 
 namespace {
 
-class rule_move_fixture : public command_fixture {
+class rule_move_fixture : public test::command_fixture {
 public:
 	rule_move_fixture()
 	{
-		bot_.rules().add(rule{
+		bot_.rules().add(daemon::rule{
 			{ "s0" },
 			{ "c0" },
 			{ "o0" },
 			{ "p0" },
 			{ "onMessage" },
-			rule::action_type::drop
+			daemon::rule::action_type::drop
 		});
-		bot_.rules().add(rule{
+		bot_.rules().add(daemon::rule{
 			{ "s1", },
 			{ "c1", },
 			{ "o1", },
 			{ "p1", },
 			{ "onMessage", },
-			rule::action_type::accept
+			daemon::rule::action_type::accept
 		});
-		bot_.rules().add(rule{
+		bot_.rules().add(daemon::rule{
 			{ "s2", },
 			{ "c2", },
 			{ "o2", },
 			{ "p2", },
 			{ "onMessage", },
-			rule::action_type::accept
+			daemon::rule::action_type::accept
 		});
 	}
 };
@@ -69,14 +64,16 @@
 {
 	request({
 		{ "command",    "rule-move" },
-		{ "from",       2           },
-		{ "to",         0           }
+		{ "from",       2U          },
+		{ "to",         0U          }
 	});
 
-	const auto [json, code] = request({{ "command", "rule-list" }});
+	stream_->clear();
 
-	BOOST_TEST(!code);
-	BOOST_TEST(json.is_object());
+	const auto json = request({{ "command", "rule-list" }});
+
+	BOOST_TEST(json.size() == 2U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-list");
 
 	// Rule 2.
 	{
@@ -125,14 +122,16 @@
 {
 	request({
 		{ "command",    "rule-move" },
-		{ "from",       0           },
-		{ "to",         2           }
+		{ "from",       0U          },
+		{ "to",         2U          }
 	});
 
-	const auto [json, code] = request({{ "command", "rule-list" }});
+	stream_->clear();
 
-	BOOST_TEST(!code);
-	BOOST_TEST(json.is_object());
+	const auto json = request({{ "command", "rule-list" }});
+
+	BOOST_TEST(json.size() == 2U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-list");
 
 	// Rule 1.
 	{
@@ -181,14 +180,16 @@
 {
 	request({
 		{ "command",    "rule-move" },
-		{ "from",       1           },
-		{ "to",         1           }
+		{ "from",       1U          },
+		{ "to",         1U          }
 	});
 
-	const auto [json, code] = request({{ "command", "rule-list" }});
+	stream_->clear();
 
-	BOOST_TEST(!code);
-	BOOST_TEST(json.is_object());
+	const auto json = request({{ "command", "rule-list" }});
+
+	BOOST_TEST(json.size() == 2U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-list");
 
 	// Rule 0.
 	{
@@ -237,14 +238,16 @@
 {
 	request({
 		{ "command",    "rule-move" },
-		{ "from",       0           },
-		{ "to",         123         }
+		{ "from",       0U          },
+		{ "to",         123U        }
 	});
 
-	const auto [json, code] = request({{ "command", "rule-list" }});
+	stream_->clear();
 
-	BOOST_TEST(!code);
-	BOOST_TEST(json.is_object());
+	const auto json = request({{ "command", "rule-list" }});
+
+	BOOST_TEST(json.size() == 2U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-list");
 
 	// Rule 1.
 	{
@@ -293,66 +296,71 @@
 
 BOOST_AUTO_TEST_CASE(invalid_index_1_from)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "rule-move" },
 		{ "from",       -100        },
-		{ "to",         0           }
+		{ "to",         0U          }
 	});
 
-	BOOST_TEST(code == rule_error::invalid_index);
-	BOOST_TEST(json["error"].get<int>() == rule_error::invalid_index);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-move");
+	BOOST_TEST(json["error"].get<int>() == daemon::rule_error::invalid_index);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "rule");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_index_1_to)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "rule-move" },
-		{ "from",       0           },
+		{ "from",       0U          },
 		{ "to",         -100        }
 	});
 
-	BOOST_TEST(code == rule_error::invalid_index);
-	BOOST_TEST(json["error"].get<int>() == rule_error::invalid_index);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-move");
+	BOOST_TEST(json["error"].get<int>() == daemon::rule_error::invalid_index);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "rule");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_index_2_from)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "rule-move" },
-		{ "from",       100         },
-		{ "to",         0           }
+		{ "from",       100U        },
+		{ "to",         0U          }
 	});
 
-	BOOST_TEST(code == rule_error::invalid_index);
-	BOOST_TEST(json["error"].get<int>() == rule_error::invalid_index);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-move");
+	BOOST_TEST(json["error"].get<int>() == daemon::rule_error::invalid_index);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "rule");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_index_3_from)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "rule-move" },
 		{ "from",       "notaint"   },
-		{ "to",         0           }
+		{ "to",         0U          }
 	});
 
-	BOOST_TEST(code == rule_error::invalid_index);
-	BOOST_TEST(json["error"].get<int>() == rule_error::invalid_index);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-move");
+	BOOST_TEST(json["error"].get<int>() == daemon::rule_error::invalid_index);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "rule");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_index_3_to)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "rule-move" },
-		{ "from",       0           },
+		{ "from",       0U          },
 		{ "to",         "notaint"   }
 	});
 
-	BOOST_TEST(code == rule_error::invalid_index);
-	BOOST_TEST(json["error"].get<int>() == rule_error::invalid_index);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-move");
+	BOOST_TEST(json["error"].get<int>() == daemon::rule_error::invalid_index);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "rule");
 }
 
--- a/tests/src/libirccd-daemon/command-rule-remove/main.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/tests/src/libirccd-daemon/command-rule-remove/main.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -23,34 +23,29 @@
 
 #include <irccd/test/command_fixture.hpp>
 
-using irccd::test::command_fixture;
-
-using irccd::daemon::rule;
-using irccd::daemon::rule_error;
-
 namespace irccd {
 
 namespace {
 
-class rule_remove_fixture : public command_fixture {
+class rule_remove_fixture : public test::command_fixture {
 public:
 	rule_remove_fixture()
 	{
-		bot_.rules().add(rule{
+		bot_.rules().add(daemon::rule{
 			{ "s1", "s2" },
 			{ "c1", "c2" },
 			{ "o1", "o2" },
 			{ "p1", "p2" },
 			{ "onMessage", "onCommand" },
-			rule::action_type::drop
+			daemon::rule::action_type::drop
 		});
-		bot_.rules().add(rule{
+		bot_.rules().add(daemon::rule{
 			{ "s1", },
 			{ "c1", },
 			{ "o1", },
 			{ "p1", },
 			{ "onMessage", },
-			rule::action_type::accept
+			daemon::rule::action_type::accept
 		});
 	}
 };
@@ -61,12 +56,15 @@
 {
 	request({
 		{ "command",    "rule-remove"   },
-		{ "index",      1               }
+		{ "index",      1U              }
 	});
 
-	const auto [json, code] = request({{ "command", "rule-list" }});
+	stream_->clear();
 
-	BOOST_TEST(!code);
+	const auto json = request({{ "command", "rule-list" }});
+
+	BOOST_TEST(json.size() == 2U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-list");
 	BOOST_TEST(json["list"].is_array());
 	BOOST_TEST(json["list"].size() == 1U);
 
@@ -90,37 +88,40 @@
 
 BOOST_AUTO_TEST_CASE(invalid_index_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "rule-remove"   },
 		{ "index",      -100            }
 	});
 
-	BOOST_TEST(code == rule_error::invalid_index);
-	BOOST_TEST(json["error"].get<int>() == rule_error::invalid_index);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-remove");
+	BOOST_TEST(json["error"].get<int>() == daemon::rule_error::invalid_index);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "rule");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_index_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "rule-remove"   },
-		{ "index",      100             }
+		{ "index",      100U            }
 	});
 
-	BOOST_TEST(code == rule_error::invalid_index);
-	BOOST_TEST(json["error"].get<int>() == rule_error::invalid_index);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-remove");
+	BOOST_TEST(json["error"].get<int>() == daemon::rule_error::invalid_index);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "rule");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_index_3)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "rule-remove"   },
 		{ "index",      "notaint"       }
 	});
 
-	BOOST_TEST(code == rule_error::invalid_index);
-	BOOST_TEST(json["error"].get<int>() == rule_error::invalid_index);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "rule-remove");
+	BOOST_TEST(json["error"].get<int>() == daemon::rule_error::invalid_index);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "rule");
 }
 
--- a/tests/src/libirccd-daemon/command-server-connect/main.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/tests/src/libirccd-daemon/command-server-connect/main.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -21,21 +21,15 @@
 
 #include <irccd/test/command_fixture.hpp>
 
-using irccd::test::command_fixture;
-using irccd::test::mock_server;
-
-using irccd::daemon::server;
-using irccd::daemon::server_error;
-
 namespace irccd {
 
 namespace {
 
-BOOST_FIXTURE_TEST_SUITE(server_connect_fixture_suite, command_fixture)
+BOOST_FIXTURE_TEST_SUITE(server_connect_fixture_suite, test::command_fixture)
 
 BOOST_AUTO_TEST_CASE(minimal)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-connect"    },
 		{ "name",       "local"             },
 		{ "hostname",   "irc.example.org"   }
@@ -43,7 +37,8 @@
 
 	const auto s = bot_.servers().get("local");
 
-	BOOST_TEST(!code);
+	BOOST_TEST(json.size() == 1U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-connect");
 	BOOST_TEST(s);
 	BOOST_TEST(s->get_id() == "local");
 	BOOST_TEST(s->get_hostname() == "irc.example.org");
@@ -54,7 +49,7 @@
 
 BOOST_AUTO_TEST_CASE(full)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",            "server-connect"        },
 		{ "name",               "local2"                },
 		{ "hostname",           "irc.example2.org"      },
@@ -66,7 +61,7 @@
 		{ "ipv6",               true                    },
 		{ "ctcpVersion",        "ultra bot"             },
 		{ "commandChar",        "::"                    },
-		{ "port",               18000                   },
+		{ "port",               18000U                  },
 		{ "ssl",                true                    },
 		{ "sslVerify",          true                    },
 		{ "autoRejoin",         true                    },
@@ -75,7 +70,8 @@
 
 	const auto s = bot_.servers().get("local2");
 
-	BOOST_TEST(!code);
+	BOOST_TEST(json.size() == 1U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-connect");
 	BOOST_TEST(s);
 	BOOST_TEST(s->get_id() == "local2");
 	BOOST_TEST(s->get_hostname() == "irc.example2.org");
@@ -86,11 +82,11 @@
 	BOOST_TEST(s->get_username() == "frc");
 	BOOST_TEST(s->get_command_char() == "::");
 	BOOST_TEST(s->get_ctcp_version() == "ultra bot");
-	BOOST_TEST(!static_cast<bool>(s->get_options() & server::options::ipv4));
-	BOOST_TEST(static_cast<bool>(s->get_options() & server::options::ipv6));
-	BOOST_TEST(static_cast<bool>(s->get_options() & server::options::ssl));
-	BOOST_TEST(static_cast<bool>(s->get_options() & server::options::auto_rejoin));
-	BOOST_TEST(static_cast<bool>(s->get_options() & server::options::join_invite));
+	BOOST_TEST(!static_cast<bool>(s->get_options() & daemon::server::options::ipv4));
+	BOOST_TEST(static_cast<bool>(s->get_options() & daemon::server::options::ipv6));
+	BOOST_TEST(static_cast<bool>(s->get_options() & daemon::server::options::ssl));
+	BOOST_TEST(static_cast<bool>(s->get_options() & daemon::server::options::auto_rejoin));
+	BOOST_TEST(static_cast<bool>(s->get_options() & daemon::server::options::join_invite));
 }
 
 #endif // !IRCCD_HAVE_SSL
@@ -99,109 +95,117 @@
 
 BOOST_AUTO_TEST_CASE(already_exists)
 {
-	bot_.servers().add(std::make_unique<mock_server>(ctx_, "local"));
+	bot_.servers().add(std::make_unique<test::mock_server>(ctx_, "local"));
 
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-connect"        },
 		{ "name",       "local"                 },
 		{ "hostname",   "127.0.0.1"             }
 	});
 
-	BOOST_TEST(code == server_error::already_exists);
-	BOOST_TEST(json["error"].get<int>() == server_error::already_exists);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-connect");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::already_exists);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_hostname_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-connect"        },
 		{ "name",       "new"                   },
 	});
 
-	BOOST_TEST(code == server_error::invalid_hostname);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_hostname);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-connect");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_hostname);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_hostname_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-connect"        },
 		{ "name",       "new"                   },
 		{ "hostname",   123456                  }
 	});
 
-	BOOST_TEST(code == server_error::invalid_hostname);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_hostname);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-connect");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_hostname);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_identifier_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-connect"        },
 		{ "name",       ""                      },
 		{ "hostname",   "127.0.0.1"             }
 	});
 
-	BOOST_TEST(code == server_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-connect");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_identifier_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-connect"        },
 		{ "name",       123456                  },
 		{ "hostname",   "127.0.0.1"             }
 	});
 
-	BOOST_TEST(code == server_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-connect");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_port_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-connect"        },
 		{ "name",       "new"                   },
 		{ "hostname",   "127.0.0.1"             },
 		{ "port",       "notaint"               }
 	});
 
-	BOOST_TEST(code == server_error::invalid_port);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_port);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-connect");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_port);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_port_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-connect"        },
 		{ "name",       "new"                   },
 		{ "hostname",   "127.0.0.1"             },
 		{ "port",       -123                    }
 	});
 
-	BOOST_TEST(code == server_error::invalid_port);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_port);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-connect");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_port);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_port_3)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-connect"        },
 		{ "name",       "new"                   },
 		{ "hostname",   "127.0.0.1"             },
-		{ "port",       1000000                 }
+		{ "port",       1000000U                }
 	});
 
-	BOOST_TEST(code == server_error::invalid_port);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_port);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-connect");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_port);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
@@ -209,15 +213,16 @@
 
 BOOST_AUTO_TEST_CASE(ssl_disabled)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-connect"        },
 		{ "name",       "new"                   },
 		{ "hostname",   "127.0.0.1"             },
 		{ "ssl",        true                    }
 	});
 
-	BOOST_TEST(code == server_error::ssl_disabled);
-	BOOST_TEST(json["error"].get<int>() == server_error::ssl_disabled);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-connect");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::ssl_disabled);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
@@ -225,31 +230,33 @@
 
 BOOST_AUTO_TEST_CASE(invalid_family_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-connect"        },
 		{ "name",       "new"                   },
 		{ "hostname",   "127.0.0.1"             },
-		{ "port",       6667                    },
+		{ "port",       6667U                   },
 		{ "ipv4",       "invalid"               }
 	});
 
-	BOOST_TEST(code == server_error::invalid_family);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_family);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-connect");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_family);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_family_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-connect"        },
 		{ "name",       "new"                   },
 		{ "hostname",   "127.0.0.1"             },
-		{ "port",       6667                    },
+		{ "port",       6667U                   },
 		{ "ipv6",       1234                    }
 	});
 
-	BOOST_TEST(code == server_error::invalid_family);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_family);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-connect");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_family);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
--- a/tests/src/libirccd-daemon/command-server-disconnect/main.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/tests/src/libirccd-daemon/command-server-disconnect/main.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -21,24 +21,18 @@
 
 #include <irccd/test/command_fixture.hpp>
 
-using irccd::test::command_fixture;
-using irccd::test::mock_server;
-
-using irccd::daemon::server;
-using irccd::daemon::server_error;
-
 namespace irccd {
 
 namespace {
 
-class server_disconnect_fixture : public command_fixture {
+class server_disconnect_fixture : public test::command_fixture {
 protected:
-	std::shared_ptr<mock_server> s1_;
-	std::shared_ptr<mock_server> s2_;
+	std::shared_ptr<test::mock_server> s1_;
+	std::shared_ptr<test::mock_server> s2_;
 
 	server_disconnect_fixture()
-		: s1_(new mock_server(ctx_, "s1", "localhost"))
-		, s2_(new mock_server(ctx_, "s2", "localhost"))
+		: s1_(new test::mock_server(ctx_, "s1", "localhost"))
+		, s2_(new test::mock_server(ctx_, "s2", "localhost"))
 	{
 		bot_.servers().add(s1_);
 		bot_.servers().add(s2_);
@@ -49,12 +43,12 @@
 
 BOOST_AUTO_TEST_CASE(one)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-disconnect"     },
 		{ "server",     "s1"                    }
 	});
 
-	BOOST_TEST(!code);
+	BOOST_TEST(json.size() == 1U);
 	BOOST_TEST(json["command"].get<std::string>() == "server-disconnect");
 	BOOST_TEST(s1_->find("disconnect").size() == 1U);
 	BOOST_TEST(!bot_.servers().has("s1"));
@@ -63,9 +57,9 @@
 
 BOOST_AUTO_TEST_CASE(all)
 {
-	const auto [json, code] = request({{ "command", "server-disconnect" }});
+	const auto json = request({{ "command", "server-disconnect" }});
 
-	BOOST_TEST(!code);
+	BOOST_TEST(json.size() == 1U);
 	BOOST_TEST(json["command"].get<std::string>() == "server-disconnect");
 	BOOST_TEST(s1_->find("disconnect").size() == 1U);
 	BOOST_TEST(s2_->find("disconnect").size() == 1U);
@@ -77,25 +71,27 @@
 
 BOOST_AUTO_TEST_CASE(invalid_identifier)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-disconnect"     },
 		{ "server",     123456                  }
 	});
 
-	BOOST_TEST(code == server_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-disconnect");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(not_found)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-disconnect"     },
 		{ "server",     "unknown"               }
 	});
 
-	BOOST_TEST(code == server_error::not_found);
-	BOOST_TEST(json["error"].get<int>() == server_error::not_found);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-disconnect");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::not_found);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
--- a/tests/src/libirccd-daemon/command-server-info/main.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/tests/src/libirccd-daemon/command-server-info/main.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -21,21 +21,15 @@
 
 #include <irccd/test/command_fixture.hpp>
 
-using irccd::test::command_fixture;
-using irccd::test::mock_server;
-
-using irccd::daemon::server;
-using irccd::daemon::server_error;
-
 namespace irccd {
 
 namespace {
 
-BOOST_FIXTURE_TEST_SUITE(server_info_fixture_suite, command_fixture)
+BOOST_FIXTURE_TEST_SUITE(server_info_fixture_suite, test::command_fixture)
 
 BOOST_AUTO_TEST_CASE(basic)
 {
-	auto server = std::make_unique<mock_server>(ctx_, "test", "example.org");
+	auto server = std::make_unique<test::mock_server>(ctx_, "test", "example.org");
 
 	server->set_port(8765);
 	server->set_password("none");
@@ -49,13 +43,13 @@
 	bot_.servers().clear();
 	bot_.servers().add(std::move(server));
 
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-info"   },
 		{ "server",     "test"          },
 	});
 
-	BOOST_TEST(!code);
-	BOOST_TEST(json.is_object());
+	BOOST_TEST(json.size() == 11U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-info");
 	BOOST_TEST(json["hostname"].get<std::string>() == "example.org");
 	BOOST_TEST(json["name"].get<std::string>() == "test");
 	BOOST_TEST(json["nickname"].get<std::string>() == "pascal");
@@ -68,37 +62,40 @@
 
 BOOST_AUTO_TEST_CASE(invalid_identifier_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-info"   },
 		{ "server",     123456          }
 	});
 
-	BOOST_TEST(code == server_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-info");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_identifier_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-info"   },
 		{ "server",     ""              }
 	});
 
-	BOOST_TEST(code == server_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-info");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(not_found)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-info"   },
 		{ "server",     "unknown"       }
 	});
 
-	BOOST_TEST(code == server_error::not_found);
-	BOOST_TEST(json["error"].get<int>() == server_error::not_found);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-info");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::not_found);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
--- a/tests/src/libirccd-daemon/command-server-invite/main.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/tests/src/libirccd-daemon/command-server-invite/main.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -21,20 +21,15 @@
 
 #include <irccd/test/command_fixture.hpp>
 
-using irccd::test::command_fixture;
-
-using irccd::daemon::server;
-using irccd::daemon::server_error;
-
 namespace irccd {
 
 namespace {
 
-BOOST_FIXTURE_TEST_SUITE(server_invite_fixture_suite, command_fixture)
+BOOST_FIXTURE_TEST_SUITE(server_invite_fixture_suite, test::command_fixture)
 
 BOOST_AUTO_TEST_CASE(basic)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-invite" },
 		{ "server",     "test"          },
 		{ "target",     "francis"       },
@@ -43,7 +38,8 @@
 
 	const auto cmd = server_->find("invite").back();
 
-	BOOST_TEST(!code);
+	BOOST_TEST(json.size() == 1U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-invite");
 	BOOST_TEST(std::any_cast<std::string>(cmd[0]) == "francis");
 	BOOST_TEST(std::any_cast<std::string>(cmd[1]) == "#music");
 }
@@ -52,99 +48,106 @@
 
 BOOST_AUTO_TEST_CASE(invalid_identifier_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-invite" },
 		{ "server",     123456          },
 		{ "target",     "francis"       },
 		{ "channel",    "#music"        }
 	});
 
-	BOOST_TEST(code == server_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-invite");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_identifier_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-invite" },
 		{ "server",     ""              },
 		{ "target",     "francis"       },
 		{ "channel",    "#music"        }
 	});
 
-	BOOST_TEST(code == server_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-invite");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_nickname_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-invite" },
 		{ "server",     "test"          },
 		{ "target",     ""              },
 		{ "channel",    "#music"        }
 	});
 
-	BOOST_TEST(code == server_error::invalid_nickname);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_nickname);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-invite");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_nickname);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_nickname_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-invite" },
 		{ "server",     "test"          },
 		{ "target",     123456          },
 		{ "channel",    "#music"        }
 	});
 
-	BOOST_TEST(code == server_error::invalid_nickname);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_nickname);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-invite");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_nickname);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_channel_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-invite" },
 		{ "server",     "test"          },
 		{ "target",     "jean"          },
 		{ "channel",    ""              }
 	});
 
-	BOOST_TEST(code == server_error::invalid_channel);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_channel);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-invite");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_channel);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_channel_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-invite" },
 		{ "server",     "test"          },
 		{ "target",     "jean"          },
 		{ "channel",    123456          }
 	});
 
-	BOOST_TEST(code == server_error::invalid_channel);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_channel);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-invite");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_channel);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(not_found)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-invite" },
 		{ "server",     "unknown"       },
 		{ "target",     "francis"       },
 		{ "channel",    "#music"        }
 	});
 
-	BOOST_TEST(code == server_error::not_found);
-	BOOST_TEST(json["error"].get<int>() == server_error::not_found);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-invite");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::not_found);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
--- a/tests/src/libirccd-daemon/command-server-join/main.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/tests/src/libirccd-daemon/command-server-join/main.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -21,20 +21,15 @@
 
 #include <irccd/test/command_fixture.hpp>
 
-using irccd::test::command_fixture;
-
-using irccd::daemon::server;
-using irccd::daemon::server_error;
-
 namespace irccd {
 
 namespace {
 
-BOOST_FIXTURE_TEST_SUITE(server_join_fixture_suite, command_fixture)
+BOOST_FIXTURE_TEST_SUITE(server_join_fixture_suite, test::command_fixture)
 
 BOOST_AUTO_TEST_CASE(basic)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-join"   },
 		{ "server",     "test"          },
 		{ "channel",    "#music"        },
@@ -43,14 +38,15 @@
 
 	const auto cmd = server_->find("join").back();
 
-	BOOST_TEST(!code);
+	BOOST_TEST(json.size() == 1U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-join");
 	BOOST_TEST(std::any_cast<std::string>(cmd[0]) == "#music");
 	BOOST_TEST(std::any_cast<std::string>(cmd[1]) == "plop");
 }
 
 BOOST_AUTO_TEST_CASE(nopassword)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-join"   },
 		{ "server",     "test"          },
 		{ "channel",    "#music"        }
@@ -58,7 +54,8 @@
 
 	const auto cmd = server_->find("join").back();
 
-	BOOST_TEST(!code);
+	BOOST_TEST(json.size() == 1U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-join");
 	BOOST_TEST(std::any_cast<std::string>(cmd[0]) == "#music");
 	BOOST_TEST(std::any_cast<std::string>(cmd[1]) == "");
 }
@@ -67,80 +64,86 @@
 
 BOOST_AUTO_TEST_CASE(invalid_identifier_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-join"   },
 		{ "server",     123456          },
 		{ "channel",    "#music"        }
 	});
 
-	BOOST_TEST(code == server_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-join");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_identifier_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-join"   },
 		{ "server",     ""              },
 		{ "channel",    "#music"        }
 	});
 
-	BOOST_TEST(code == server_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-join");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_channel_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-join"   },
 		{ "server",     "test"          },
 		{ "channel",    ""              }
 	});
 
-	BOOST_TEST(code == server_error::invalid_channel);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_channel);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-join");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_channel);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_channel_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-join"   },
 		{ "server",     "test"          },
 		{ "channel",    123456          }
 	});
 
-	BOOST_TEST(code == server_error::invalid_channel);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_channel);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-join");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_channel);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_password)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-join"   },
 		{ "server",     "test"          },
 		{ "channel",    "#staff"        },
 		{ "password",   123456          }
 	});
 
-	BOOST_TEST(code == server_error::invalid_password);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_password);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-join");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_password);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(not_found)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-join"   },
 		{ "server",     "unknown"       },
 		{ "channel",    "#music"        }
 	});
 
-	BOOST_TEST(code == server_error::not_found);
-	BOOST_TEST(json["error"].get<int>() == server_error::not_found);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-join");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::not_found);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
--- a/tests/src/libirccd-daemon/command-server-kick/main.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/tests/src/libirccd-daemon/command-server-kick/main.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -21,20 +21,15 @@
 
 #include <irccd/test/command_fixture.hpp>
 
-using irccd::test::command_fixture;
-
-using irccd::daemon::server;
-using irccd::daemon::server_error;
-
 namespace irccd {
 
 namespace {
 
-BOOST_FIXTURE_TEST_SUITE(server_kick_fixture_suite, command_fixture)
+BOOST_FIXTURE_TEST_SUITE(server_kick_fixture_suite, test::command_fixture)
 
 BOOST_AUTO_TEST_CASE(basic)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-kick"   },
 		{ "server",     "test"          },
 		{ "target",     "francis"       },
@@ -44,7 +39,8 @@
 
 	const auto cmd = server_->find("kick").back();
 
-	BOOST_TEST(!code);
+	BOOST_TEST(json.size() == 1U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-kick");
 	BOOST_TEST(std::any_cast<std::string>(cmd[1]) == "#staff");
 	BOOST_TEST(std::any_cast<std::string>(cmd[0]) == "francis");
 	BOOST_TEST(std::any_cast<std::string>(cmd[2]) == "too noisy");
@@ -52,7 +48,7 @@
 
 BOOST_AUTO_TEST_CASE(noreason)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-kick"   },
 		{ "server",     "test"          },
 		{ "target",     "francis"       },
@@ -61,7 +57,8 @@
 
 	const auto cmd = server_->find("kick").back();
 
-	BOOST_TEST(!code);
+	BOOST_TEST(json.size() == 1U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-kick");
 	BOOST_TEST(std::any_cast<std::string>(cmd[1]) == "#staff");
 	BOOST_TEST(std::any_cast<std::string>(cmd[0]) == "francis");
 	BOOST_TEST(std::any_cast<std::string>(cmd[2]) == "");
@@ -71,91 +68,97 @@
 
 BOOST_AUTO_TEST_CASE(invalid_identifier_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-kick"   },
 		{ "server",     123456          },
 		{ "target",     "francis"       },
 		{ "channel",    "#music"        }
 	});
 
-	BOOST_TEST(code == server_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-kick");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_identifier_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-kick"   },
 		{ "server",     ""              },
 		{ "target",     "francis"       },
 		{ "channel",    "#music"        }
 	});
 
-	BOOST_TEST(code == server_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-kick");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_nickname_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-kick"   },
 		{ "server",     "test"          },
 		{ "target",     ""              },
 		{ "channel",    "#music"        }
 	});
 
-	BOOST_TEST(code == server_error::invalid_nickname);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_nickname);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-kick");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_nickname);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_nickname_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-kick"   },
 		{ "server",     "test"          },
 		{ "target",     123456          },
 		{ "channel",    "#music"        }
 	});
 
-	BOOST_TEST(code == server_error::invalid_nickname);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_nickname);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-kick");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_nickname);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_channel_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-kick"   },
 		{ "server",     "test"          },
 		{ "target",     "jean"          },
 		{ "channel",    ""              }
 	});
 
-	BOOST_TEST(code == server_error::invalid_channel);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_channel);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-kick");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_channel);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_channel_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-kick"   },
 		{ "server",     "test"          },
 		{ "target",     "jean"          },
 		{ "channel",    123456          }
 	});
 
-	BOOST_TEST(code == server_error::invalid_channel);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_channel);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-kick");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_channel);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_message)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-kick"   },
 		{ "server",     "test"          },
 		{ "target",     "jean"          },
@@ -163,22 +166,24 @@
 		{ "reason",     123456          }
 	});
 
-	BOOST_TEST(code == server_error::invalid_message);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_message);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-kick");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_message);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(not_found)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-kick"   },
 		{ "server",     "unknown"       },
 		{ "target",     "francis"       },
 		{ "channel",    "#music"        }
 	});
 
-	BOOST_TEST(code == server_error::not_found);
-	BOOST_TEST(json["error"].get<int>() == server_error::not_found);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-kick");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::not_found);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
--- a/tests/src/libirccd-daemon/command-server-list/main.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/tests/src/libirccd-daemon/command-server-list/main.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -21,20 +21,17 @@
 
 #include <irccd/test/command_fixture.hpp>
 
-using irccd::test::command_fixture;
-using irccd::test::mock_server;
-
 namespace irccd {
 
 namespace {
 
-class server_list_fixture : public command_fixture {
+class server_list_fixture : public test::command_fixture {
 protected:
 	server_list_fixture()
 	{
 		bot_.servers().clear();
-		bot_.servers().add(std::make_unique<mock_server>(ctx_, "s1", "localhost"));
-		bot_.servers().add(std::make_unique<mock_server>(ctx_, "s2", "localhost"));
+		bot_.servers().add(std::make_unique<test::mock_server>(ctx_, "s1", "localhost"));
+		bot_.servers().add(std::make_unique<test::mock_server>(ctx_, "s2", "localhost"));
 	}
 };
 
@@ -42,11 +39,12 @@
 
 BOOST_AUTO_TEST_CASE(basic)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command", "server-list" }
 	});
 
-	BOOST_TEST(!code);
+	BOOST_TEST(json.size() == 2U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-list");
 	BOOST_TEST(json.is_object());
 	BOOST_TEST(json["list"].is_array());
 	BOOST_TEST(json["list"].size() == 2U);
--- a/tests/src/libirccd-daemon/command-server-me/main.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/tests/src/libirccd-daemon/command-server-me/main.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -21,20 +21,15 @@
 
 #include <irccd/test/command_fixture.hpp>
 
-using irccd::test::command_fixture;
-
-using irccd::daemon::server;
-using irccd::daemon::server_error;
-
 namespace irccd {
 
 namespace {
 
-BOOST_FIXTURE_TEST_SUITE(server_me_fixture_suite, command_fixture)
+BOOST_FIXTURE_TEST_SUITE(server_me_fixture_suite, test::command_fixture)
 
 BOOST_AUTO_TEST_CASE(basic)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-me"     },
 		{ "server",     "test"          },
 		{ "target",     "jean"          },
@@ -43,7 +38,8 @@
 
 	const auto cmd = server_->find("me").back();
 
-	BOOST_TEST(!code);
+	BOOST_TEST(json.size() == 1U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-me");
 	BOOST_TEST(std::any_cast<std::string>(cmd[1]) == "hello!");
 	BOOST_TEST(std::any_cast<std::string>(cmd[0]) == "jean");
 }
@@ -52,71 +48,76 @@
 
 BOOST_AUTO_TEST_CASE(invalid_identifier_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-me"     },
 		{ "server",     123456          },
 		{ "target",     "#music"        },
 		{ "message",    "hello!"        }
 	});
 
-	BOOST_TEST(code == server_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-me");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_identifier_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-me"     },
 		{ "server",     ""              },
 		{ "target",     "#music"        },
 		{ "message",    "hello!"        }
 	});
 
-	BOOST_TEST(code == server_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-me");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_channel_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-me"     },
 		{ "server",     "test"          },
 		{ "target",     ""              },
 		{ "message",    "hello!"        }
 	});
 
-	BOOST_TEST(code == server_error::invalid_channel);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_channel);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-me");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_channel);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_channel_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-me"     },
 		{ "server",     "test"          },
 		{ "target",     123456          },
 		{ "message",    "hello!"        }
 	});
 
-	BOOST_TEST(code == server_error::invalid_channel);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_channel);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-me");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_channel);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(not_found)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-me"     },
 		{ "server",     "unknown"       },
 		{ "target",     "#music"        },
 		{ "message",    "hello!"        }
 	});
 
-	BOOST_TEST(code == server_error::not_found);
-	BOOST_TEST(json["error"].get<int>() == server_error::not_found);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-me");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::not_found);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
--- a/tests/src/libirccd-daemon/command-server-message/main.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/tests/src/libirccd-daemon/command-server-message/main.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -21,20 +21,15 @@
 
 #include <irccd/test/command_fixture.hpp>
 
-using irccd::test::command_fixture;
-
-using irccd::daemon::server;
-using irccd::daemon::server_error;
-
 namespace irccd {
 
 namespace {
 
-BOOST_FIXTURE_TEST_SUITE(server_message_fixture_suite, command_fixture)
+BOOST_FIXTURE_TEST_SUITE(server_message_fixture_suite, test::command_fixture)
 
 BOOST_AUTO_TEST_CASE(basic)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-message"        },
 		{ "server",     "test"                  },
 		{ "target",     "#staff"                },
@@ -43,7 +38,8 @@
 
 	const auto cmd = server_->find("message").back();
 
-	BOOST_TEST(!code);
+	BOOST_TEST(json.size() == 1U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-message");
 	BOOST_TEST(std::any_cast<std::string>(cmd[1]) == "plop!");
 	BOOST_TEST(std::any_cast<std::string>(cmd[0]) == "#staff");
 }
@@ -52,71 +48,76 @@
 
 BOOST_AUTO_TEST_CASE(invalid_identifier_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-message"        },
 		{ "server",     123456                  },
 		{ "target",     "#music"                },
 		{ "message",    "plop!"                 }
 	});
 
-	BOOST_TEST(code == server_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-message");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_identifier_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-message"        },
 		{ "server",     ""                      },
 		{ "target",     "#music"                },
 		{ "message",    "plop!"                 }
 	});
 
-	BOOST_TEST(code == server_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-message");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_channel_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-message"        },
 		{ "server",     "test"                  },
 		{ "target",     ""                      },
 		{ "message",    "plop!"                 }
 	});
 
-	BOOST_TEST(code == server_error::invalid_channel);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_channel);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-message");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_channel);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_channel_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-message"        },
 		{ "server",     "test"                  },
 		{ "target",     123456                  },
 		{ "message",    "plop!"                 }
 	});
 
-	BOOST_TEST(code == server_error::invalid_channel);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_channel);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-message");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_channel);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(not_found)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-message"        },
 		{ "server",     "unknown"               },
 		{ "target",     "#music"                },
 		{ "message",    "plop!"                 }
 	});
 
-	BOOST_TEST(code == server_error::not_found);
-	BOOST_TEST(json["error"].get<int>() == server_error::not_found);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-message");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::not_found);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
--- a/tests/src/libirccd-daemon/command-server-mode/main.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/tests/src/libirccd-daemon/command-server-mode/main.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -21,20 +21,15 @@
 
 #include <irccd/test/command_fixture.hpp>
 
-using irccd::test::command_fixture;
-
-using irccd::daemon::server;
-using irccd::daemon::server_error;
-
 namespace irccd {
 
 namespace {
 
-BOOST_FIXTURE_TEST_SUITE(server_mode_fixture_suite, command_fixture)
+BOOST_FIXTURE_TEST_SUITE(server_mode_fixture_suite, test::command_fixture)
 
 BOOST_AUTO_TEST_CASE(basic)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-mode"   },
 		{ "server",     "test"          },
 		{ "channel",    "#irccd"        },
@@ -43,7 +38,8 @@
 
 	const auto cmd = server_->find("mode").back();
 
-	BOOST_TEST(!code);
+	BOOST_TEST(json.size() == 1U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-mode");
 	BOOST_TEST(std::any_cast<std::string>(cmd[0]) == "#irccd");
 	BOOST_TEST(std::any_cast<std::string>(cmd[1]) == "+t");
 }
@@ -52,98 +48,106 @@
 
 BOOST_AUTO_TEST_CASE(invalid_identifier_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-mode"   },
 		{ "server",     123456          },
 		{ "channel",    "#music"        },
 		{ "mode",       "+i"            }
 	});
 
-	BOOST_TEST(code == server_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-mode");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_identifier_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-mode"   },
 		{ "server",     ""              },
 		{ "channel",    "#music"        },
 		{ "mode",       "+i"            }
 	});
 
-	BOOST_TEST(code == server_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-mode");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_channel_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-mode"   },
 		{ "server",     "test"          },
 		{ "channel",    ""              },
 		{ "mode",       "+i"            }
 	});
 
-	BOOST_TEST(code == server_error::invalid_channel);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_channel);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-mode");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_channel);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_channel_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-mode"   },
 		{ "server",     "test"          },
 		{ "channel",    123456          },
 		{ "mode",       "+i"            }
 	});
 
-	BOOST_TEST(code == server_error::invalid_channel);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_channel);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-mode");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_channel);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_mode_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-mode"   },
 		{ "server",     "test"          },
 		{ "channel",    "#music"        },
 		{ "mode",       ""              }
 	});
 
-	BOOST_TEST(code == server_error::invalid_mode);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_mode);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-mode");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_mode);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_mode_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-mode"   },
 		{ "server",     "test"          },
 		{ "channel",    "#music"        },
 		{ "mode",       123456          }
 	});
 
-	BOOST_TEST(code == server_error::invalid_mode);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_mode);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-mode");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_mode);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
+
 BOOST_AUTO_TEST_CASE(not_found)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-mode"   },
 		{ "server",     "unknown"       },
 		{ "channel",    "#music"        },
 		{ "mode",       "+i"            }
 	});
 
-	BOOST_TEST(code == server_error::not_found);
-	BOOST_TEST(json["error"].get<int>() == server_error::not_found);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-mode");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::not_found);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
--- a/tests/src/libirccd-daemon/command-server-nick/main.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/tests/src/libirccd-daemon/command-server-nick/main.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -21,27 +21,22 @@
 
 #include <irccd/test/command_fixture.hpp>
 
-using irccd::test::command_fixture;
-
-using irccd::daemon::server;
-using irccd::daemon::server_error;
-
 namespace irccd {
 
 namespace {
 
-BOOST_FIXTURE_TEST_SUITE(server_nick_fixture_suite, command_fixture)
+BOOST_FIXTURE_TEST_SUITE(server_nick_fixture_suite, test::command_fixture)
 
 BOOST_AUTO_TEST_CASE(basic)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-nick"   },
 		{ "server",     "test"          },
 		{ "nickname",   "chris"         }
 	});
 
-	BOOST_TEST(!code);
-	BOOST_TEST(json.is_object());
+	BOOST_TEST(json.size() == 1U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-nick");
 	BOOST_TEST(server_->get_nickname() == "chris");
 }
 
@@ -49,65 +44,70 @@
 
 BOOST_AUTO_TEST_CASE(invalid_identifier_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-nick"   },
 		{ "server",     123456          },
 		{ "nickname",   "chris"         }
 	});
 
-	BOOST_TEST(code == server_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-nick");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_identifier_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-nick"   },
 		{ "server",     ""              },
 		{ "nickname",   "chris"         }
 	});
 
-	BOOST_TEST(code == server_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-nick");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_nickname_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-nick"   },
 		{ "server",     "test"          },
 		{ "nickname",   ""              }
 	});
 
-	BOOST_TEST(code == server_error::invalid_nickname);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_nickname);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-nick");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_nickname);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_nickname_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-nick"   },
 		{ "server",     "test"          },
 		{ "nickname",   123456          }
 	});
 
-	BOOST_TEST(code == server_error::invalid_nickname);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_nickname);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-nick");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_nickname);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 BOOST_AUTO_TEST_CASE(not_found)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-nick"   },
 		{ "server",     "unknown"       },
 		{ "nickname",   "chris"         }
 	});
 
-	BOOST_TEST(code == server_error::not_found);
-	BOOST_TEST(json["error"].get<int>() == server_error::not_found);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-nick");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::not_found);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
--- a/tests/src/libirccd-daemon/command-server-notice/main.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/tests/src/libirccd-daemon/command-server-notice/main.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -21,20 +21,15 @@
 
 #include <irccd/test/command_fixture.hpp>
 
-using irccd::test::command_fixture;
-
-using irccd::daemon::server;
-using irccd::daemon::server_error;
-
 namespace irccd {
 
 namespace {
 
-BOOST_FIXTURE_TEST_SUITE(server_notice_fixture_suite, command_fixture)
+BOOST_FIXTURE_TEST_SUITE(server_notice_fixture_suite, test::command_fixture)
 
 BOOST_AUTO_TEST_CASE(basic)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-notice" },
 		{ "server",     "test"          },
 		{ "target",     "#staff"        },
@@ -43,7 +38,8 @@
 
 	const auto cmd = server_->find("notice").back();
 
-	BOOST_TEST(!code);
+	BOOST_TEST(json.size() == 1U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-notice");
 	BOOST_TEST(std::any_cast<std::string>(cmd[1]) == "quiet!");
 	BOOST_TEST(std::any_cast<std::string>(cmd[0]) == "#staff");
 }
@@ -52,71 +48,76 @@
 
 BOOST_AUTO_TEST_CASE(invalid_identifier_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-notice" },
 		{ "server",     123456          },
 		{ "target",     "#music"        },
 		{ "message",    "quiet!"        }
 	});
 
-	BOOST_TEST(code == server_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-notice");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_identifier_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-notice" },
 		{ "server",     ""              },
 		{ "target",     "#music"        },
 		{ "message",    "quiet!"        }
 	});
 
-	BOOST_TEST(code == server_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-notice");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_channel_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-notice" },
 		{ "server",     "test"          },
 		{ "target",     ""              },
 		{ "message",    "quiet!"        }
 	});
 
-	BOOST_TEST(code == server_error::invalid_channel);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_channel);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-notice");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_channel);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_channel_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-notice" },
 		{ "server",     "test"          },
 		{ "target",     123456          },
 		{ "message",    "quiet!"        }
 	});
 
-	BOOST_TEST(code == server_error::invalid_channel);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_channel);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-notice");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_channel);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(not_found)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-notice" },
 		{ "server",     "unknown"       },
 		{ "target",     "#music"        },
 		{ "message",    "quiet!"        }
 	});
 
-	BOOST_TEST(code == server_error::not_found);
-	BOOST_TEST(json["error"].get<int>() == server_error::not_found);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-notice");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::not_found);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
--- a/tests/src/libirccd-daemon/command-server-part/main.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/tests/src/libirccd-daemon/command-server-part/main.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -21,20 +21,15 @@
 
 #include <irccd/test/command_fixture.hpp>
 
-using irccd::test::command_fixture;
-
-using irccd::daemon::server;
-using irccd::daemon::server_error;
-
 namespace irccd {
 
 namespace {
 
-BOOST_FIXTURE_TEST_SUITE(server_part_fixture_suite, command_fixture)
+BOOST_FIXTURE_TEST_SUITE(server_part_fixture_suite, test::command_fixture)
 
 BOOST_AUTO_TEST_CASE(basic)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-part"   },
 		{ "server",     "test"          },
 		{ "channel",    "#staff"        },
@@ -43,14 +38,15 @@
 
 	const auto cmd = server_->find("part").back();
 
-	BOOST_TEST(!code);
+	BOOST_TEST(json.size() == 1U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-part");
 	BOOST_TEST(std::any_cast<std::string>(cmd[0]) == "#staff");
 	BOOST_TEST(std::any_cast<std::string>(cmd[1]) == "too noisy");
 }
 
 BOOST_AUTO_TEST_CASE(noreason)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-part"   },
 		{ "server",     "test"          },
 		{ "channel",    "#staff"        }
@@ -58,7 +54,8 @@
 
 	const auto cmd = server_->find("part").back();
 
-	BOOST_TEST(!code);
+	BOOST_TEST(json.size() == 1U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-part");
 	BOOST_TEST(std::any_cast<std::string>(cmd[0]) == "#staff");
 	BOOST_TEST(std::any_cast<std::string>(cmd[1]) == "");
 }
@@ -67,66 +64,71 @@
 
 BOOST_AUTO_TEST_CASE(invalid_identifier_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-part"   },
 		{ "server",     123456          },
 		{ "channel",    "#music"        }
 	});
 
-	BOOST_TEST(code == server_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-part");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_identifier_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-part"   },
 		{ "server",     ""              },
 		{ "channel",    "#music"        }
 	});
 
-	BOOST_TEST(code == server_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-part");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_channel_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-part"   },
 		{ "server",     "test"          },
 		{ "channel",    ""              }
 	});
 
-	BOOST_TEST(code == server_error::invalid_channel);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_channel);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-part");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_channel);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_channel_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-part"   },
 		{ "server",     "test"          },
 		{ "channel",    123456          }
 	});
 
-	BOOST_TEST(code == server_error::invalid_channel);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_channel);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-part");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_channel);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(not_found)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-part"   },
 		{ "server",     "unknown"       },
 		{ "channel",    "#music"        }
 	});
 
-	BOOST_TEST(code == server_error::not_found);
-	BOOST_TEST(json["error"].get<int>() == server_error::not_found);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-part");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::not_found);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
--- a/tests/src/libirccd-daemon/command-server-reconnect/main.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/tests/src/libirccd-daemon/command-server-reconnect/main.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -21,24 +21,18 @@
 
 #include <irccd/test/command_fixture.hpp>
 
-using irccd::test::command_fixture;
-using irccd::test::mock_server;
-
-using irccd::daemon::server;
-using irccd::daemon::server_error;
-
 namespace irccd {
 
 namespace {
 
-class server_reconnect_fixture : public command_fixture {
+class server_reconnect_fixture : public test::command_fixture {
 protected:
-	std::shared_ptr<mock_server> s1_;
-	std::shared_ptr<mock_server> s2_;
+	std::shared_ptr<test::mock_server> s1_;
+	std::shared_ptr<test::mock_server> s2_;
 
 	server_reconnect_fixture()
-		: s1_(new mock_server(ctx_, "s1", "localhost"))
-		, s2_(new mock_server(ctx_, "s2", "localhost"))
+		: s1_(new test::mock_server(ctx_, "s1", "localhost"))
+		, s2_(new test::mock_server(ctx_, "s2", "localhost"))
 	{
 		bot_.servers().clear();
 		bot_.servers().add(s1_);
@@ -52,12 +46,13 @@
 
 BOOST_AUTO_TEST_CASE(basic)
 {
-	const auto [_, code] = request({
+	const auto json = request({
 		{ "command",    "server-reconnect"      },
 		{ "server",     "s1"                    }
 	});
 
-	BOOST_TEST(!code);
+	BOOST_TEST(json.size() == 1U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-reconnect");
 	BOOST_TEST(s1_->find("disconnect").size() == 1U);
 	BOOST_TEST(s1_->find("connect").size() == 1U);
 	BOOST_TEST(s2_->empty());
@@ -65,9 +60,10 @@
 
 BOOST_AUTO_TEST_CASE(all)
 {
-	const auto [_, code] = request({{ "command", "server-reconnect" }});
+	const auto json = request({{ "command", "server-reconnect" }});
 
-	BOOST_TEST(!code);
+	BOOST_TEST(json.size() == 1U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-reconnect");
 	BOOST_TEST(s1_->find("disconnect").size() == 1U);
 	BOOST_TEST(s1_->find("connect").size() == 1U);
 	BOOST_TEST(s2_->find("disconnect").size() == 1U);
@@ -78,37 +74,40 @@
 
 BOOST_AUTO_TEST_CASE(invalid_identifier_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-reconnect"      },
 		{ "server",     123456                  }
 	});
 
-	BOOST_TEST(code == server_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-reconnect");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_identifier_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-reconnect"      },
 		{ "server",     ""                      }
 	});
 
-	BOOST_TEST(code == server_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-reconnect");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(not_found)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-reconnect"      },
 		{ "server",     "unknown"               }
 	});
 
-	BOOST_TEST(code == server_error::not_found);
-	BOOST_TEST(json["error"].get<int>() == server_error::not_found);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-reconnect");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::not_found);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
--- a/tests/src/libirccd-daemon/command-server-topic/main.cpp	Thu Feb 07 11:42:49 2019 +0100
+++ b/tests/src/libirccd-daemon/command-server-topic/main.cpp	Mon Feb 11 20:30:00 2019 +0100
@@ -21,20 +21,15 @@
 
 #include <irccd/test/command_fixture.hpp>
 
-using irccd::test::command_fixture;
-
-using irccd::daemon::server;
-using irccd::daemon::server_error;
-
 namespace irccd {
 
 namespace {
 
-BOOST_FIXTURE_TEST_SUITE(server_topic_fixture_suite, command_fixture)
+BOOST_FIXTURE_TEST_SUITE(server_topic_fixture_suite, test::command_fixture)
 
 BOOST_AUTO_TEST_CASE(basic)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-topic"  },
 		{ "server",     "test"          },
 		{ "channel",    "#staff"        },
@@ -43,7 +38,8 @@
 
 	const auto cmd = server_->find("topic").back();
 
-	BOOST_TEST(!code);
+	BOOST_TEST(json.size() == 1U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-topic");
 	BOOST_TEST(std::any_cast<std::string>(cmd[0]) == "#staff");
 	BOOST_TEST(std::any_cast<std::string>(cmd[1]) == "new version");
 }
@@ -52,71 +48,76 @@
 
 BOOST_AUTO_TEST_CASE(invalid_identifier_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-topic"  },
 		{ "server",     123456          },
 		{ "channel",    "#music"        },
 		{ "topic",      "plop"          }
 	});
 
-	BOOST_TEST(code == server_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-topic");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_identifier_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-topic"  },
 		{ "server",     ""              },
 		{ "channel",    "#music"        },
 		{ "topic",      "plop"          }
 	});
 
-	BOOST_TEST(code == server_error::invalid_identifier);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_identifier);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-topic");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_identifier);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_channel_1)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-topic"  },
 		{ "server",     "test"          },
 		{ "channel",    ""              },
 		{ "topic",      "plop"          }
 	});
 
-	BOOST_TEST(code == server_error::invalid_channel);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_channel);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-topic");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_channel);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(invalid_channel_2)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-topic"  },
 		{ "server",     "test"          },
 		{ "channel",    123456          },
 		{ "topic",      "plop"          }
 	});
 
-	BOOST_TEST(code == server_error::invalid_channel);
-	BOOST_TEST(json["error"].get<int>() == server_error::invalid_channel);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-topic");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::invalid_channel);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }
 
 BOOST_AUTO_TEST_CASE(not_found)
 {
-	const auto [json, code] = request({
+	const auto json = request({
 		{ "command",    "server-topic"  },
 		{ "server",     "unknown"       },
 		{ "channel",    "#music"        },
 		{ "topic",      "plop"          }
 	});
 
-	BOOST_TEST(code == server_error::not_found);
-	BOOST_TEST(json["error"].get<int>() == server_error::not_found);
+	BOOST_TEST(json.size() == 4U);
+	BOOST_TEST(json["command"].get<std::string>() == "server-topic");
+	BOOST_TEST(json["error"].get<int>() == daemon::server_error::not_found);
 	BOOST_TEST(json["errorCategory"].get<std::string>() == "server");
 }