diff --git a/server/internal/metrics/include/TextMetricsLib.h b/server/internal/metrics/include/TextMetricsLib.h index 574a9642a9cca456aac4a3313651d1a9d4c621bf..4db863f2a574c304d8717383634e2d9629ce59c9 100644 --- a/server/internal/metrics/include/TextMetricsLib.h +++ b/server/internal/metrics/include/TextMetricsLib.h @@ -5,39 +5,41 @@ #ifndef SOURCEDOUT_DECLARATION_H #define SOURCEDOUT_DECLARATION_H +#include #include -#include -#include -#include #include +#include +#include +#include -#include - -class ITextMetric{ - virtual void setData(std::string text1, std::string text2) = 0; - virtual double getMetric() = 0; +class ITextMetric { + public: + virtual ~ITextMetric() = default; + virtual void setData(std::string text1, std::string text2) = 0; + virtual double getMetric() = 0; }; -class PrepareDataTextMetric : public ITextMetric{ -public: - void setData(std::string text1, std::string text2) override; -protected: - std::vector tokens1; - std::vector tokens2; -private: - static std::string deleteComments(const std::string& text); - static std::vector tbmTokenizer(const std::string &text); -}; +class PrepareDataTextMetric : public ITextMetric { + public: + void setData(std::string text1, std::string text2) override; + + protected: + std::vector tokens1; + std::vector tokens2; -class LevDistTextMetric : public PrepareDataTextMetric{ -public: - double getMetric() override; + private: + static std::string deleteComments(const std::string& text); + static std::vector tbmTokenizer(const std::string& text); }; -class JaccardTextMetric : public PrepareDataTextMetric{ -public: - double getMetric() override; +class LevDistTextMetric : public PrepareDataTextMetric { + public: + double getMetric() override; }; +class JaccardTextMetric : public PrepareDataTextMetric { + public: + double getMetric() override; +}; -#endif //SOURCEDOUT_DECLARATION_H +#endif // SOURCEDOUT_DECLARATION_H diff --git a/server/internal/metrics/include/TokenMetricLib.h b/server/internal/metrics/include/TokenMetricLib.h index 82c238d88d6d31b343b68cb950e7bf573b9bd6d4..59ee7a06929e01b50078aecb804ef06fa10bb971 100644 --- a/server/internal/metrics/include/TokenMetricLib.h +++ b/server/internal/metrics/include/TokenMetricLib.h @@ -15,6 +15,7 @@ class ITokenMetric{ + virtual ~ITokenMetric() = default; virtual void countMetric() = 0; virtual void setData(std::vector tokens1, std::vector tokens2) = 0; virtual double getMetric() = 0; diff --git a/server/internal/service/include/SolutionService.h b/server/internal/service/include/SolutionService.h index b60f8d9e0bc8a9008fe7030c741e43e67901c716..0e4fe565a6779be25abd03d58a0b462d54cb4133 100644 --- a/server/internal/service/include/SolutionService.h +++ b/server/internal/service/include/SolutionService.h @@ -15,17 +15,19 @@ class SolutionService : ISolutionService { std::unique_ptr solutionRepo; std::unique_ptr taskRepo; std::unique_ptr antlr; - std::unique_ptr textMetric; + std::unique_ptr textMetric; std::unique_ptr tokenMetric; void setAntlrWrapper(const std::string& fileExtension, const std::string& filedata); std::string setResultVerdict(float textBasedRes, float tokenBasedRes, float treshold); std::pair getMaxTextResMetric(std::vector& solutions, - const std::string& filedata); + const std::string& filedata, + float treshold); public: - explicit SolutionService(std::unique_ptr solutionRepo); + explicit SolutionService(std::unique_ptr solutionRepo, + std::unique_ptr taskRepo); SolutionService(); void setMetrics(std::unique_ptr metrics_); Solution createSolution(size_t userId, size_t taskId, diff --git a/server/internal/service/src/SolutionService.cpp b/server/internal/service/src/SolutionService.cpp index 79c7f2c1d5d44c0f15957582f56f1dcec255412f..290f244fa5b1d32c8a629a81fd5f490c2df8744d 100644 --- a/server/internal/service/src/SolutionService.cpp +++ b/server/internal/service/src/SolutionService.cpp @@ -13,8 +13,9 @@ const std::string NOT_PLAGIAT_VERDICT = "Красивое решение. А главное уникальное !"; SolutionService::SolutionService( - std::unique_ptr solutionRepo) - : solutionRepo(std::move(solutionRepo)) {} + std::unique_ptr solutionRepo, + std::unique_ptr taskRepo) + : solutionRepo(std::move(solutionRepo)), taskRepo(std::move(taskRepo)) {} SolutionService::SolutionService() { // solutionRepo=std::make_unique(); @@ -42,16 +43,18 @@ std::string SolutionService::setResultVerdict(float textBasedRes, } std::pair SolutionService::getMaxTextResMetric( - std::vector& solutions, const std::string& filedata) { - std::pair maxMatch = (0, 0); + std::vector& solutions, const std::string& filedata, + float treshold) { + std::pair maxMatch = std::make_pair(0.0, 0ul); for (auto sol : solutions) { textMetric = std::make_unique(); textMetric->setData(filedata, sol.getSource()); - float textBasedRes = textMetric->getMetric(); + float textBasedRes = float(textMetric->getMetric()); + std::cout << textBasedRes << std::endl; textMetric = std::make_unique(); textMetric->setData(filedata, sol.getSource()); - textBasedRes = (textBasedRes + textMetric->getMetric()) / 2; + textBasedRes = (textBasedRes + float(textMetric->getMetric())) / 2; if (textBasedRes > treshold) { break; @@ -85,11 +88,13 @@ Solution SolutionService::createSolution(size_t userId, size_t taskId, std::vector solutions = solutionRepo->getSolutionsByTaskId(taskId); - // float textBasedRes = getMaxTextResMetric(solutions, filedata); + std::pair textBasedRes = + getMaxTextResMetric(solutions, filedata, treshold); + // TODO: вызов метрик // получил результат - std::string result = setResultVerdict(0, 0, treshold); + std::string result = setResultVerdict(textBasedRes.first, 0.5, treshold); Solution sol = Solution(std::ctime(&now), userId, filedata, codeParse.first, codeParse.second, taskId, ""); diff --git a/server/internal/service/tests/SolutionServiceTest.cpp b/server/internal/service/tests/SolutionServiceTest.cpp index d0eacf477c22bd8e9d488f47aa764069ca23fa8b..473842aceff80a82ef09e73b0e0fbafd34a90ed0 100644 --- a/server/internal/service/tests/SolutionServiceTest.cpp +++ b/server/internal/service/tests/SolutionServiceTest.cpp @@ -27,14 +27,28 @@ class SolutionRepositoryMock : public ISolutionRepository { MOCK_METHOD(void, deleteSolution, (Solution solution), (override)); }; +class TaskRepositoryMock : public ITaskRepository { + public: + ~TaskRepositoryMock() override = default; + MOCK_METHOD(Task, getTaskById, (size_t id), (override)); + MOCK_METHOD(void, updateTask, (Task task), (override)); + MOCK_METHOD(int, storeTask, (Task task), (override)); + MOCK_METHOD(void, deleteTask, (Task task), (override)); + MOCK_METHOD(void, deleteTaskById, (size_t id), (override)); + MOCK_METHOD(std::vector, getAllTasks, (), (override)); +}; + struct SolutionServiceTest : public testing::Test { SolutionService* ss; - SolutionRepositoryMock* mock_ptr; + SolutionRepositoryMock* solutionMockPtr; + TaskRepositoryMock* taskMockPtr; void SetUp() { - auto mock = std::make_unique(); - mock_ptr = mock.get(); - ss = new SolutionService(std::move(mock)); + auto sMock = std::make_unique(); + solutionMockPtr = sMock.get(); + auto tMock = std::make_unique(); + taskMockPtr = tMock.get(); + ss = new SolutionService(std::move(sMock), std::move(tMock)); } void TearDown() { delete ss; } }; @@ -47,7 +61,7 @@ TEST_F(SolutionServiceTest, getSolutionsByUserAndTaskId) { std::vector solutions; solutions.push_back(Solution(0, "", 1, "", "", "", 1, "")); solutions.push_back(Solution(1, "", 1, "", "", "", 1, "")); - EXPECT_CALL(*mock_ptr, getSolutions(1, 1)) + EXPECT_CALL(*solutionMockPtr, getSolutions(1, 1)) .Times(1) .WillOnce(::testing::Return(solutions)); std::vector sols = ss->getSolutionsByUserAndTaskId(1, 1); @@ -55,19 +69,19 @@ TEST_F(SolutionServiceTest, getSolutionsByUserAndTaskId) { } TEST_F(SolutionServiceTest, deleteSolution) { - EXPECT_CALL(*mock_ptr, deleteSolutionById(1)).Times(1); + EXPECT_CALL(*solutionMockPtr, deleteSolutionById(1)).Times(1); ss->deleteSolutionById(1); } TEST_F(SolutionServiceTest, deleteSolutionException) { - EXPECT_CALL(*mock_ptr, deleteSolutionById(-1)) + EXPECT_CALL(*solutionMockPtr, deleteSolutionById(-1)) .Times(1) .WillRepeatedly(NoSolutionException()); EXPECT_THROW(ss->deleteSolutionById(-1), std::exception); } TEST_F(SolutionServiceTest, getMetrics) { - EXPECT_CALL(*mock_ptr, getSolutionById(1)) + EXPECT_CALL(*solutionMockPtr, getSolutionById(1)) .Times(1) .WillOnce(::testing::Return( Solution(1, "", 1, "", "tokens", "astTree", 1, ""))); @@ -77,20 +91,32 @@ TEST_F(SolutionServiceTest, getMetrics) { } TEST_F(SolutionServiceTest, getMetricsException) { - EXPECT_CALL(*mock_ptr, getSolutionById(-1)) + EXPECT_CALL(*solutionMockPtr, getSolutionById(-1)) .Times(1) .WillRepeatedly(NoSolutionException()); EXPECT_THROW(ss->getMetrics(-1), std::exception); } TEST_F(SolutionServiceTest, createSolution) { - EXPECT_CALL(*mock_ptr, + EXPECT_CALL(*solutionMockPtr, storeSolution(Solution(0, "", 2, "source", "", "", 1, ""))) .Times(1) .WillRepeatedly(::testing::Return(1)); + + std::vector solutions; + solutions.push_back(Solution(0, "", 1, "int main(){return 0;}", "", "", 1, "")); + solutions.push_back(Solution(1, "", 1, "", "", "", 1, "")); + EXPECT_CALL(*solutionMockPtr, getSolutionsByTaskId(1)) + .Times(1) + .WillOnce(::testing::Return(solutions)); + + EXPECT_CALL(*taskMockPtr, getTaskById(1)) + .Times(1) + .WillOnce(::testing::Return(Task(1, "desription", 0.7f))); + Solution sol = ss->createSolution(2, 1, "main.cpp", "int main(){return 0;}"); EXPECT_EQ(sol.getId(), 1); - EXPECT_EQ(sol.getSource(), "main.cpp"); + EXPECT_EQ(sol.getSource(), "int main(){return 0;}"); EXPECT_EQ(sol.getTokens(), "[@0,0:2='int',<45>,1:0] [@1,4:7='main',<132>,1:4] " "[@2,8:8='(',<85>,1:8] [@3,9:9=')',<86>,1:9] "