diff --git a/Assignment_3/lib/ADT_Stack.cpp b/Assignment_3/lib/ADT_Stack.cpp index 1e0e258..7e1c042 100644 --- a/Assignment_3/lib/ADT_Stack.cpp +++ b/Assignment_3/lib/ADT_Stack.cpp @@ -1,5 +1,67 @@ -class Stack { - void push(int element, bool output); - void pop(int element, bool output); - void size(int element, bool output); -}; \ No newline at end of file +#include +#include +#include +#include + +#include "ADT_Stack.h" + +operation create_operation(methodname name, int value) { + operation op; + op.method = name; + op.value = value; + return op; +} + + +void ADTStack::push(int element){ + stack.push(element); +} + +void ADTStack::pop(int output) { + if (stack.empty() == false) { + int top = stack.top(); + if (output == top){ + stack.pop(); + } else { + std::ostringstream oss; + oss << "Invalid operation: pop " << output << " (actual top: " << top << ")"; + throw std::invalid_argument(oss.str()); + } + } else { + std::ostringstream oss; + oss << "Invalid operation: pop " << output << " (stack is empty)"; + throw std::invalid_argument(oss.str()); + } +} + +void ADTStack::size(int output){ + int size = stack.size(); + if (output != size) { + std::ostringstream oss; + oss << "Invalid operation: size " << output << " (actual size: " << size << ")"; + throw std::invalid_argument(oss.str()); + } +} + +void ADTStack::do_op(operation * op) { + switch (op->method) { + case methodname::push: + push(op->value); + break; + case methodname::pop: + pop(op->value); + break; + case methodname::size: + size(op->value); + break; + default: + break; + } +} + +void ADTStack::do_ops(std::vector ops) { + for (operation op : ops) { + do_op(&op); + } +} + diff --git a/Assignment_3/lib/ADT_Stack.h b/Assignment_3/lib/ADT_Stack.h new file mode 100644 index 0000000..9a6a64a --- /dev/null +++ b/Assignment_3/lib/ADT_Stack.h @@ -0,0 +1,21 @@ +#include +#include + +enum methodname {push, pop, size, noop}; +typedef struct _operation{ + methodname method; + int value; +} operation; + +operation create_operation(methodname name, int value); + +class ADTStack { + private: + std::stack stack; + public: + void push(int element); + void pop(int output); + void size(int output); + void do_op(operation * op); + void do_ops(std::vector ops); +}; \ No newline at end of file diff --git a/Assignment_3/lib/CMakeLists.txt b/Assignment_3/lib/CMakeLists.txt index be8e6f8..12db947 100644 --- a/Assignment_3/lib/CMakeLists.txt +++ b/Assignment_3/lib/CMakeLists.txt @@ -1 +1 @@ -add_library(sets STATIC Node.h Node.cpp Stack.h Stack.cpp ADT_Stack.cpp ) +add_library(sets STATIC ADT_Stack.h ADT_Stack.cpp Node.h Node.cpp Stack.h Stack.cpp ) diff --git a/Assignment_3/test/ADT_Stack_test.cpp b/Assignment_3/test/ADT_Stack_test.cpp new file mode 100644 index 0000000..04a2fba --- /dev/null +++ b/Assignment_3/test/ADT_Stack_test.cpp @@ -0,0 +1,78 @@ +#include + +#include +#include +#include + +TEST(ADTStackTest, SimplePushPop) { + std::vector ops; + + ops.push_back(create_operation(methodname::push, 1)); + ops.push_back(create_operation(methodname::pop, 1)); + + ADTStack * adt = new ADTStack(); + adt->do_ops(ops); +} + +TEST(ADTStackTest, SimplePopWrong) { + std::vector ops; + ops.push_back(create_operation(methodname::push, 2)); + ops.push_back(create_operation(methodname::pop, 1)); + + ADTStack * adt = new ADTStack(); + + try { + adt->do_ops(ops); + FAIL() << "Expected std::invalid_argument"; + } + catch(std::invalid_argument const & err) { + EXPECT_EQ(err.what(),std::string("Invalid operation: pop 1 (actual top: 2)")); + } + catch(...) { + FAIL() << "Expected std::invalid_argument"; + } +} + +TEST(ADTStackTest, PopEmpty) { + std::vector ops; + ops.push_back(create_operation(methodname::pop, 1)); + + ADTStack * adt = new ADTStack(); + + try { + adt->do_ops(ops); + FAIL() << "Expected std::invalid_argument"; + } + catch(std::invalid_argument const & err) { + EXPECT_EQ(err.what(),std::string("Invalid operation: pop 1 (stack is empty)")); + } + catch(...) { + FAIL() << "Expected std::invalid_argument"; + } +} + +TEST(ADTStackTest, SizeEmpty) { + std::vector ops; + ops.push_back(create_operation(methodname::size, 0)); + + ADTStack * adt = new ADTStack(); + adt->do_ops(ops); +} +TEST(ADTStackTest, SizeEmptyWrong) { + std::vector ops; + ops.push_back(create_operation(methodname::size, 1)); + + ADTStack * adt = new ADTStack(); + + try { + adt->do_ops(ops); + FAIL() << "Expected std::invalid_argument"; + } + catch(std::invalid_argument const & err) { + EXPECT_EQ(err.what(),std::string("Invalid operation: size 1 (actual size: 0)")); + } + catch(...) { + FAIL() << "Expected std::invalid_argument"; + } +} + diff --git a/Assignment_3/test/CMakeLists.txt b/Assignment_3/test/CMakeLists.txt index 133ce92..d2bc02f 100644 --- a/Assignment_3/test/CMakeLists.txt +++ b/Assignment_3/test/CMakeLists.txt @@ -10,3 +10,8 @@ add_executable(node_unit_test Node_test.cpp) target_link_libraries(node_unit_test PUBLIC gtest gtest_main) target_link_libraries(node_unit_test PUBLIC sets) add_test(NodeTest node_unit_test) + +add_executable(adt_unit_test ADT_Stack_test.cpp) +target_link_libraries(adt_unit_test PUBLIC gtest gtest_main) +target_link_libraries(adt_unit_test PUBLIC sets) +add_test(ADTTest adt_unit_test)