diff options
-rw-r--r-- | connectionregistry.h | 12 | ||||
-rw-r--r-- | diff.cpp | 4 | ||||
-rw-r--r-- | tests/Makefile | 1 | ||||
-rw-r--r-- | tests/test-connectionregistry.cpp | 144 | ||||
-rw-r--r-- | tests/test-diff.cpp | 110 | ||||
-rw-r--r-- | tests/test-whiteboard.cpp | 68 |
6 files changed, 272 insertions, 67 deletions
diff --git a/connectionregistry.h b/connectionregistry.h index cdd30d9..155ab31 100644 --- a/connectionregistry.h +++ b/connectionregistry.h @@ -22,16 +22,18 @@ public: void addConnection(connection c); void delConnection(connection c); - // map connection to id - std::unordered_map<connection, std::string> m_connections; - // map id to list of related connections, used for iteration over connections to notify about changes - std::unordered_map<std::string, std::unordered_set<connection>> m_ids; - std::unordered_set<connection>::iterator begin(const std::string& id); std::unordered_set<connection>::iterator end(const std::string& id); void dump() const; +private: + // map connection to id + std::unordered_map<connection, std::string> m_connections; + // map id to list of related connections, used for iteration over connections to notify about changes + std::unordered_map<std::string, std::unordered_set<connection>> m_ids; + +public: class RegistryGuard { public: @@ -115,6 +115,10 @@ void Diff::create(const std::string& xml) m_pos0 = tree.get<int>("diff.start"); m_pos1 = tree.get<int>("diff.end"); + + if (m_pos0 > m_pos1) + throw std::runtime_error("Bad range in diff"); + m_data = tree.get<std::string>("diff.data"); } diff --git a/tests/Makefile b/tests/Makefile index 0347210..f3ec6c8 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -15,6 +15,7 @@ UNITS=storage.cpp config.cpp compiledsql.cpp qrcode.cpp whiteboard.cpp connectio UNITTESTS=test-config.cpp \ test-storage.cpp \ + test-connectionregistry.cpp \ test-compiledsql.cpp \ test-qrcode.cpp \ test-whiteboard.cpp \ diff --git a/tests/test-connectionregistry.cpp b/tests/test-connectionregistry.cpp new file mode 100644 index 0000000..1f68dd9 --- /dev/null +++ b/tests/test-connectionregistry.cpp @@ -0,0 +1,144 @@ +#include <gtest/gtest.h> + +#include <filesystem> +#include <string> +#include <system_error> + +#include <boost/beast/core.hpp> +#include <boost/beast/http.hpp> + +#include "libreichwein/file.h" + +#include "connectionregistry.h" + +namespace fs = std::filesystem; +using namespace Reichwein; + +class ConnectionRegistryTest: public ::testing::Test +{ +protected: + ConnectionRegistryTest(){ + } + + ~ConnectionRegistryTest(){ + } +}; + +TEST_F(ConnectionRegistryTest, constructor) +{ + ConnectionRegistry cr{}; +} + +TEST_F(ConnectionRegistryTest, test_addConnection) +{ + boost::asio::io_context ioc{1}; + + boost::asio::ip::tcp::socket ts0{ioc}; + ConnectionRegistry::connection c0 {std::make_shared<ConnectionRegistry::connection::element_type>(std::move(ts0))}; + + boost::asio::ip::tcp::socket ts1{ioc}; + ConnectionRegistry::connection c1 {std::make_shared<ConnectionRegistry::connection::element_type>(std::move(ts1))}; + + ConnectionRegistry cr{}; + + cr.addConnection(c0); + EXPECT_THROW(cr.addConnection(c0), std::exception); + cr.addConnection(c1); + EXPECT_THROW(cr.addConnection(c0), std::exception); + EXPECT_THROW(cr.addConnection(c1), std::exception); +} + +TEST_F(ConnectionRegistryTest, test_delConnection) +{ + boost::asio::io_context ioc{1}; + + boost::asio::ip::tcp::socket ts0{ioc}; + ConnectionRegistry::connection c0 {std::make_shared<ConnectionRegistry::connection::element_type>(std::move(ts0))}; + + boost::asio::ip::tcp::socket ts1{ioc}; + ConnectionRegistry::connection c1 {std::make_shared<ConnectionRegistry::connection::element_type>(std::move(ts1))}; + + ConnectionRegistry cr{}; + + EXPECT_THROW(cr.delConnection(c0), std::exception); + + cr.addConnection(c0); + cr.delConnection(c0); + + cr.addConnection(c0); + cr.addConnection(c1); + cr.delConnection(c0); + EXPECT_THROW(cr.delConnection(c0), std::exception); + cr.delConnection(c1); + EXPECT_THROW(cr.delConnection(c1), std::exception); +} + +TEST_F(ConnectionRegistryTest, test_setId) +{ + boost::asio::io_context ioc{1}; + boost::asio::ip::tcp::socket ts{ioc}; + + ConnectionRegistry::connection c {std::make_shared<ConnectionRegistry::connection::element_type>(std::move(ts))}; + + ConnectionRegistry cr{}; + + EXPECT_THROW(cr.setId(c, "id1"), std::exception); + cr.addConnection(c); + cr.setId(c, "id2"); +} + +TEST_F(ConnectionRegistryTest, test_dump) +{ + boost::asio::io_context ioc{1}; + boost::asio::ip::tcp::socket ts{ioc}; + + ConnectionRegistry::connection c {std::make_shared<ConnectionRegistry::connection::element_type>(std::move(ts))}; + + ConnectionRegistry cr{}; + + cr.addConnection(c); + cr.dump(); + + cr.setId(c, "id1"); + cr.dump(); +} + +TEST_F(ConnectionRegistryTest, test_iterators) +{ + boost::asio::io_context ioc{1}; + boost::asio::ip::tcp::socket ts{ioc}; + + ConnectionRegistry::connection c {std::make_shared<ConnectionRegistry::connection::element_type>(std::move(ts))}; + + ConnectionRegistry cr{}; + + EXPECT_THROW(cr.begin(""), std::exception); + EXPECT_THROW(cr.end(""), std::exception); + + cr.addConnection(c); + EXPECT_THROW(cr.begin(""), std::exception); + EXPECT_THROW(cr.end(""), std::exception); + + cr.setId(c, "id1"); + + EXPECT_EQ(std::distance(cr.begin("id1"), cr.end("id1")), 1); +} + +TEST_F(ConnectionRegistryTest, test_guard) +{ + boost::asio::io_context ioc{1}; + boost::asio::ip::tcp::socket ts{ioc}; + + ConnectionRegistry::connection c {std::make_shared<ConnectionRegistry::connection::element_type>(std::move(ts))}; + + ConnectionRegistry cr{}; + + { + ConnectionRegistry::RegistryGuard rg{cr, c}; + + EXPECT_THROW(cr.addConnection(c), std::exception); + } + + EXPECT_THROW(cr.delConnection(c), std::exception); +} + diff --git a/tests/test-diff.cpp b/tests/test-diff.cpp index b6b703a..7061ef0 100644 --- a/tests/test-diff.cpp +++ b/tests/test-diff.cpp @@ -4,6 +4,8 @@ #include <string> #include <system_error> +#include <stdlib.h> + #include "libreichwein/file.h" #include "diff.h" @@ -23,6 +25,112 @@ protected: TEST_F(DiffTest, constructor) { - Diff diff{}; + // empty constructor + { + Diff d{}; + EXPECT_EQ(d.get_xml(), "<diff><start>0</start><end>0</end><data/></diff>"); + } + + // constructor via xml diff + { + EXPECT_THROW(Diff d{""}, std::exception); + } + { + EXPECT_THROW(Diff d{"<diff><begin></begin></diff>"}, std::exception); + EXPECT_THROW(Diff d{"<diff><end>0</end><data>abc</data></diff>"}, std::exception); + EXPECT_THROW(Diff d{"<diff><start>0</start><data>abc</data></diff>"}, std::exception); + EXPECT_THROW(Diff d{"<diff><start>0</start><end>0</end></diff>"}, std::exception); + EXPECT_THROW(Diff d{"<diff><start>5</start><end>0</end><data>abc</data></diff>"}, std::exception); + EXPECT_THROW(Diff d{"<diff><start></start><end>0</end><data>abc</data></diff>"}, std::exception); + } + + { + Diff d{"<diff><start>0</start><end>0</end><data>abc</data></diff>"}; + EXPECT_EQ(d.get_xml(), "<diff><start>0</start><end>0</end><data>abc</data></diff>"); + } + + { + Diff d{"<diff><start>5</start><end>5</end><data>abc</data></diff>"}; + EXPECT_EQ(d.get_xml(), "<diff><start>5</start><end>5</end><data>abc</data></diff>"); + } + + { + Diff d{"<diff><start>5</start><end>50</end><data>abc</data></diff>"}; + EXPECT_EQ(d.get_xml(), "<diff><start>5</start><end>50</end><data>abc</data></diff>"); + } + + // constructor via versions + { + Diff d{"", ""}; + EXPECT_EQ(d.get_xml(), "<diff><start>0</start><end>0</end><data/></diff>"); + } + { + Diff d{"a", "a"}; + EXPECT_EQ(d.get_xml(), "<diff><start>0</start><end>0</end><data/></diff>"); + } + { + Diff d{"a", "b"}; + EXPECT_EQ(d.get_xml(), "<diff><start>0</start><end>1</end><data>b</data></diff>"); + } + { + Diff d{"0a1", "0b1"}; + EXPECT_EQ(d.get_xml(), "<diff><start>1</start><end>2</end><data>b</data></diff>"); + } + { + Diff d{"0abc1", "00b01"}; + EXPECT_EQ(d.get_xml(), "<diff><start>1</start><end>4</end><data>0b0</data></diff>"); + } + { + Diff d{"0ab1", "00b01"}; + EXPECT_EQ(d.get_xml(), "<diff><start>1</start><end>3</end><data>0b0</data></diff>"); + } + { + Diff d{"0abc1", "00b1"}; + EXPECT_EQ(d.get_xml(), "<diff><start>1</start><end>4</end><data>0b</data></diff>"); + } + { + Diff d{"0abc1", ""}; + EXPECT_EQ(d.get_xml(), "<diff><start>0</start><end>5</end><data/></diff>"); + } + { + Diff d{"bc1", "0abc1"}; + EXPECT_EQ(d.get_xml(), "<diff><start>0</start><end>0</end><data>0a</data></diff>"); + } + { + Diff d{"0abc1", "0ab"}; + EXPECT_EQ(d.get_xml(), "<diff><start>3</start><end>5</end><data/></diff>"); + } + { + Diff d{"0abc1", "0abc123"}; + EXPECT_EQ(d.get_xml(), "<diff><start>5</start><end>5</end><data>23</data></diff>"); + } + { + Diff d{"0abc1", "010abc1"}; + EXPECT_EQ(d.get_xml(), "<diff><start>0</start><end>0</end><data>01</data></diff>"); + } + { + Diff d{"0abc1", "0ac1"}; + EXPECT_EQ(d.get_xml(), "<diff><start>2</start><end>3</end><data/></diff>"); + } + { + Diff d{"0abc1", "0abxc1"}; + EXPECT_EQ(d.get_xml(), "<diff><start>3</start><end>3</end><data>x</data></diff>"); + } +} + +TEST_F(DiffTest, diff_create) +{ + const char* result {diff_create("0abc1", "0ab")}; + + EXPECT_EQ(std::string(result), "<diff><start>3</start><end>5</end><data/></diff>"); + free((void*)result); // this will be done by javascript side in real scenario +} + +TEST_F(DiffTest, diff_apply) +{ + const char* result {diff_apply("0abc1", "<diff><start>3</start><end>5</end><data/></diff>")}; + + EXPECT_EQ(std::string(result), "0ab"); + free((void*)result); // this will be done by javascript side in real scenario } diff --git a/tests/test-whiteboard.cpp b/tests/test-whiteboard.cpp index a472d64..9e6b7fb 100644 --- a/tests/test-whiteboard.cpp +++ b/tests/test-whiteboard.cpp @@ -3,6 +3,7 @@ #include <cstring> #include <filesystem> #include <memory> +#include <regex> #include <string> #include <system_error> @@ -38,62 +39,6 @@ namespace { const fs::path testDbFilename{"./whiteboard.db3"}; } -class Webserver -{ -public: - Webserver() - { - File::setFile(webserverConfigFilename, R"CONFIG( -<webserver> - <user>www-data</user> - <group>www-data</group> - <threads>10</threads> - <statisticspath>stats.db</statisticspath> - <plugin-directory>../plugins</plugin-directory> - <sites> - <site> - <host>[::1]</host> - <path requested="/"> - <plugin>websocket</plugin> - <target>::1:9876</target> - </path> - </site> - </sites> - <sockets> - <socket> - <address>::1</address> - <port>8080</port> - <protocol>http</protocol> - <site>localhost</site> - </socket> - </sockets> -</webserver> -)CONFIG"); - start(); - } - - ~Webserver() - { - stop(); - fs::remove(webserverConfigFilename); - } - - void start() - { - m_child = bp::child("/usr/bin/webserver"s, "-c"s, webserverConfigFilename.generic_string()); - Process::wait_for_pid_listening_on(m_child.id(), 8080); - std::this_thread::sleep_for(std::chrono::milliseconds(20)); - } - - void stop() - { - m_child.terminate(); - } - -private: - bp::child m_child; -}; - class WhiteboardTest: public ::testing::Test { protected: @@ -118,8 +63,6 @@ protected: m_config = std::make_shared<Config>(testConfigFilename); - //m_webserver = std::make_shared<Webserver>(webserverConfigFilename); - m_pid = fork(); if (m_pid == -1) { throw std::runtime_error("Error on fork(): "s + strerror(errno)); @@ -151,7 +94,6 @@ protected: } std::shared_ptr<Config> m_config; - //std::shared_ptr<Webserver> m_webserver; pid_t m_pid{}; }; @@ -223,12 +165,16 @@ private: boost::asio::ip::tcp::endpoint ep_; }; -TEST_F(WhiteboardTest, connection) +// +// tests via websocket server in separate process (hides coverage) +// + +TEST_F(WhiteboardTest, websocket_server_connection) { WebsocketClient wc; } -TEST_F(WhiteboardTest, generate_id) +TEST_F(WhiteboardTest, websocket_server_generate_id) { WebsocketClient wc; |