Skip to content

Commit

Permalink
Федотов Кирилл. Лабораторная работа №3 (#374)
Browse files Browse the repository at this point in the history
* lab3

* fix

* fix2

* fix3

* fix4

* fix5

* add tests

* fix

* add tests2

* add tests3

* add tests4

* add tests5

* add tests6

* fix

* fix

* fix

* fix

* fix

* fix

* fix
  • Loading branch information
KirFedotov authored May 31, 2024
1 parent 0df1df5 commit 291575b
Show file tree
Hide file tree
Showing 6 changed files with 316 additions and 0 deletions.
8 changes: 8 additions & 0 deletions modules/bakhtiarov_a_priority_queue/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,18 @@ get_filename_component(DIR_NAME ${CMAKE_CURRENT_LIST_DIR} NAME)
set(MODULE "${DIR_NAME}")
set(LIBRARY "lib_${MODULE}")
set(TESTS "test_${MODULE}")
set(APPLICATION "app_${MODULE}")

# Include directory with public headers
include_directories(${CMAKE_CURRENT_SOURCE_DIR})

# Add all submodules
add_subdirectory(src)
add_subdirectory(test)
add_subdirectory(application)

#############################################
##### Testing
#############################################

include("CTestTests.txt")
145 changes: 145 additions & 0 deletions modules/bakhtiarov_a_priority_queue/CTestTests.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
set(prefix "${MODULE}")

add_test(
NAME ${prefix}_run
COMMAND ${APPLICATION}
)
set_tests_properties (${prefix}_run PROPERTIES
PASS_REGULAR_EXPRESSION "Usage:"
LABELS "${MODULE}"
)

add_test(
NAME ${prefix}_run_help
COMMAND ${APPLICATION} --help
)
set_tests_properties (${prefix}_run_help PROPERTIES
PASS_REGULAR_EXPRESSION "Usage:"
LABELS "${MODULE}"
)

add_test(
NAME ${prefix}_run_push
COMMAND ${APPLICATION} 5 push 10 1
)
set_tests_properties (${prefix}_run_push PROPERTIES
PASS_REGULAR_EXPRESSION "Pushed"
LABELS "${MODULE}"
)

add_test(
NAME ${prefix}_run_pop
COMMAND ${APPLICATION} 5 pop
)
set_tests_properties (${prefix}_run_pop PROPERTIES
PASS_REGULAR_EXPRESSION "Queue is empty, cannot pop."
LABELS "${MODULE}"
)

add_test(
NAME ${prefix}_run_invalid_operation
COMMAND ${APPLICATION} 5 invalid_operation
)
set_tests_properties (${prefix}_run_invalid_operation PROPERTIES
PASS_REGULAR_EXPRESSION "Error: Operation must be 'push', 'pop', 'front' or 'back'."
LABELS "${MODULE}"
)

add_test(
NAME ${prefix}_run_negative_size
COMMAND ${APPLICATION} -1 push 10 1
)
set_tests_properties (${prefix}_run_negative_size PROPERTIES
PASS_REGULAR_EXPRESSION "Error: Queue size must be greater than 0."
LABELS "${MODULE}"
)

add_test(
NAME ${prefix}_run_push_multiple
COMMAND ${APPLICATION} 5 push 10 1 push 20 2 push 30 1
)
set_tests_properties (${prefix}_run_push_multiple PROPERTIES
PASS_REGULAR_EXPRESSION "Pushed"
LABELS "${MODULE}"
)

add_test(
NAME ${prefix}_run_insufficient_args_for_push
COMMAND ${APPLICATION} 5 push
)
set_tests_properties (${prefix}_run_insufficient_args_for_push PROPERTIES
PASS_REGULAR_EXPRESSION "Incorrect number of arguments for push."
LABELS "${MODULE}"
)

add_test(
NAME ${prefix}_run_front
COMMAND ${APPLICATION} 5 push 10 1 front
)
set_tests_properties (${prefix}_run_front PROPERTIES
PASS_REGULAR_EXPRESSION "Front element is: \\(10, 1\\)."
LABELS "${MODULE}"
)

add_test(
NAME ${prefix}_run_back
COMMAND ${APPLICATION} 5 push 10 1 back
)
set_tests_properties (${prefix}_run_back PROPERTIES
PASS_REGULAR_EXPRESSION "Back element is: \\(10, 1\\)."
LABELS "${MODULE}"
)

add_test(
NAME ${prefix}_invalid_input
COMMAND ${APPLICATION} 5 push abc 1
)
set_tests_properties (${prefix}_invalid_input PROPERTIES
PASS_REGULAR_EXPRESSION "Error: Unknown operation 'abc'\\..*Error: Unknown operation '1'\\."
LABELS "${MODULE}"
)

add_test(
NAME ${prefix}_test_front_operation
COMMAND ${APPLICATION} 5 push 1 1 front
)
set_tests_properties (${prefix}_test_front_operation PROPERTIES
PASS_REGULAR_EXPRESSION "Pushed \\(1, 1\\) into the queue\\.\nFront element is: \\(1, 1\\)\\."
LABELS "${MODULE}"
)

add_test(
NAME ${prefix}_run_insufficient_args_push
COMMAND ${APPLICATION} 5 push 10
)
set_tests_properties (${prefix}_run_insufficient_args_push PROPERTIES
PASS_REGULAR_EXPRESSION "Error: Insufficient arguments for push operation\\."
LABELS "${MODULE}"
)

add_test(
NAME ${prefix}_run_popping
COMMAND ${APPLICATION} 5 push 10 1 pop
)
set_tests_properties (${prefix}_run_popping PROPERTIES
PASS_REGULAR_EXPRESSION "Popped front element from the queue\\."
LABELS "${MODULE}"
)

add_test(
NAME ${prefix}_run_front_empty_queue
COMMAND ${APPLICATION} 1 front
)
set_tests_properties (${prefix}_run_front_empty_queue PROPERTIES
PASS_REGULAR_EXPRESSION "Queue is empty\\."
LABELS "${MODULE}"
)

add_test(
NAME ${prefix}_run_back_empty_queue
COMMAND ${APPLICATION} 1 back
)
set_tests_properties (${prefix}_run_back_empty_queue PROPERTIES
PASS_REGULAR_EXPRESSION "Queue is empty\\."
LABELS "${MODULE}"
)
15 changes: 15 additions & 0 deletions modules/bakhtiarov_a_priority_queue/application/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
set(target ${APPLICATION})

file(GLOB srcs "*.cpp")
set_source_files_properties(${srcs} PROPERTIES
LABELS "${MODULE};Application")

add_executable(${target} ${srcs})
set_target_properties(${target} PROPERTIES
OUTPUT_NAME ${MODULE}
LABELS "${MODULE};Application")

target_link_libraries(${target} ${LIBRARY})
if (UNIX)
target_link_libraries(${target} ${CMAKE_THREAD_LIBS_INIT})
endif (UNIX)
11 changes: 11 additions & 0 deletions modules/bakhtiarov_a_priority_queue/application/application.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright 2024 Fedotov Kirill

#include <iostream>

#include "include/priority_queue_app.h"

int main(int argc, char* argv[]) {
PriorityQueueApplication application;
std::cout << application.ProcessQueueOperations(argc, argv) << std::endl;
return 0;
}
21 changes: 21 additions & 0 deletions modules/bakhtiarov_a_priority_queue/include/priority_queue_app.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2024 Fedotov Kirill

#pragma once

#include <string>
#include <utility>

#include "include/priority_queue.h"

class PriorityQueueApplication {
private:
std::string msg;
TQueue_insert<int> queue;
bool Validate(int argc, char* argv[]);
void Help(const char* application, const char* errMsg = nullptr);

public:
PriorityQueueApplication() = default;
std::string ProcessQueueOperations(int argc, char* argv[]);
std::string ProcessMultipleOperations(int argc, char *argv[]);
};
116 changes: 116 additions & 0 deletions modules/bakhtiarov_a_priority_queue/src/priority_queue_app.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// Copyright 2024 Fedotov Kirill

#include "include/priority_queue_app.h"
#include <sstream>
#include <cstring>
#include <exception>

bool PriorityQueueApplication::Validate(int argc, char *argv[]) {
int required_argc = 4;
if (argc == 1) {
Help(argv[0]);
return false;
} else if (std::strcmp(argv[1], "--help") == 0) {
Help(argv[0]);
return false;
} else if (std::strcmp(argv[2], "push") != 0
&& std::strcmp(argv[2], "pop") != 0
&& std::strcmp(argv[2], "front") != 0
&& std::strcmp(argv[2], "back") != 0) {
Help(argv[0], "Operation must be 'push', 'pop', 'front' or 'back'.");
return false;
} else if (argc < required_argc && std::strcmp(argv[2], "push") == 0) {
Help(argv[0], "Incorrect number of arguments for push.");
return false;
} else {
try {
int size = std::stoi(argv[1]);
if (size < 1) {
throw std::invalid_argument
("Queue size must be greater than 0.");
}
queue = TQueue_insert<int>(size);
} catch(const std::exception& e) {
Help(argv[0], e.what());
return false;
}
}
return true;
}

void PriorityQueueApplication::Help
(const char *application, const char *errMsg) {
std::stringstream message;

if (errMsg) {
message << "Error: " << errMsg << '\n';
}

message << "Usage:\n";
message << '\t' << application <<
" <size> <operation> [<value> <priority>]\n";
message << "Where:\n";
message << '\t' << "<size> is the maximum size of the queue\n";
message << '\t' <<
"<operation> is the queue operation ('push', 'pop', 'front', 'back')\n";
message << '\t' <<
"[<value> <priority>] are required for 'push' operation\n";
msg = message.str();
}

std::string PriorityQueueApplication::ProcessQueueOperations
(int argc, char *argv[]) {
if (Validate(argc, argv)) {
return ProcessMultipleOperations(argc, argv);
}
return msg;
}

std::string PriorityQueueApplication::ProcessMultipleOperations
(int argc, char *argv[]) {
std::stringstream result;
for (int i = 2; i < argc; ++i) {
if (std::strcmp(argv[i], "push") == 0) {
if (i + 2 < argc) {
try {
int value = std::stoi(argv[i + 1]);
int priority = std::stoi(argv[i + 2]);
queue.push(std::make_pair(value, priority));
result << "Pushed (" << value << ", " << priority
<< ") into the queue.\n";
i += 2;
} catch(const std::exception& e) {
result << e.what() << "\n";
}
} else {
result << "Error: Insufficient arguments for push operation.\n";
}
} else if (std::strcmp(argv[i], "pop") == 0) {
if (queue.isEmpty()) {
result << "Queue is empty, cannot pop.\n";
} else {
queue.pop();
result << "Popped front element from the queue.\n";
}
} else if (std::strcmp(argv[i], "front") == 0) {
if (queue.isEmpty()) {
result << "Queue is empty.\n";
} else {
auto front_elem = queue.front();
result << "Front element is: (" << front_elem.first << ", "
<< front_elem.second << ").\n";
}
} else if (std::strcmp(argv[i], "back") == 0) {
if (queue.isEmpty()) {
result << "Queue is empty.\n";
} else {
auto back_elem = queue.back();
result << "Back element is: (" << back_elem.first << ", "
<< back_elem.second << ").\n";
}
} else {
result << "Error: Unknown operation '" << argv[i] << "'.\n";
}
}
return result.str();
}

0 comments on commit 291575b

Please sign in to comment.