From 8e9ae14d71606e0ee5d6e36c96bfd01f779ca142 Mon Sep 17 00:00:00 2001 From: anyakakzovut Date: Sat, 14 Dec 2024 14:57:05 +0300 Subject: [PATCH 1/8] Create .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..01f9cb9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build/ +.vscode/ \ No newline at end of file From 2fb76cfb291852b354df87f962b090f1e3499738 Mon Sep 17 00:00:00 2001 From: anyakakzovut Date: Sat, 14 Dec 2024 15:05:53 +0300 Subject: [PATCH 2/8] pop function: stack check and memory release --- 05_hw/stack.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/05_hw/stack.c b/05_hw/stack.c index 0964440..242dedf 100644 --- a/05_hw/stack.c +++ b/05_hw/stack.c @@ -30,8 +30,13 @@ void push(Stack* stack, int data) { } void pop(Stack* stack) { + if (stack->top == NULL) { + printf("Stack is empty, cannot pop.\n"); + return; + } Node* temp = stack->top; stack->top = stack->top->next; + free(temp); } Node* searchByValue(Stack* stack, int value) { From 151d3ef8132da0a56f087fd1ff77273dc49139c6 Mon Sep 17 00:00:00 2001 From: anyakakzovut Date: Sat, 14 Dec 2024 15:06:39 +0300 Subject: [PATCH 3/8] searchByValue function: moving to the next node --- 05_hw/stack.c | 1 + 1 file changed, 1 insertion(+) diff --git a/05_hw/stack.c b/05_hw/stack.c index 242dedf..a5f378e 100644 --- a/05_hw/stack.c +++ b/05_hw/stack.c @@ -45,6 +45,7 @@ Node* searchByValue(Stack* stack, int value) { if (current->data == value) { return current; } + current = current->next; } return NULL; } From bfc9da43d80d4fc1284e73a96e9038a855ba7d50 Mon Sep 17 00:00:00 2001 From: anyakakzovut Date: Sat, 14 Dec 2024 15:08:06 +0300 Subject: [PATCH 4/8] isEmpty function: stack check --- 05_hw/stack.c | 1 - 1 file changed, 1 deletion(-) diff --git a/05_hw/stack.c b/05_hw/stack.c index a5f378e..468204c 100644 --- a/05_hw/stack.c +++ b/05_hw/stack.c @@ -78,7 +78,6 @@ void traverseStack(Stack* stack) { } bool isEmpty(Stack* stack) { - free(stack->top); return stack->top == NULL; } From 15a02a3b8dc7518cb1479caac6ef4600d7b477ec Mon Sep 17 00:00:00 2001 From: anyakakzovut Date: Sat, 14 Dec 2024 15:08:57 +0300 Subject: [PATCH 5/8] destroyStack function: set top to NULL --- 05_hw/stack.c | 1 + 1 file changed, 1 insertion(+) diff --git a/05_hw/stack.c b/05_hw/stack.c index 468204c..3f4a1cc 100644 --- a/05_hw/stack.c +++ b/05_hw/stack.c @@ -21,6 +21,7 @@ void destroyStack(Stack* stack) { current = current->next; free(tmp); } + stack->top = NULL; } void push(Stack* stack, int data) { From be982688d4be190dd4b30d97962d7f7b8f8d7060 Mon Sep 17 00:00:00 2001 From: anyakakzovut <107941858+anyakakzovut@users.noreply.github.com> Date: Thu, 19 Dec 2024 23:27:58 +0300 Subject: [PATCH 6/8] add tests --- .gitignore | 3 +- 05_hw/CMakeLists.txt | 15 ++++-- 05_hw/tests.cpp | 115 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 129 insertions(+), 4 deletions(-) create mode 100644 05_hw/tests.cpp diff --git a/.gitignore b/.gitignore index 01f9cb9..31b81d2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ build/ -.vscode/ \ No newline at end of file +.vscode/ +googletest/ \ No newline at end of file diff --git a/05_hw/CMakeLists.txt b/05_hw/CMakeLists.txt index 6f5e398..f892963 100644 --- a/05_hw/CMakeLists.txt +++ b/05_hw/CMakeLists.txt @@ -1,7 +1,16 @@ cmake_minimum_required(VERSION 3.10) project(stack) -add_library(stack stack.c) +set(GOOGLETEST_VERSION 1.15.2) +enable_testing() -add_executable(main main.c) -target_link_libraries(main stack) +add_subdirectory(googletest) +include_directories(googletest/include) + +add_library(stack stack.cpp) + +add_executable(tests tests.cpp) +target_link_libraries(tests PRIVATE gtest stack) + +add_executable(main main.cpp) +target_link_libraries(main stack) \ No newline at end of file diff --git a/05_hw/tests.cpp b/05_hw/tests.cpp new file mode 100644 index 0000000..0d68db6 --- /dev/null +++ b/05_hw/tests.cpp @@ -0,0 +1,115 @@ +#include +#include "stack.h" + +using namespace std; + +class StackTest : public testing::Test +{ + void SetUp() override + { + stack = new Stack(); + } + + void TearDown() override { + delete stack; + } + + public: + Stack* stack; +}; + +TEST_F(StackTest, isEmptyTest) +{ + ASSERT_EQ(isEmpty(stack), true); +} + +TEST_F(StackTest, getTopTest) +{ + ASSERT_EQ(getTop(stack), nullptr); +} + +TEST_F(StackTest, PushTest) +{ + push(stack, 3); + push(stack, 5); + ASSERT_EQ(getTop(stack)->data, 5); +} + +TEST_F(StackTest, PopTest) +{ + push(stack, 3); + pop(stack); + ASSERT_EQ(getTop(stack), nullptr); +} + +TEST_F(StackTest, EmptyPopTest) +{ + pop(stack); + ASSERT_EQ(getTop(stack), nullptr); +} + +TEST_F(StackTest, destroyStackTest) +{ + push(stack, 3); + push(stack, 5); + push(stack, 15); + + destroyStack(stack); + + ASSERT_EQ(getTop(stack), nullptr); +} + +TEST_F(StackTest, searchByValueTest) +{ + push(stack, 3); + push(stack, 5); + push(stack, 15); + ASSERT_EQ(searchByValue(stack, 5)->data, 5); +} + +TEST_F(StackTest, searchByValueInvTest) +{ + ASSERT_EQ(searchByValue(stack, 5), nullptr); +} + +TEST_F(StackTest, searchByIndexTest) +{ + push(stack, 3); + push(stack, 5); + push(stack, 15); + ASSERT_EQ(searchByIndex(stack, 1)->data, 5); +} + +TEST_F(StackTest, searchByIndexInvTest) +{ + ASSERT_EQ(searchByIndex(stack, 1), nullptr); +} + +TEST_F(StackTest, traverseStackTest) { + testing::internal::CaptureStdout(); + + push(stack, 3); + push(stack, 5); + push(stack, 15); + + traverseStack(stack); + + std::string str = testing::internal::GetCapturedStdout(); + EXPECT_EQ("Stack elements: 15 5 3 \n", str); +} + +TEST_F(StackTest, traverseStackEmptyTest) { + testing::internal::CaptureStdout(); + + traverseStack(stack); + + std::string str = testing::internal::GetCapturedStdout(); + EXPECT_EQ("Stack elements: \n", str); +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} \ No newline at end of file From f2c8df395ce8f60afea7ad84c405d62de6be5bf0 Mon Sep 17 00:00:00 2001 From: anyakakzovut <107941858+anyakakzovut@users.noreply.github.com> Date: Thu, 19 Dec 2024 23:47:46 +0300 Subject: [PATCH 7/8] add benchmark --- .gitignore | 3 ++- 05_hw/CMakeLists.txt | 9 +++++-- 05_hw/benchmark.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 05_hw/benchmark.cpp diff --git a/.gitignore b/.gitignore index 31b81d2..93f2d9a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ build/ .vscode/ -googletest/ \ No newline at end of file +googletest/ +benchmark/ \ No newline at end of file diff --git a/05_hw/CMakeLists.txt b/05_hw/CMakeLists.txt index f892963..51c4093 100644 --- a/05_hw/CMakeLists.txt +++ b/05_hw/CMakeLists.txt @@ -3,14 +3,19 @@ project(stack) set(GOOGLETEST_VERSION 1.15.2) enable_testing() - add_subdirectory(googletest) include_directories(googletest/include) add_library(stack stack.cpp) - add_executable(tests tests.cpp) target_link_libraries(tests PRIVATE gtest stack) +set(BENCHMARK_ENABLE_TESTING OFF) +add_subdirectory(benchmark) +include_directories(benchmark/include) + +add_executable(benchmark benchmark.cpp) +target_link_libraries(bench PRIVATE benchmark::benchmark stack) + add_executable(main main.cpp) target_link_libraries(main stack) \ No newline at end of file diff --git a/05_hw/benchmark.cpp b/05_hw/benchmark.cpp new file mode 100644 index 0000000..542a2b1 --- /dev/null +++ b/05_hw/benchmark.cpp @@ -0,0 +1,61 @@ +#include +#include "stack.h" + +class StackBench : public benchmark::Fixture +{ + // Метод, который выполняется перед каждым бенчмарком + void SetUp(::benchmark::State& state) + { + stack = new Stack(); // Создаем новый экземпляр стека + } + + // Метод, который выполняется после каждого бенчмарка + void TearDown(::benchmark::State& state) + { + delete stack; // Удаляем стек, освобождая память + } + +public: + Stack* stack; // Указатель на стек, который будет использоваться в бенчмарках +}; + +// Определяем бенчмарк для измерения времени выполнения операции добавления элементов в стек +BENCHMARK_DEFINE_F(StackBench, PushBench)(benchmark::State& st) +{ + for (auto _ : st) // Цикл для повторного выполнения теста + { + for(int i = 0; i < st.range(0); i++) // Внутренний цикл для добавления элементов в стек + push(stack, i); // Добавляем элемент i в стек + } +} + +// Определяем бенчмарк для измерения времени выполнения операции удаления элементов из стека +BENCHMARK_DEFINE_F(StackBench, PopBench)(benchmark::State& st) +{ + for(int i = 0; i < st.range(0); i++) // Сначала заполняем стек элементами + push(stack, i); // Добавляем элемент i в стек + + for (auto _ : st) // Цикл для повторного выполнения теста + { + for(int i = 0; i < st.range(0); i++) // Внутренний цикл для удаления элементов из стека + pop(stack); // Удаляем верхний элемент из стека + } +} + +// Регистрируем бенчмарки с различными аргументами (размером стека) +BENCHMARK_REGISTER_F(StackBench, PushBench) + ->Arg(100) // Размер стека 100 + ->Arg(1000) // Размер стека 1000 + ->Arg(10000) // Размер стека 10000 + ->Arg(100000) // Размер стека 100000 + ->Arg(1000000); // Размер стека 1000000 + +// Регистрируем бенчмарк для удаления элементов с теми же аргументами +BENCHMARK_REGISTER_F(StackBench, PopBench) + ->Arg(100) + ->Arg(1000) + ->Arg(10000) + ->Arg(100000) + ->Arg(1000000); + +BENCHMARK_MAIN(); \ No newline at end of file From 8d5d43051aed3200cb3f5a277817e53ef6b0e8c8 Mon Sep 17 00:00:00 2001 From: anyakakzovut <107941858+anyakakzovut@users.noreply.github.com> Date: Thu, 19 Dec 2024 23:53:37 +0300 Subject: [PATCH 8/8] add comments for tests.cpp --- 05_hw/tests.cpp | 76 ++++++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 30 deletions(-) diff --git a/05_hw/tests.cpp b/05_hw/tests.cpp index 0d68db6..0483875 100644 --- a/05_hw/tests.cpp +++ b/05_hw/tests.cpp @@ -5,111 +5,127 @@ using namespace std; class StackTest : public testing::Test { + // Метод, который выполняется перед каждым тестом void SetUp() override { - stack = new Stack(); + stack = new Stack(); // Создаем новый экземпляр стека } + // Метод, который выполняется после каждого теста void TearDown() override { - delete stack; + delete stack; // Удаляем стек, освобождая память } public: - Stack* stack; + Stack* stack; // Указатель на стек, который будет использоваться в тестах }; +// Тест на проверку, что стек пустой TEST_F(StackTest, isEmptyTest) { - ASSERT_EQ(isEmpty(stack), true); + ASSERT_EQ(isEmpty(stack), true); // Проверяем, что isEmpty возвращает true } +// Тест на получение верхнего элемента стека TEST_F(StackTest, getTopTest) { - ASSERT_EQ(getTop(stack), nullptr); + ASSERT_EQ(getTop(stack), nullptr); // Проверяем, что верхний элемент равен nullptr (стек пуст) } +// Тест на добавление элементов в стек TEST_F(StackTest, PushTest) { - push(stack, 3); - push(stack, 5); - ASSERT_EQ(getTop(stack)->data, 5); + push(stack, 3); // Добавляем элемент 3 + push(stack, 5); // Добавляем элемент 5 + ASSERT_EQ(getTop(stack)->data, 5); // Проверяем, что верхний элемент равен 5 } +// Тест на удаление элемента из стека TEST_F(StackTest, PopTest) { - push(stack, 3); - pop(stack); - ASSERT_EQ(getTop(stack), nullptr); + push(stack, 3); // Добавляем элемент 3 + pop(stack); // Удаляем верхний элемент + ASSERT_EQ(getTop(stack), nullptr); // Проверяем, что стек пустой (nullptr) } +// Тест на попытку удалить элемент из пустого стека TEST_F(StackTest, EmptyPopTest) { - pop(stack); - ASSERT_EQ(getTop(stack), nullptr); + pop(stack); // Пытаемся удалить элемент из пустого стека + ASSERT_EQ(getTop(stack), nullptr); // Проверяем, что стек все еще пустой } +// Тест на уничтожение стека TEST_F(StackTest, destroyStackTest) { - push(stack, 3); + push(stack, 3); // Добавляем элементы в стек push(stack, 5); push(stack, 15); - destroyStack(stack); + destroyStack(stack); // Уничтожаем стек - ASSERT_EQ(getTop(stack), nullptr); + ASSERT_EQ(getTop(stack), nullptr); // Проверяем, что стек пустой (nullptr) } +// Тест на поиск элемента по значению TEST_F(StackTest, searchByValueTest) { push(stack, 3); push(stack, 5); push(stack, 15); - ASSERT_EQ(searchByValue(stack, 5)->data, 5); + + ASSERT_EQ(searchByValue(stack, 5)->data, 5); // Проверяем, что найденный элемент равен 5 } +// Тест на поиск элемента по значению (не найдено) TEST_F(StackTest, searchByValueInvTest) { - ASSERT_EQ(searchByValue(stack, 5), nullptr); + ASSERT_EQ(searchByValue(stack, 5), nullptr); // Проверяем, что поиск возвращает nullptr (не найдено) } +// Тест на поиск элемента по индексу TEST_F(StackTest, searchByIndexTest) { push(stack, 3); push(stack, 5); push(stack, 15); - ASSERT_EQ(searchByIndex(stack, 1)->data, 5); + + ASSERT_EQ(searchByIndex(stack, 1)->data, 5); // Проверяем, что элемент с индексом 1 равен 5 } +// Тест на поиск элемента по индексу (не найдено) TEST_F(StackTest, searchByIndexInvTest) { - ASSERT_EQ(searchByIndex(stack, 1), nullptr); + ASSERT_EQ(searchByIndex(stack, 1), nullptr); // Проверяем, что поиск возвращает nullptr (не найдено) } +// Тест на обход стека и вывод его элементов TEST_F(StackTest, traverseStackTest) { - testing::internal::CaptureStdout(); + testing::internal::CaptureStdout(); // Захватываем стандартный вывод push(stack, 3); push(stack, 5); push(stack, 15); - traverseStack(stack); + traverseStack(stack); // Обходим стек и выводим элементы - std::string str = testing::internal::GetCapturedStdout(); - EXPECT_EQ("Stack elements: 15 5 3 \n", str); + std::string str = testing::internal::GetCapturedStdout(); // Получаем захваченный вывод + EXPECT_EQ("Stack elements: 15 5 3 \n", str); // Проверяем правильность вывода } +// Тест на обход пустого стека TEST_F(StackTest, traverseStackEmptyTest) { - testing::internal::CaptureStdout(); + testing::internal::CaptureStdout(); // Захватываем стандартный вывод - traverseStack(stack); + traverseStack(stack); // Обходим пустой стек - std::string str = testing::internal::GetCapturedStdout(); - EXPECT_EQ("Stack elements: \n", str); + std::string str = testing::internal::GetCapturedStdout(); // Получаем захваченный вывод + EXPECT_EQ("Stack elements: \n", str); // Проверяем правильность вывода для пустого стека } int main(int argc, char **argv) { - ::testing::InitGoogleTest(&argc, argv); + ::testing::InitGoogleTest(&argc, argv); // Инициализируем Google Test - return RUN_ALL_TESTS(); + return RUN_ALL_TESTS(); // Запускаем все тесты и возвращаем результат } \ No newline at end of file