diff --git a/.travis.yml b/.travis.yml index 84ac59a..f7cd9d0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,7 +29,6 @@ before_install: - sudo python ./serverAPI.py & script: - - ./linters/run.sh --local - mkdir build - cd build - cmake ../ diff --git a/Attraction b/Attraction new file mode 100644 index 0000000..e37e903 --- /dev/null +++ b/Attraction @@ -0,0 +1,11 @@ +1 1 1 Почтампт #0 +2 24 78 Музей_Пушкина #Пушкин#Дворец +3 5 13 Красная_площадь #Красная_площадь +4 5 10 Пушкинский_музей #История#Красная_площадь +5 4 8 Грановитая_палата #История#Красная_площадь#Искуство#шапка +6 5 11 Сабор_василия_блаженного #Красная_площадь#История#Храмы +7 56 65 ВДНХ #Выставка#Прогулка +8 58 65 Фонтан_дружбы_народов #Фонтан#История +9 54 63 Музей_космонавтики #Музеи#История#Космос +10 60 65 Каменный_цветок #Фонтан#История + diff --git a/CMakeLists.txt b/CMakeLists.txt index 39748bf..a11351b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,11 +23,21 @@ include_directories(include) add_library(algorithm STATIC src/algorithm.cpp) -add_library(queu STATIC src/queu.cpp) +add_library(queue STATIC src/queue.cpp) add_library(server STATIC src/server.cpp) +#find_package (SQLite3) +#if (SQLITE3_FOUND) +# include_directories(${SQLITE3_INCLUDE_DIRS}) +# target_link_libraries (new ${SQLITE3_LIBRARIES}) +#endif (SQLITE3_FOUND) + add_library(worker STATIC src/worker.cpp) -add_executable(test test/test.cpp src/worker.cpp) -target_link_libraries(test gtest) \ No newline at end of file +include_directories(/usr/include) +link_directories(/usr/lib) +target_link_libraries(worker gtest gmock new.cpp) + +add_executable(test test/test.cpp src/worker.cpp src/algorithm.cpp) +target_link_libraries(test gtest gmock) \ No newline at end of file diff --git a/include/Data.hpp b/include/Data.hpp new file mode 100644 index 0000000..b6d6681 --- /dev/null +++ b/include/Data.hpp @@ -0,0 +1,42 @@ +#include +#include +#include +#include + +#ifndef INCLUDE_DATA_HPP_ +#define INCLUDE_DATA_HPP_ + +static const unsigned MIN_IN_HOUR = 60; + +typedef std::pair Point; +typedef std::vector Points; +typedef std::vector Filters; + +struct DataIn { + Filters FilterList; + unsigned TimeLimit; + unsigned MaxDots; + Point StartPoint; + Point EndPoint; + int UserID; + DataIn() {} + DataIn(::Filters _f, unsigned _t, unsigned _md, Point _sp, Point _ep, + int _u) + : FilterList(_f), + TimeLimit(_t), + MaxDots(_md), + StartPoint(_sp), + EndPoint(_ep), + UserID(_u) {} +}; + +struct DataOut { + Points RoutePoints; + unsigned MaxTime; + int UserID; + DataOut() {} + DataOut(const Points&& _p, unsigned _t, int _u) + : RoutePoints(_p), MaxTime(_t), UserID(_u) {} +}; + +#endif // INCLUDE_DATA_HPP_ \ No newline at end of file diff --git a/include/algorithm.hpp b/include/algorithm.hpp index 9704b01..e3a4dd0 100644 --- a/include/algorithm.hpp +++ b/include/algorithm.hpp @@ -1,8 +1,57 @@ /* - * Copyright 2019 + * Copyright 2019 */ #ifndef INCLUDE_ALGORITHM_HPP_ #define INCLUDE_ALGORITHM_HPP_ +#include +#include +#include +#include +#include +#include +#include + +class Algorithm { + + public: + typedef std::size_t dotId; + typedef std::pair edge; + typedef std::size_t weight; + + private: + typedef boost::adjacency_list > graph_t; + typedef boost::graph_traits::vertex_descriptor vertex_descriptor; + + public: + Algorithm()= delete; + explicit Algorithm(const std::vector &edgeArr, const std::vector &weightArr); + ~Algorithm(); + Algorithm(const Algorithm&) = delete; + Algorithm(const Algorithm&&) = delete; + Algorithm& operator=(const Algorithm&) = delete; + Algorithm& operator=(const Algorithm&&) = delete; + + std::vector CalcRoute(const dotId &A, const dotId &B); + + std::pair, size_t> + getRoute(dotId from, const size_t &pointsCount, + const size_t &time, const size_t &maxPlacesCount); + + + + // delete this from algo and use from WorkerAPI + long int getWeightIndex(const size_t &pointsCount, const size_t &from, const size_t &to); + + private: + void MakeGraph(); + edge * edgeArr; + size_t edgeSize; + weight * weightArr; + graph_t myGraph; + const size_t MAX_PLACES = 200; // контроль (максимальное кол-во мест в пути) +}; + #endif // INCLUDE_ALGORITHM_HPP_ diff --git a/include/queu.hpp b/include/queu.hpp deleted file mode 100644 index 89cfa2b..0000000 --- a/include/queu.hpp +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright 2019 - */ - -#ifndef INCLUDE_QUEU_HPP_ -#define INCLUDE_QUEU_HPP_ - -#endif // INCLUDE_QUEU_HPP_ diff --git a/include/queue.hpp b/include/queue.hpp new file mode 100644 index 0000000..02c5de7 --- /dev/null +++ b/include/queue.hpp @@ -0,0 +1,59 @@ +/* + * Copyright 2019 + */ + +#ifndef INCLUDE_QUEUE_HPP_ +#define INCLUDE_QUEUE_HPP_ + + +#include +#include +#include + +template +class GQueue { +public: + GQueue() = delete; + explicit GQueue(const T &element404); + ~GQueue(); + void push(const T &element); + T popIfNotEmpty(); + + GQueue(const GQueue&) = delete; + GQueue(const GQueue&&) = delete; + GQueue& operator=(const GQueue&) = delete; + GQueue& operator=(const GQueue&&) = delete; + +private: + T element404; + std::unique_ptr> queue; + std::mutex GQueueMutex; +}; + +template +GQueue::~GQueue() = default; + +template +GQueue::GQueue(const T &element404) { + queue.reset(new std::queue); + this->element404 = element404; +} + +template +void GQueue::push(const T &element) { + const std::lock_guard lock(GQueueMutex); + queue->push(element); +} + +template +T GQueue::popIfNotEmpty() { + const std::lock_guard lock(GQueueMutex); + T answer = this->element404; + if (!queue->empty()) { + answer = queue->front(); + queue->pop(); + } + return answer; +} + +#endif // INCLUDE_QUEU_HPP_ diff --git a/include/worker.hpp b/include/worker.hpp index 93edf35..9d8342f 100644 --- a/include/worker.hpp +++ b/include/worker.hpp @@ -1,54 +1,77 @@ -/* - * Copyright 2019 - */ +#include +#include +#include +#include +//#include "sqlite-autoconf-3300100/sqlite3.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "queue.hpp" +#include "algorithm.hpp" +#include +#include "Data.hpp" +#include #ifndef INCLUDE_WORKER_HPP_ #define INCLUDE_WORKER_HPP_ -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -struct Point +struct Limit { - double X; - double Y; + double Point[4]; + int Number_of_dots; + int Time; }; -namespace http = boost::beast::http; - -class Worker { - -public: // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! PRIVATE AFTER TESTS !!!!!!!!!!!!!!!!!!!!!! - - // this typedef get from Algorithm before merge we don't know about Algo - typedef std::size_t dotId; - typedef std::pair edge; - typedef std::size_t weight; - - // храним в этих векторах данные, которые получим из API - std::vector edges; - std::vector weightArr; +struct Line { + int id; + std::string Name; + double x; + double y; + std::vectorTags; + Line(int ID, std::string n, double X, double Y, std::vectorT): id(ID), Name(std::move(n)), x(X), y(Y), Tags(std::move(T)){}; + Line(): id(0), Name("name"), x(0), y(0), Tags({}){}; +}; - const size_t MAX_POINT_COUNT = 500; - const size_t MIN_POINT_COUNT = 3; +class Table { + public: + std::ifstream file; + std::vector table; + public: + void SelectTag(std::vector values, std::vector& res); + void SelectAll(std::vector& res); + Table(std::string filename); + virtual ~Table(); +}; +class Worker +{ +private: + DataIn request; + Table DB; + GQueue &In; + GQueue &Out; + bool Stop; + std::vector> edges; // вектор из 2 точек + std::vector weightArr; // вес ребра + std::thread WProces; + DataIn GetFromQueueIn(); + void SendToQueueOut(const DataOut &value); + void GetDotsFromDB(const DataIn &value, std::vector &points); void GetRibsFromAPI(const std::vector &points); - void getWeightFromPythonAPI(const std::string &jsonPoints, std::string &answer); - std::string createJsonForSending(const std::vector &points); - void setJsonAnswerInClass(const std::string &answer, const size_t &pointCount); - + void GetRoutefromAlgorithm(const std::vector edge, const std::vector weight, + std::pair, size_t> &res, size_t num_dots, DataIn value); + void FinalPoints(std::vector &points, const std::pair, size_t> &res); + void WorkerProcess(); public: - - static long int getWeightIndex(const size_t &pointsCount, const size_t &from, const size_t &to); - + Worker(GQueue &in, GQueue &out, std::string DBName); + ~Worker(); + void GetRest(int timeToSleep); + void Kill(); + FRIEND_TEST(Get, Get_from_queu); + FRIEND_TEST(Send, Send_to_queu); + FRIEND_TEST(Get_dots, Get_dots_from_DB); + FRIEND_TEST(Get_dots2, Get_dots_from_DB2); + FRIEND_TEST(Get_dots3, Get_dots_from_DB3); + FRIEND_TEST(Get_dots4, NumberOfDots); + FRIEND_TEST(Get_dots5, NumberOfDots); }; #endif // INCLUDE_WORKER_HPP_ - diff --git a/src/algorithm.cpp b/src/algorithm.cpp index b27cdab..868d8c6 100644 --- a/src/algorithm.cpp +++ b/src/algorithm.cpp @@ -1,7 +1,156 @@ /* - * Copyright 2019 + * Copyright 2019 */ #include "algorithm.hpp" +Algorithm::Algorithm(const std::vector &edges, + const std::vector &weights) { + + assert(edges.size() == weights.size()); + + edgeSize = edges.size(); + edgeArr = new edge[edgeSize]; + weightArr = new weight[edgeSize]; + for (size_t i = 0; i < edgeSize; i++) { + *(edgeArr+i) = edges.at(i); + *(weightArr+i)= weights.at(i); + } +} + +Algorithm::~Algorithm() { + delete[]edgeArr; + delete[]weightArr; +} + +void Algorithm::MakeGraph() { + myGraph = graph_t(edgeArr, edgeArr + edgeSize, weightArr, edgeSize); + boost::property_map::type weightGraph = + get(boost::edge_weight, myGraph); +} + +std::vector Algorithm::CalcRoute(const dotId &A, + const dotId &B) { + MakeGraph(); + + // вектор для пройденных путей + std::vector pastWay(num_vertices(myGraph)); + // вектор для расстояния от корня + std::vector rootDist(num_vertices(myGraph)); + + // Обозначим начальную и конечную точку + vertex_descriptor pointA = vertex(A, myGraph); + vertex_descriptor pointB = vertex(B, myGraph); + + boost::dijkstra_shortest_paths(myGraph, pointA, + boost::predecessor_map(&pastWay[0]).distance_map(&rootDist[0])); + + std::vector::vertex_descriptor> path; + boost::graph_traits::vertex_descriptor current = pointB; + + // идем в обратную сторону и запоминаем путь + while ( current != pointA ) { + path.push_back(current); + current = pastWay[current]; + } + path.push_back(pointA); // добавляем в конец точку с которой начинали + + std::vector answer; + + // в ответ записываем в правильном порядке + std::vector::vertex_descriptor >:: + reverse_iterator iter; + for (iter = path.rbegin(); iter != path.rend(); ++iter) + answer.push_back(*iter); + + return answer; +} + +// new part +// возвращает id точек пути (включая исходную) и время для обхода +std::pair, size_t> +Algorithm::getRoute(Algorithm::dotId from, const size_t &pointsCount, + const size_t &time, const size_t &maxPlacesCount) { + + assert(time > 0); + assert(maxPlacesCount > 1); + + size_t currentTime = 0; + // если пользователь тратит время на нахождение в точке, то следует + // добавлять это время кажыдй раз к currentTime + std::pair, size_t> answer; + std::unordered_set visitedPints; + visitedPints.insert(from); // пользователь был в точке из который начинает маршут + answer.first.push_back(from); // дабавим начальную точку в путь + + // компаратор, чтобы сравнивать претендентов на место следущей точки + auto comp = [](std::pair a, std::pair b) + { return a.second < b.second; }; + + while(true) { + if (answer.first.size() >= maxPlacesCount + 1 || // maxPlacesCount + 1 так как в ответе + answer.first.size() > MAX_PLACES) // уже есть начальная точка + break; + + // получаем индекс, с которого находятся ребра от нашей вершины + size_t startRibsIndexInEdges = (pointsCount-1) * from; + + // получаем индекс, с которого находятся веса от нашей вершины + size_t weightIndex = getWeightIndex(pointsCount, from, edgeArr[startRibsIndexInEdges].second); + + // возможные пути из точки + std::set< std::pair, decltype(comp) > nextPointPretendents(comp); + + // обходим места, куда можем попасть из данной точки + for (size_t i = 0 ; i < pointsCount -1 ; i++, weightIndex++) { + + // не рассматриваем посещенные точки + if ( visitedPints.find(edgeArr[startRibsIndexInEdges + i].second) != visitedPints.end() ) + continue; + + // сохраняем допустимую точку + nextPointPretendents.insert(std::make_pair(edgeArr[startRibsIndexInEdges + i].second, + weightArr[weightIndex])); + } + + // ничего не добавили => всё обошли + if (nextPointPretendents.empty()) + break; + + // получаем ближайшую точку + std::pair pretendent = *nextPointPretendents.begin(); + if (currentTime + pretendent.second <= time) { + currentTime += pretendent.second; + from = pretendent.first; + answer.first.push_back(pretendent.first); + visitedPints.insert(pretendent.first); + } else + // ближайшая точка вне досягаемости за оставшееся время + break; + + } + answer.second = currentTime; + return answer; +} + + +// delete this from algo +// данная функция будет вызываться как статическая из воркера-апи +long int Algorithm::getWeightIndex(const size_t &pointsCount, const size_t &from, + const size_t &to) { + + if (from > pointsCount - 1 || to > pointsCount - 1 || + from == to) + return -1; // return error + + if (from == 0) + return to - 1; + + if (from < to) + return ( (pointsCount -1) * from + to) - 1; + + return ( (pointsCount -1) * from + to); + +} + diff --git a/src/queu.cpp b/src/queu.cpp deleted file mode 100644 index e0faea8..0000000 --- a/src/queu.cpp +++ /dev/null @@ -1,5 +0,0 @@ -/* - * Copyright 2019 - */ - -#include "queu.hpp" diff --git a/src/queue.cpp b/src/queue.cpp new file mode 100644 index 0000000..c1c64d5 --- /dev/null +++ b/src/queue.cpp @@ -0,0 +1,16 @@ +/* + * Copyright 2019 + */ + + +#include "queue.hpp" + +// template realization in header + + + + + + + + diff --git a/src/worker.cpp b/src/worker.cpp index dddab40..fe5a70f 100644 --- a/src/worker.cpp +++ b/src/worker.cpp @@ -1,128 +1,151 @@ -/* - * Copyright 2019 - */ - #include "worker.hpp" +#include "queue.hpp" +#include "algorithm.hpp" +#include -void Worker::GetRibsFromAPI(const std::vector &points ) { - - const size_t pointCount = points.size(); - if (pointCount < MIN_POINT_COUNT || pointCount > MAX_POINT_COUNT) - return; - - const std::string jsonForSending = createJsonForSending(points); - - std::string answer; - getWeightFromPythonAPI(jsonForSending, answer); - - setJsonAnswerInClass(answer, pointCount); - +Worker::Worker(GQueue &in, GQueue &out, std::string DBName):In(in), Out(out), DB(DBName), Stop(false), + WProces(std::bind(&Worker::WorkerProcess, this)) { } +Worker::~Worker(){ + Stop = true; + printf("End WorkerProc \n"); + WProces.join(); +} -std::string Worker::createJsonForSending(const std::vector &points) { +DataIn Worker::GetFromQueueIn(){ + DataIn a = In.popIfNotEmpty(); + return a; +} - boost::property_tree::ptree rootJsonTree; - boost::property_tree::ptree coordinates; - boost::property_tree::ptree coordinate; +void Worker::SendToQueueOut(const DataOut &value){ + Out.push(value); +} +void Worker::GetDotsFromDB(const DataIn &value, std::vector &points){ + DB.SelectTag(value.FilterList, points); +} - for (size_t i = 0 ; i < points.size() ; i++) { - coordinate.put("X", points.at(i).X); - coordinate.put("Y", points.at(i).Y); - // id координаты = её место в принимающем векторе - std::string id = std::to_string(i); - coordinates.add_child( id, coordinate); +void Worker::GetRibsFromAPI(const std::vector &points){ + for ( int i = 0; i < points.size(); ++i ) { + for(int j = 0; j < points.size() - 1; ++j ) { + weightArr.push_back(2); + edges.push_back(std::make_pair(i, j)); + } } - - rootJsonTree.add_child("coordinates", coordinates); - std::stringstream jsonStream; - boost::property_tree::write_json(jsonStream, rootJsonTree); - - return jsonStream.str(); } +void Worker::GetRoutefromAlgorithm(const std::vector edge, const std::vector weight, + std::pair, size_t> &res, size_t num_dots, DataIn value){ + Algorithm way(edge, weight); // из апи 2 массива + res = way.getRoute(0, num_dots, value.TimeLimit, value.MaxDots); +} -void Worker::getWeightFromPythonAPI(const std::string &jsonPoints, std::string &answer) { - - const std::string host = "127.0.0.1"; - const std::string target = "/api"; - - boost::asio::io_context ioc; - - boost::asio::ip::tcp::resolver resolver(ioc); - - boost::asio::ip::tcp::socket socket(ioc); - - // установка соединения - boost::asio::connect(socket, resolver.resolve(host, "5000")); - - // создаем запрос - http::request req(http::verb::post, target, 11); - - // устанавливаем поля http заголовка - req.set(http::field::host, host); - req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING); - req.set(http::field::content_type, "application/json"); - req.set(http::field::accept_charset, "utf-8"); - req.content_length(jsonPoints.size()); - req.keep_alive(req.keep_alive()); - req.body() = jsonPoints; - req.prepare_payload(); - - // отправляем запрос - http::write(socket, req); - - // читаем запрос - std::stringstream answerStream; - { - boost::beast::flat_buffer buffer; - http::response response; - http::read(socket, buffer, response); - answerStream << response; +void Worker::FinalPoints(std::vector &points, const std::pair, size_t> &res){ + std::vector buf; + for( int i = 0; i < res.first.size(); ++i ) { + buf.push_back(points[res.first[i]]); } + points.clear(); + points = buf; +} - // закрываем соединение - socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both); - - // стираем заголовки из ответа - answer = answerStream.str(); - size_t startJson = answer.find('{'); - answer.erase(0, startJson); +void Worker::WorkerProcess(){ + int counter = 1; + while ( !Stop ) { + DataIn value = GetFromQueueIn(); + if ( value.UserID == -1) { + sleep(200); + } else { + std::vector PointsResFromDB; + GetDotsFromDB(value, PointsResFromDB); + std::vector> RibsResFromApi; + GetRibsFromAPI(PointsResFromDB); + std::pair, size_t> Res; + GetRoutefromAlgorithm(edges, weightArr, Res, PointsResFromDB.size(), value); // !!!!!!!!!!! + FinalPoints(PointsResFromDB, Res); + DataOut OutValue; + OutValue.UserID = value.UserID; + OutValue.MaxTime = Res.second; + OutValue.RoutePoints = PointsResFromDB; + SendToQueueOut(OutValue); + } + } } -void Worker::setJsonAnswerInClass(const std::string &json, const size_t &pointCount){ +void Worker::GetRest(int timeToSleep) { - boost::property_tree::ptree answerTree; - std::istringstream is(json); - boost::property_tree::json_parser::read_json(is, answerTree); +} - answerTree = answerTree.get_child("weights"); +void Worker::Kill() { + Stop = true; +} - std::string key; - for (size_t i = 0 ; i < pointCount ; i++) - for (size_t j = 0 ; j < pointCount ; j++) { - if (i == j) - continue; - key = std::to_string(i) + "->" + std::to_string(j); - size_t distance = answerTree.get_child(key).get_value() ; - edges.push_back(std::make_pair(i, j)); - weightArr.push_back(distance); +//================================================================================================================= + +Table::Table(std::string filename) { + file.open(filename); + if (!file.is_open()) // если файл не открыт + printf("Файл не может быть открыт!\n"); + else { + std::string delim("#"); + std::string delitel(" "); + std::string TagsBuf; + Line buf; + std::string buffer; + while(getline(file,buffer)) { + size_t prev = 0; + size_t next; + size_t delta = delim.length(); + size_t delta2 = delitel.length(); + size_t prev2 = 0; + size_t next2 = buffer.find(delitel, prev2); + buf.id = atoi(buffer.substr(prev2, next2-prev2).c_str()); // atoi( str.c_str() ); + prev2 = next2 + delta2; + next2 = buffer.find(delitel, prev2); + buf.x = atoi(buffer.substr(prev2, next2-prev2).c_str()); + prev2 = next2 + delta2; + next2 = buffer.find(delitel, prev2); + buf.y = atoi(buffer.substr(prev2, next2-prev2).c_str()); + prev2 = next2 + delta2; + next2 = buffer.find(delitel, prev2); + buf.Name = (buffer.substr(prev2, next2-prev2)); + prev2 = next2 + delta2; + next2 = buffer.find(delitel, prev2); + TagsBuf = (buffer.substr(prev2, next2-prev2)); + while( ( next = TagsBuf.find( delim, prev ) ) != std::string::npos ){ + buf.Tags.push_back(TagsBuf.substr(prev, next-prev)); + prev = next + delta; + } + buf.Tags.push_back(TagsBuf.substr(prev)); + table.push_back(buf); + buf.Tags.clear(); } + } } -long int Worker::getWeightIndex(const size_t &pointsCount, const size_t &from, const size_t &to){ - - if (from > pointsCount - 1 || to > pointsCount - 1 || - from == to) - return -1; // return error - - if (from == 0) - return to - 1; +void Table::SelectTag(std::vector values, std::vector& res) { + bool flag = false; + for ( auto lineElem : table ) { + for (int i = 0; i < values.size() && !flag; ++i) { + for (int j = 0; j < lineElem.Tags.size() && !flag; ++j) { + if ( values[i] == lineElem.Tags[j] ) { + res.push_back(std::make_pair(lineElem.x, lineElem.y)); + flag = true; + } + } + } + flag = false; + } +} +void Table::SelectAll(std::vector& res){ + for ( auto i : table) { + res.emplace_back(i.x, i.y); + } +} - if (from < to) - return ( (pointsCount -1) * from + to) - 1; +Table::~Table() { + file.close(); +} - return ( (pointsCount -1) * from + to); -} diff --git a/test/test.cpp b/test/test.cpp index ed7aaab..9d36cb8 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -1,231 +1,135 @@ /* - * Copyright 2019 + * Copyright 2019 */ #include -#include "worker.hpp" - - -TEST(global, distance) { - - Worker worker; - std::vector points; - points.push_back( Point{3.2,4.5} ); - points.push_back( Point{102.0,-4.7} ); - points.push_back( Point{-7,1.4} ); - points.push_back( Point{72,103.0} ); - points.push_back( Point{-7.3,19.1} ); - points.push_back( Point{-45.4,-182} ); - - worker.GetRibsFromAPI(points); - - size_t index; - - // check point "0" -> "1" weight = 99 - index = worker.getWeightIndex(points.size(), 0,1); - ASSERT_TRUE(worker.edges.at(index).first == 0); - ASSERT_TRUE(worker.edges.at(index).second == 1); - ASSERT_TRUE(worker.weightArr.at(index) == 99); - - // check point "0" -> "2" weight = 20 - index = worker.getWeightIndex(points.size(), 0,2); - ASSERT_TRUE(worker.edges.at(index).first == 0); - ASSERT_TRUE(worker.edges.at(index).second == 2); - ASSERT_TRUE(worker.weightArr.at(index) == 10); - // check point "0" -> "3" weight = 120 - index = worker.getWeightIndex(points.size(), 0,3); - ASSERT_TRUE(worker.edges.at(index).first == 0); - ASSERT_TRUE(worker.edges.at(index).second == 3); - ASSERT_TRUE(worker.weightArr.at(index) == 120); - - // check point "5" -> "0" weight = 192 - index = worker.getWeightIndex(points.size(), 5,0); - ASSERT_TRUE(worker.edges.at(index).first == 5); - ASSERT_TRUE(worker.edges.at(index).second == 0); - ASSERT_TRUE(worker.weightArr.at(index) == 192); - - // check point "5" -> "4" weight = 204 - index = worker.getWeightIndex(points.size(), 5,4); - ASSERT_TRUE(worker.edges.at(index).first == 5); - ASSERT_TRUE(worker.edges.at(index).second == 4); - ASSERT_TRUE(worker.weightArr.at(index) == 204); - - // check point "4" -> "2" weight = 17 - index = worker.getWeightIndex(points.size(), 4,2); - ASSERT_TRUE(worker.edges.at(index).first == 4); - ASSERT_TRUE(worker.edges.at(index).second == 2); - ASSERT_TRUE(worker.weightArr.at(index) == 17); - - // check point "4" -> "2" weight = 17 - index = worker.getWeightIndex(points.size(), 4,2); - ASSERT_TRUE(worker.edges.at(index).first == 4); - ASSERT_TRUE(worker.edges.at(index).second == 2); - ASSERT_TRUE(worker.weightArr.at(index) == 17); - - // check point "2" -> "3" weight = 128 - index = worker.getWeightIndex(points.size(), 2,3); - ASSERT_TRUE(worker.edges.at(index).first == 2); - ASSERT_TRUE(worker.edges.at(index).second == 3); - ASSERT_TRUE(worker.weightArr.at(index) == 128); - - // check point "5" -> "3" weight = 308 - index = worker.getWeightIndex(points.size(), 5,3); - ASSERT_TRUE(worker.edges.at(index).first == 5); - ASSERT_TRUE(worker.edges.at(index).second == 3); - ASSERT_TRUE(worker.weightArr.at(index) == 308); +#include +#include +#include "worker.hpp" +#include +#include +#include "gmock/gmock.h" + +using ::testing::_; +using ::testing::Return; +using ::testing::A; +using ::testing::ByRef; +using ::testing::Ref; +using ::testing::TypedEq; + + +TEST(Get, Get_from_queu) { + Table a("../Attraction"); + std::vector check = {"Красная_площадь","0"}; + std::vector res; + a.SelectTag(check, res); + std::vector resCheck = {{1,1},{5,13},{5,10},{4,8},{5,11}}; + ASSERT_EQ(res, resCheck); } - - -TEST(getIndex, getIndex) { - - size_t index; - - index = Worker::getWeightIndex(10, 3,3); - ASSERT_TRUE(index == -1); - - index = Worker::getWeightIndex(6, 40,50); - ASSERT_TRUE(index == -1); - - index = Worker::getWeightIndex(6, 4,5); - ASSERT_TRUE(index == 24); - - index = Worker::getWeightIndex(6, 1,4); - ASSERT_TRUE(index == 8); - - index = Worker::getWeightIndex(6, 5,3); - ASSERT_TRUE(index == 28); - - index = Worker::getWeightIndex(6, 3,0); - ASSERT_TRUE(index == 15); - - index = Worker::getWeightIndex(6, 0,5); - ASSERT_TRUE(index == 4); - - index = Worker::getWeightIndex(6, 1,2); - ASSERT_TRUE(index == 6); - - index = Worker::getWeightIndex(6, 4,1); - ASSERT_TRUE(index == 21); - - index = Worker::getWeightIndex(6, 2,5); - ASSERT_TRUE(index == 14); - +// +TEST(Send, Send_to_queu) { + Table a("../Attraction"); + std::vector res; + a.SelectAll(res); + std::vector resCheck = {{1, 1},{24, 78},{5, 13},{5, 10},{4, 8},{5, 11}, + {56, 65},{58, 65},{54, 63},{60, 65},{0, 0}}; + ASSERT_EQ(res, resCheck); } - -TEST(setJsonAnswerInClass, setJsonAnswerInClass) { - - Worker worker; - std::string json; - size_t pointsCount; - size_t index; - - json = "{\"weights\":{\"0->1\":99,\"0->2\":10,\"0->3\":120,\"0->4\":17,\"0->5\":192,\"1->0\":99,\"1->2\":109,\"1->3\":111,\"1->4\":111,\"1->5\":230,\"2->0\":10,\"2->1\":109,\"2->3\":128,\"2->4\":17,\"2->5\":187,\"3->0\":120,\"3->1\":111,\"3->2\":128,\"3->4\":115,\"3->5\":308,\"4->0\":17,\"4->1\":111,\"4->2\":17,\"4->3\":115,\"4->5\":204,\"5->0\":192,\"5->1\":230,\"5->2\":187,\"5->3\":308,\"5->4\":204}}"; - pointsCount = 6; - worker.setJsonAnswerInClass(json, pointsCount); - - index = Worker::getWeightIndex(6,0,5); - ASSERT_TRUE(worker.weightArr.at(index) == 192); - ASSERT_TRUE(worker.edges.at(index).first == 0); - ASSERT_TRUE(worker.edges.at(index).second == 5); - - index = Worker::getWeightIndex(6,3,1); - ASSERT_TRUE(worker.weightArr.at(index) == 111); - index = Worker::getWeightIndex(6,5,1); - ASSERT_TRUE(worker.weightArr.at(index) == 230); - index = Worker::getWeightIndex(6,4,3); - ASSERT_TRUE(worker.weightArr.at(index) == 115); - - - worker.edges.clear(); - worker.weightArr.clear(); - json = "{\"weights\":{\"0->1\":25,\"0->2\":13,\"0->3\":10,\"1->0\":55,\"1->2\":129,\"1->3\":151,\"2->0\":10,\"2->1\":119,\"2->3\":158,\"3->0\":127,\"3->1\":171,\"3->2\":258}}"; - pointsCount = 4; - worker.setJsonAnswerInClass(json, pointsCount); - - index = Worker::getWeightIndex(4,3,2); - ASSERT_TRUE(worker.weightArr.at(index) == 258); - ASSERT_TRUE(worker.edges.at(index).first == 3); - ASSERT_TRUE(worker.edges.at(index).second == 2); - - index = Worker::getWeightIndex(4,0,1); - ASSERT_TRUE(worker.weightArr.at(index) == 25); - - index = Worker::getWeightIndex(4,2,0); - ASSERT_TRUE(worker.weightArr.at(index) == 10); - - index = Worker::getWeightIndex(4,2,3); - ASSERT_TRUE(worker.weightArr.at(index) == 158); - +TEST(Get_dots, Get_dots_from_DB) { + DataIn NotCorrect; + NotCorrect.UserID = -1; + DataOut NotCorrect2; + NotCorrect2.UserID = -1; + GQueue In(NotCorrect); + GQueue Out(NotCorrect2); + DataIn forcheck; + forcheck.FilterList = {{"dfgvd"}}; + Worker w1(In, Out, "../Attraction"); + w1.Kill(); + std::vector a; + std::vector check = {}; + w1.GetDotsFromDB(forcheck,a); + ASSERT_EQ(a, check); } - -TEST(PythonAPI, PythonAPI) { - - Worker worker; - std::string jsonForSending = "{\"coordinates\": {\"0\": {\"X\": \"3.2\",\"Y\": \"4.5\"},\"1\": {\"X\": \"102\",\"Y\": \"-4.7\"},\"2\": {\"X\": \"-7\",\"Y\": \"1.39\"}}}"; - std::string answer; - - worker.getWeightFromPythonAPI(jsonForSending, answer); - - std::string goodAnswer = "{\"weights\":{\"0->1\":99,\"0->2\":10,\"1->0\":99,\"1->2\":109,\"2->0\":10,\"2->1\":109}}\n"; - - int result = strcmp(answer.c_str(), goodAnswer.c_str()); - ASSERT_TRUE(result == 0); - - jsonForSending = "{\"coordinates\": {\"0\": {\"X\": \"0\",\"Y\": \"10.0\"},\"1\": {\"X\": \"2\",\"Y\": \"0\"},\"2\": {\"X\": \"-1\",\"Y\": \"-1\"}}}"; - - worker.getWeightFromPythonAPI(jsonForSending, answer); - - goodAnswer = "{\"weights\":{\"0->1\":10,\"0->2\":11,\"1->0\":10,\"1->2\":3,\"2->0\":11,\"2->1\":3}}\n"; - - result = strcmp(answer.c_str(), goodAnswer.c_str()); - ASSERT_TRUE(result == 0); - +TEST(Get_dots2, Get_dots_from_DB2) { + DataIn NotCorrect; + NotCorrect.UserID = -1; + DataOut NotCorrect2; + NotCorrect2.UserID = -1; + GQueue In(NotCorrect); + GQueue Out(NotCorrect2); + DataIn forcheck; + forcheck.FilterList = {{"Красная_площадь"}}; + Worker w1(In, Out, "../Attraction"); + w1.Kill(); + std::vector a; + std::vector check = {{5,13},{5,10},{4,8},{5, 11}}; + w1.GetDotsFromDB(forcheck,a); + ASSERT_EQ(a, check); +} +//// +TEST(Get_dots3, Get_dots_from_DB3) { + DataIn NotCorrect; + NotCorrect.UserID = -1; + DataOut NotCorrect2; + NotCorrect2.UserID = -1; + GQueue In(NotCorrect); + GQueue Out(NotCorrect2); + DataIn forcheck; + forcheck.FilterList = {{"Красная_площадь"},{"История"}}; + Worker w1(In, Out, "../Attraction"); + w1.Kill(); + std::vector a; +// for ( auto i : a ) { +// std::cout< check = { {5, 13}, {5, 10}, {4, 8}, {5, 11}, {58, 65}, + {54, 63}, {60, 65} }; + w1.GetDotsFromDB(forcheck,a); + ASSERT_EQ(a, check); +} +// +TEST(Get_dots4, NumberOfDots) { + DataIn NotCorrect; + NotCorrect.UserID = -1; + DataOut NotCorrect2; + NotCorrect2.UserID = -1; + GQueue In(NotCorrect); + GQueue Out(NotCorrect2); + DataIn forcheck; + forcheck.FilterList = {{"История"}}; + Worker w1(In, Out, "../Attraction"); + w1.Kill(); + In.push(forcheck); + DataIn a; + a.FilterList = w1.GetFromQueueIn().FilterList; + ASSERT_EQ(a.FilterList, forcheck.FilterList); } - -TEST(createJsonForSend, createJsonForSend) { - - Worker worker; - std::vector points; - points.push_back( Point{3.2,4.5} ); - points.push_back( Point{102.0,-4.7} ); - points.push_back( Point{-7,1.4} ); - points.push_back( Point{72,103.0} ); - - std::string answer = worker.createJsonForSending(points); - - std::string goodAnswer = "{\n" - " \"coordinates\": {\n" - " \"0\": {\n" - " \"X\": \"3.2000000000000002\",\n" - " \"Y\": \"4.5\"\n" - " },\n" - " \"1\": {\n" - " \"X\": \"102\",\n" - " \"Y\": \"-4.7000000000000002\"\n" - " },\n" - " \"2\": {\n" - " \"X\": \"-7\",\n" - " \"Y\": \"1.3999999999999999\"\n" - " },\n" - " \"3\": {\n" - " \"X\": \"72\",\n" - " \"Y\": \"103\"\n" - " }\n" - " }\n" - "}\n"; - - int result = strcmp(answer.c_str(), goodAnswer.c_str()); - ASSERT_TRUE(result == 0); - +TEST(Get_dots5, NumberOfDots) { + DataIn NotCorrect; + NotCorrect.UserID = -1; + DataOut NotCorrect2; + NotCorrect2.UserID = -1; + GQueue In(NotCorrect); + GQueue Out(NotCorrect2); + Worker w1(In, Out, "../Attraction"); + w1.Kill(); + std::vector points = {{1,2},{3,4},{5,6},{7,8},{9,10},{11,11}}; + std::pair, size_t> res = {{1,3,5},5}; + std::vector Result = {{3, 4}, {7, 8}, {11, 11}}; + w1.FinalPoints(points,res); + ASSERT_EQ(points, Result); } int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv); + testing::InitGoogleMock(&argc, argv); return RUN_ALL_TESTS(); } +