diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e67c64f..df92952 100755 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Install gtest manually - run: sudo apt-get install libgtest-dev && cd /usr/src/gtest && sudo cmake CMakeLists.txt && sudo make && ls -l lib && sudo cp lib/*.a /usr/lib && sudo ln -s /usr/lib/libgtest.a /usr/local/lib/libgtest.a && sudo ln -s /usr/lib/libgtest_main.a /usr/local/lib/libgtest_main.a + run: sudo apt-get install libgtest-dev libgmock-dev && cd /usr/src/gtest && sudo cmake CMakeLists.txt && sudo make && ls -l lib && sudo cp lib/*.a /usr/lib && sudo ln -s /usr/lib/libgtest.a /usr/local/lib/libgtest.a && sudo ln -s /usr/lib/libgtest_main.a /usr/local/lib/libgtest_main.a - uses: actions/checkout@v1 - name: configure run: mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-Werror" .. diff --git a/CMakeLists.txt b/CMakeLists.txt index 36758e8..65f04a3 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,5 +9,13 @@ set(tool_dest "bin") set(lib_dest "lib") set(include_dest "include/") +include(FetchContent) +FetchContent_Declare( + googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG release-1.10.0 +) +FetchContent_MakeAvailable(googletest) + add_subdirectory(src) add_subdirectory(test) diff --git a/README.md b/README.md index f19f864..19caea0 100644 --- a/README.md +++ b/README.md @@ -44,13 +44,13 @@ class TimedDoor : public Door { private: DoorTimerAdapter * adapter; int iTimeout; - bool opened; + bool isOpened; public: explicit TimedDoor(int); bool isDoorOpened(); void unlock(); void lock(); - void DoorTimeOut(); + int getTimeOut(); void throwState(); }; diff --git a/include/TimedDoor.h b/include/TimedDoor.h index e1eade2..b79a698 100644 --- a/include/TimedDoor.h +++ b/include/TimedDoor.h @@ -1,7 +1,6 @@ -// Copyright 2021 GHA Test Team +// Copyright 2024 Derun Andrey -#ifndef INCLUDE_TIMEDDOOR_H_ -#define INCLUDE_TIMEDDOOR_H_ +#pragma once class DoorTimerAdapter; class Timer; @@ -22,31 +21,32 @@ class Door { class DoorTimerAdapter : public TimerClient { private: - TimedDoor& door; + TimedDoor &door; + public: - explicit DoorTimerAdapter(TimedDoor&); + explicit DoorTimerAdapter(TimedDoor &); void Timeout(); }; class TimedDoor : public Door { private: - DoorTimerAdapter * adapter; + DoorTimerAdapter *adapter; int iTimeout; - bool opened; + bool isOpened; + public: explicit TimedDoor(int); bool isDoorOpened(); void unlock(); void lock(); - void DoorTimeOut(); + int getTimeOut() const; void throwState(); }; class Timer { TimerClient *client; void sleep(int); + public: - void tregister(int, TimerClient*); + void tregister(int, TimerClient *); }; - -#endif // INCLUDE_TIMEDDOOR_H_ diff --git a/src/TimedDoor.cpp b/src/TimedDoor.cpp new file mode 100644 index 0000000..bd96387 --- /dev/null +++ b/src/TimedDoor.cpp @@ -0,0 +1,53 @@ +// Copyright 2024 Derun Andrey + +#include "TimedDoor.h" + +#include // NOLINT [build/c++11] +#include +#include // NOLINT [build/c++11] + +// DoorTimerAdapter Implementation +DoorTimerAdapter::DoorTimerAdapter(TimedDoor& door_) : door(door_) {} + +void DoorTimerAdapter::Timeout() { + if (door.isDoorOpened()) { + throw std::runtime_error("Time's up!"); + } +} + +// TimedDoor Implementation +TimedDoor::TimedDoor(int timeout_) + : iTimeout(timeout_), + isOpened(false), + adapter(new DoorTimerAdapter(*this)) {} + +bool TimedDoor::isDoorOpened() { return isOpened; } + +void TimedDoor::unlock() { + if (isOpened) { + throw std::logic_error("Door is already opened"); + } + isOpened = true; +} + +void TimedDoor::lock() { + if (!isOpened) { + throw std::logic_error("Door is already closed"); + } + isOpened = false; +} + +int TimedDoor::getTimeOut() const { return iTimeout; } + +void TimedDoor::throwState() { adapter->Timeout(); } + +// Timer Implementation +void Timer::sleep(int time_) { + std::this_thread::sleep_for(std::chrono::seconds(time_)); +} + +void Timer::tregister(int time_, TimerClient* client_) { + this->client = client_; + sleep(time_); + client_->Timeout(); +} diff --git a/src/main.cpp b/src/main.cpp index 9b83162..61cde30 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,9 +1,11 @@ -// Copyright 2021 GHA Test Team -#include "TimedDoor.h" +// Copyright 2024 Derun Andrey #include +#include "TimedDoor.h" + int main() { - TimedDoor tDoor(5); + int time = 5; + TimedDoor tDoor(time); tDoor.lock(); tDoor.unlock(); diff --git a/test/tests.cpp b/test/tests.cpp index 605e570..7343b7d 100644 --- a/test/tests.cpp +++ b/test/tests.cpp @@ -1,6 +1,78 @@ -// Copyright 2021 GHA Test Team +// Copyright 2024 Derun Andrey -#include #include +#include + +#include // NOLINT [build/c++11] #include +#include // NOLINT [build/c++11] + #include "TimedDoor.h" + +// Mock Timer Client +class MockTimerClient : public TimerClient { + public: + MOCK_METHOD(void, Timeout, (), (override)); +}; + +// Test Fixture for TimedDoor +class TimedDoorTest : public ::testing::Test { + protected: + TimedDoor door; + MockTimerClient mockClient; + Timer timer; + + TimedDoorTest() : door(1), timer() {} + + void SetUp() override { timer.tregister(door.getTimeOut(), &mockClient); } + + void TearDown() override { + testing::Mock::VerifyAndClearExpectations(&mockClient); + } +}; + +TEST_F(TimedDoorTest, UNL_D_TH_TIMEOUT) { + door.unlock(); + std::this_thread::sleep_for(std::chrono::seconds(door.getTimeOut())); + EXPECT_THROW(door.throwState(), std::runtime_error); +} + +TEST_F(TimedDoorTest, LOCK_D_TH_UNLOCK) { + std::this_thread::sleep_for(std::chrono::seconds(door.getTimeOut() + 1)); + EXPECT_NO_THROW(door.throwState()); +} + +TEST_F(TimedDoorTest, LOCK_BF_TIMEOUT_TH_OPEN) { + std::this_thread::sleep_for(std::chrono::seconds(door.getTimeOut() + 1)); + door.unlock(); + EXPECT_THROW(door.throwState(), std::runtime_error); +} + +TEST_F(TimedDoorTest, UNL_MTH) { + door.unlock(); + EXPECT_TRUE(door.isDoorOpened()); +} + +TEST_F(TimedDoorTest, LOCK_MTH) { + door.unlock(); + door.lock(); + EXPECT_FALSE(door.isDoorOpened()); +} + +TEST_F(TimedDoorTest, FST_D_CLO) { EXPECT_FALSE(door.isDoorOpened()); } + +TEST_F(TimedDoorTest, UNL_D_TW) { + door.unlock(); + EXPECT_THROW(door.unlock(), std::logic_error); +} + +TEST_F(TimedDoorTest, OPEN_EX) { + door.unlock(); + EXPECT_THROW(door.throwState(), std::runtime_error); +} + +TEST_F(TimedDoorTest, CLO_BF) { EXPECT_NO_THROW(door.throwState()); } + +TEST_F(TimedDoorTest, LOCK_D_TW) { + EXPECT_THROW(door.lock(), std::logic_error); +}