# HG changeset patch # User David Demelier # Date 1464005141 -7200 # Node ID 70ed0753ce0d5100128097b7f3756da5877cd7e1 # Parent 52affa4ade71cc26a530e9839f21e11198d0c71c Plugin history: add initial unit test diff -r 52affa4ade71 -r 70ed0753ce0d cmake/function/IrccdDefineTest.cmake --- a/cmake/function/IrccdDefineTest.cmake Mon May 23 13:15:23 2016 +0200 +++ b/cmake/function/IrccdDefineTest.cmake Mon May 23 14:05:41 2016 +0200 @@ -77,6 +77,7 @@ PRIVATE ${TEST_FLAGS} SOURCEDIR="${CMAKE_CURRENT_SOURCE_DIR}" + BINARYDIR="${CMAKE_CURRENT_BINARY_DIR}" IRCCD_TESTS_DIRECTORY="${CMAKE_BINARY_DIR}/tests" ) diff -r 52affa4ade71 -r 70ed0753ce0d plugins/history/history.js --- a/plugins/history/history.js Mon May 23 13:15:23 2016 +0200 +++ b/plugins/history/history.js Mon May 23 14:05:41 2016 +0200 @@ -180,7 +180,7 @@ server.message(channel, Util.format(Plugin.format[args[0] == "seen" ? "seen" : "said"], kw)); } catch (e) { - server.message(channel, Util.format(kw)); + server.message(channel, Util.format(Plugin.format["error"], kw)); } } diff -r 52affa4ade71 -r 70ed0753ce0d tests/CMakeLists.txt --- a/tests/CMakeLists.txt Mon May 23 13:15:23 2016 +0200 +++ b/tests/CMakeLists.txt Mon May 23 14:05:41 2016 +0200 @@ -41,5 +41,6 @@ add_subdirectory(plugin-ask) add_subdirectory(plugin-auth) add_subdirectory(plugin-hangman) + add_subdirectory(plugin-history) endif () endif () diff -r 52affa4ade71 -r 70ed0753ce0d tests/plugin-history/CMakeLists.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/plugin-history/CMakeLists.txt Mon May 23 14:05:41 2016 +0200 @@ -0,0 +1,24 @@ +# +# CMakeLists.txt -- CMake build system for irccd +# +# Copyright (c) 2013-2016 David Demelier +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +irccd_define_test( + NAME plugin-history + SOURCES main.cpp + LIBRARIES libirccd + FLAGS PLUGINDIR=\"${IRCCD_FAKEROOTDIR}/${WITH_PLUGINDIR}\" +) diff -r 52affa4ade71 -r 70ed0753ce0d tests/plugin-history/broken-conf.json --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/plugin-history/broken-conf.json Mon May 23 14:05:41 2016 +0200 @@ -0,0 +1,1 @@ +this is not a json file diff -r 52affa4ade71 -r 70ed0753ce0d tests/plugin-history/main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/plugin-history/main.cpp Mon May 23 14:05:41 2016 +0200 @@ -0,0 +1,134 @@ +/* + * main.cpp -- test history plugin + * + * Copyright (c) 2013-2016 David Demelier + * + * 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 + +#include + +#include +#include +#include + +using namespace irccd; + +class ServerTest : public Server { +private: + std::string m_last; + +public: + inline ServerTest() + : Server("test", ServerInfo()) + { + } + + inline const std::string &last() const noexcept + { + return m_last; + } + + void message(std::string target, std::string message) override + { + m_last = util::join({target, message}); + } +}; + +class HistoryTest : public testing::Test { +protected: + Irccd m_irccd; + PluginService &m_ps; + + std::shared_ptr m_server; + std::shared_ptr m_plugin; + +public: + HistoryTest() + : m_ps(m_irccd.pluginService()) + , m_server(std::make_shared()) + { + m_ps.setFormats("history", { + { "error", "error=#{plugin}:#{command}:#{server}:#{channel}:#{origin}:#{nickname}" }, + { "seen", "seen=#{plugin}:#{command}:#{server}:#{channel}:#{origin}:#{nickname}:#{target}:%H:%M" }, + { "said", "said=#{plugin}:#{command}:#{server}:#{channel}:#{origin}:#{nickname}:#{target}:#{message}:%H:%M" }, + { "unknown", "unknown=#{plugin}:#{command}:#{server}:#{channel}:#{origin}:#{nickname}:#{target}" }, + }); + } + + void load(PluginConfig config = PluginConfig()) + { + // Add file if not there. + if (config.count("file") == 0) + config.emplace("file", SOURCEDIR "/words.conf"); + + m_ps.configure("history", config); + m_ps.load("history", PLUGINDIR "/history.js"); + m_plugin = m_ps.require("history"); + } +}; + +TEST_F(HistoryTest, formatError) +{ + load({{ "file", SOURCEDIR "/broken-conf.json" }}); + + m_plugin->onCommand(m_irccd, m_server, "jean!jean@localhost", "#history", "seen francis"); + ASSERT_EQ("#history:error=history:!history:test:#history:jean!jean@localhost:jean", m_server->last()); +} + +TEST_F(HistoryTest, formatSeen) +{ + std::regex rule("#history:seen=history:!history:test:#history:destructor!dst@localhost:destructor:jean:\\d{2}:\\d{2}"); + + remove(BINARYDIR "/seen.json"); + load({{ "file", BINARYDIR "/seen.json" }}); + + m_plugin->onMessage(m_irccd, m_server, "jean!jean@localhost", "#history", "hello"); + m_plugin->onCommand(m_irccd, m_server, "destructor!dst@localhost", "#history", "seen jean"); + + ASSERT_TRUE(std::regex_match(m_server->last(), rule)); +} + +TEST_F(HistoryTest, formatSaid) +{ + std::regex rule("#history:said=history:!history:test:#history:destructor!dst@localhost:destructor:jean:hello:\\d{2}:\\d{2}"); + + remove(BINARYDIR "/said.json"); + load({{ "file", BINARYDIR "/said.json" }}); + + m_plugin->onMessage(m_irccd, m_server, "jean!jean@localhost", "#history", "hello"); + m_plugin->onCommand(m_irccd, m_server, "destructor!dst@localhost", "#history", "said jean"); + + ASSERT_TRUE(std::regex_match(m_server->last(), rule)); +} + +TEST_F(HistoryTest, formatUnknown) +{ + remove(BINARYDIR "/unknown.json"); + load({{ "file", BINARYDIR "/unknown.json" }}); + + m_plugin->onMessage(m_irccd, m_server, "jean!jean@localhost", "#history", "hello"); + m_plugin->onCommand(m_irccd, m_server, "destructor!dst@localhost", "#history", "seen nobody"); + + ASSERT_EQ("#history:unknown=history:!history:test:#history:destructor!dst@localhost:destructor:nobody", m_server->last()); +} + +int main(int argc, char **argv) +{ + path::setApplicationPath(argv[0]); + testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +}