diff --git a/TDD/biblioteca_test b/TDD/biblioteca_test new file mode 100755 index 0000000000000000000000000000000000000000..6fcb23ad0781f610fe4719d355ead198a0dd08cf Binary files /dev/null and b/TDD/biblioteca_test differ diff --git a/TDD/sources/biblioteca-test.cpp b/TDD/sources/biblioteca-test.cpp index 3bcc8e48dbc1c28c1e29c308ac35648f09bee76b..0febdbc99fd8ac536433b0cf1c682b892f93390f 100644 --- a/TDD/sources/biblioteca-test.cpp +++ b/TDD/sources/biblioteca-test.cpp @@ -8,8 +8,16 @@ #include "Biblioteca.hpp" #include "Livro.hpp" #include "Periodico.hpp" +#include "Clock.hpp" TEST_CASE("Biblioteca") { + cout << "=====================> Biblioteca <====================" << endl; + cout << "=======================================================" << endl; + + cout << "=> Inicia O relogio" << endl; + chrono::year_month_day epoch = Clock::getTime(); + chrono::year_month_day hoje = Clock::init(); + cout << "=> Instanciando Biblioteca" << endl; Biblioteca& bib = Biblioteca::getInstance(); @@ -81,9 +89,6 @@ TEST_CASE("Biblioteca") { cout << "======================================================" << endl; cout << "===================> Emprestimos <====================" << endl; - chrono::year_month_day hoje = {chrono::floor<chrono::days>(chrono::system_clock::now()) + chrono::days(3)}; - chrono::year_month_day epoch = chrono::year_month_day{chrono::year{0}, chrono::month{0}, chrono::day{0}}; - cout << "=> Usuario que nao existe tenta realizar um emprestimo: " << endl; chrono::year_month_day dataDevolucao = contUsuarios.registrarEmprestimo("11234", make_shared<Livro>(l)); CHECK (int(epoch.year()) == int(dataDevolucao.year())); @@ -107,7 +112,7 @@ TEST_CASE("Biblioteca") { dataDevolucao = contUsuarios.registrarEmprestimo("12345", make_shared<Periodico>(p)); CHECK (int(hoje.year()) == int(dataDevolucao.year())); CHECK (unsigned(hoje.month()) == unsigned(dataDevolucao.month())); - CHECK (unsigned(hoje.day()) == unsigned(dataDevolucao.day())); + CHECK (unsigned(hoje.day() + chrono::days(3)) == unsigned(dataDevolucao.day())); tie(total, disponiveis) = contObras.pesquisarObra(make_shared<Periodico>(p)); cout << "Disponiveis/Total: " << disponiveis << "/" << total << endl; @@ -126,13 +131,13 @@ TEST_CASE("Biblioteca") { dataDevolucao = contUsuarios.registrarEmprestimo("12345", make_shared<Periodico>(p)); CHECK (int(hoje.year()) == int(dataDevolucao.year())); CHECK (unsigned(hoje.month()) == unsigned(dataDevolucao.month())); - CHECK (unsigned(hoje.day()) == unsigned(dataDevolucao.day())); + CHECK (unsigned(hoje.day() + chrono::days(3)) == unsigned(dataDevolucao.day())); cout << "=> Empresta a segunda obra: " << endl; dataDevolucao = contUsuarios.registrarEmprestimo("12345", make_shared<Periodico>(p)); CHECK (int(hoje.year()) == int(dataDevolucao.year())); CHECK (unsigned(hoje.month()) == unsigned(dataDevolucao.month())); - CHECK (unsigned(hoje.day()) == unsigned(dataDevolucao.day())); + CHECK (unsigned(hoje.day() + chrono::days(3)) == unsigned(dataDevolucao.day())); cout << "=> Obra nao tem exemplares disponiveis: " << endl; dataDevolucao = contUsuarios.registrarEmprestimo("54321", make_shared<Periodico>(p1)); @@ -182,14 +187,25 @@ TEST_CASE("Biblioteca") { dataDevolucao = contUsuarios.registrarEmprestimo("12345", make_shared<Livro>(l3)); CHECK (int(hoje.year()) == int(dataDevolucao.year())); CHECK (unsigned(hoje.month()) == unsigned(dataDevolucao.month())); - CHECK (unsigned(hoje.day()) == unsigned(dataDevolucao.day())); + CHECK (unsigned(hoje.day() + chrono::days(3)) == unsigned(dataDevolucao.day())); tie(total, disponiveis) = contObras.pesquisarObra(make_shared<Livro>(l3)); cout << "Disponiveis/Total: " << disponiveis << "/" << total << endl; CHECK (0 == disponiveis); CHECK (1 == total); - //usuario devolveu com atraso, nao pode emprestar depois + cout << "=> Usuario devolveu no quarto dia: " << endl; + hoje = Clock::fastFowardDays(chrono::days(4)); + CHECK (0 == contUsuarios.retornarEmprestimo("12345", make_shared<Livro>(l3))); + + cout << "==> Não pode emprestar outra obra até pagar a multa: " << endl; + dataDevolucao = contUsuarios.registrarEmprestimo("12345", make_shared<Livro>(l3)); + CHECK (int(epoch.year()) == int(dataDevolucao.year())); + CHECK (unsigned(epoch.month()) == unsigned(dataDevolucao.month())); + CHECK (unsigned(epoch.day()) == unsigned(dataDevolucao.day())); + + //cout << "===> Multa paga, pode emprestar novamente: " << endl; + cout << "======================================================" << endl; cout << "================> Recuperar Multas <==================" << endl; diff --git a/TDD/sources/clock-test.cpp b/TDD/sources/clock-test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a96f59ab3577762850d8ff09bea31c0b2f053c18 --- /dev/null +++ b/TDD/sources/clock-test.cpp @@ -0,0 +1,47 @@ +#include <iostream> +#include <tuple> +#include <chrono> +#include <memory> +#include "doctest.h" +#include "Clock.hpp" + +using namespace std; + +TEST_CASE("Set time") { + cout << "====================> Set Time <=======================" << endl; + cout << "=======================================================" << endl; + chrono::year_month_day hoje_sistema = {chrono::floor<chrono::days>(chrono::system_clock::now())}; + + cout << "=> Inicia o relogio" << endl; + chrono::year_month_day hoje = Clock::init(); + cout << "Data: " << unsigned(hoje.day()) << "/" << unsigned(hoje.month()) << "/" << int(hoje.year()) << endl; + + CHECK(int(hoje_sistema.year()) == int(hoje.year())); + CHECK(unsigned(hoje_sistema.month()) == unsigned(hoje.month())); + CHECK(unsigned(hoje_sistema.day()) == unsigned(hoje.day())); + + cout << "=> Pega o tempo atual" << endl; + hoje = Clock::getTime(); + cout << "Data: " << unsigned(hoje.day()) << "/" << unsigned(hoje.month()) << "/" << int(hoje.year()) << endl; + + CHECK(int(hoje_sistema.year()) == int(hoje.year())); + CHECK(unsigned(hoje_sistema.month()) == unsigned(hoje.month())); + CHECK(unsigned(hoje_sistema.day()) == unsigned(hoje.day())); + + cout << "=> Avança em três dias" << endl; + hoje = Clock::fastFowardDays(chrono::days(3)); + cout << "Data: " << unsigned(hoje.day()) << "/" << unsigned(hoje.month()) << "/" << int(hoje.year()) << endl; + + CHECK(int(hoje_sistema.year()) == int(hoje.year())); + CHECK(unsigned(hoje_sistema.month()) == unsigned(hoje.month())); + CHECK(unsigned(hoje_sistema.day() + chrono::days(3)) == unsigned(hoje.day())); + + cout << "=> Avança para o quarto dia" << endl; + hoje = Clock::fastFowardDays(chrono::days(1)); + cout << "Data: " << unsigned(hoje.day()) << "/" << unsigned(hoje.month()) << "/" << int(hoje.year()) << endl; + + CHECK(int(hoje_sistema.year()) == int(hoje.year())); + CHECK(unsigned(hoje_sistema.month()) == unsigned(hoje.month())); + CHECK(unsigned(hoje_sistema.day() + chrono::days(4)) == unsigned(hoje.day())); + cout << "=======================================================" << endl; +} \ No newline at end of file diff --git a/sources/Clock.cpp b/sources/Clock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c0af887639f4b2272256114ab952accb6dd782de --- /dev/null +++ b/sources/Clock.cpp @@ -0,0 +1,28 @@ +#include "Clock.hpp" + +using namespace std; + +static chrono::time_point<Clock::ClockType> now = chrono::time_point<Clock::ClockType>(std::chrono::seconds(0)); + +chrono::year_month_day Clock::convert(chrono::time_point<Clock::ClockType> time) { + chrono::year_month_day ymd = chrono::floor<std::chrono::days>(time); + return chrono::year_month_day{ymd}; +} + +chrono::year_month_day Clock::init() { + now = ClockType::now(); + return convert(now); +} + +chrono::year_month_day Clock::epoch() { + return convert(chrono::time_point<Clock::ClockType>(std::chrono::seconds(0))); +} + +chrono::year_month_day Clock::getTime() { + return convert(now); +} + +chrono::year_month_day Clock::fastFowardDays(chrono::days days) { + now += days; + return convert(now); +} diff --git a/sources/Clock.hpp b/sources/Clock.hpp new file mode 100644 index 0000000000000000000000000000000000000000..5ffe068883d424f4d1c2f6994827d7ff4da38a4e --- /dev/null +++ b/sources/Clock.hpp @@ -0,0 +1,21 @@ +#ifndef __CLOCK__ +#define __CLOCK__ + +#include <chrono> + +using namespace std; + +class Clock { + private: + Clock(); + + public: + using ClockType = std::chrono::system_clock; + static chrono::year_month_day init(); + static chrono::year_month_day epoch(); + static chrono::year_month_day getTime(); + static chrono::year_month_day fastFowardDays(chrono::days days); + static chrono::year_month_day convert(chrono::time_point<Clock::ClockType> time); +}; + +#endif \ No newline at end of file diff --git a/sources/ControladorUsuarios.cpp b/sources/ControladorUsuarios.cpp index e2d92dd9f30c52dd0193b623a10df99cba203372..2300705946e4f4433a37856cbefbdff434e792a0 100644 --- a/sources/ControladorUsuarios.cpp +++ b/sources/ControladorUsuarios.cpp @@ -5,6 +5,7 @@ #include "ControladorUsuarios.hpp" #include "Usuario.hpp" +#include "Clock.hpp" using namespace std; @@ -54,7 +55,7 @@ chrono::year_month_day ControladorUsuarios::registrarEmprestimo(string CPF, shar if (user_it == usuarios.end()) { cerr << "> Erro: Usuario não encontrado" << endl; - return chrono::year_month_day{chrono::year{0}, chrono::month{0}, chrono::day{0}}; + return Clock::epoch(); } chrono::year_month_day dataDevolucao = user_it->emprestar(descricao); @@ -75,12 +76,7 @@ int ControladorUsuarios::retornarEmprestimo(string CPF, shared_ptr<DescricaoObra return -1; } - if (!user_it->devolver(descricao)){ - cerr << "> Erro: Falha ao realizar a devolução" << endl; - return -1; - } - - return 0; + return user_it->devolver(descricao); } diff --git a/sources/Emprestimo.cpp b/sources/Emprestimo.cpp index 1f6388d9dc276700af505b608905922c4a956237..324d276a5803dbd226a622096ff375c061fb90b8 100644 --- a/sources/Emprestimo.cpp +++ b/sources/Emprestimo.cpp @@ -5,6 +5,7 @@ #include "Emprestimo.hpp" #include "DescricaoObra.hpp" #include "ControladorObras.hpp" +#include "Clock.hpp" using namespace std; @@ -12,8 +13,7 @@ using namespace std; Emprestimo::Emprestimo(shared_ptr<DescricaoObra> descricao) : descricao(descricao) { - const chrono::time_point now{chrono::system_clock::now()}; - this->dataEmprestimo = {chrono::floor<chrono::days>(now)}; + this->dataEmprestimo = Clock::getTime(); ControladorObras contObras = ControladorObras::getInstance(); if (!contObras.solicitarEmprestimo(descricao)) { @@ -31,17 +31,16 @@ void Emprestimo::mostraDetalhes() const { // Methods -void Emprestimo::removeEmprestimo(){ +bool Emprestimo::removeEmprestimo(){ ControladorObras contObras = ControladorObras::getInstance(); if (!contObras.devolverEmprestimo(descricao)) { - throw runtime_error("> Erro: obra nao existe"); + return false; } + return true; } chrono::year_month_day Emprestimo::getDataDevolucao() { - chrono::sys_days emprestimoDias = this->dataEmprestimo; - chrono::sys_days devolucaoDias = emprestimoDias + chrono::days{3}; - return chrono::year_month_day{devolucaoDias}; + return chrono::sys_days(this->dataEmprestimo) + std::chrono::days(3); } string Emprestimo::getDescricaoTitulo(){ diff --git a/sources/Emprestimo.hpp b/sources/Emprestimo.hpp index b5ea1967f88c7d1f1a46f2fc7ac0856f563c57c6..3408d4556f6ed6b685b7da612faf01cc8f28471e 100644 --- a/sources/Emprestimo.hpp +++ b/sources/Emprestimo.hpp @@ -16,7 +16,7 @@ class Emprestimo { void mostraDetalhes() const; // Methods - void removeEmprestimo(); + bool removeEmprestimo(); string getDescricaoTitulo(); std::chrono::year_month_day getDataDevolucao(); diff --git a/sources/Usuario.cpp b/sources/Usuario.cpp index 5a881efb7cb182c858a750beec0d70ab5bffcdaa..faf365375223d7df28d4b629159d19ce3c065a52 100644 --- a/sources/Usuario.cpp +++ b/sources/Usuario.cpp @@ -1,11 +1,11 @@ #include <exception> #include <iostream> #include <algorithm> -#include <chrono> #include <memory> #include "Emprestimo.hpp" #include "Usuario.hpp" +#include "Clock.hpp" using namespace std; @@ -24,14 +24,19 @@ void Usuario::mostrarDetalhes() const { cout << "Multas: " << multas << endl; } - // Methods chrono::year_month_day Usuario::emprestar(shared_ptr<DescricaoObra> descricao){ // Check number of Borrowed works if (this->emprestimos->size() >= 3) { cerr << "> Erro: Usuario já possui três emprestimos! Ignorando operação" << endl; - return chrono::year_month_day{chrono::year{0}, chrono::month{0}, chrono::day{0}}; + return Clock::epoch(); + } + + int multa = this->getMulta(); + if (multa > 0) { + cerr << "> Erro: Usuario possui " << multa << " reais em multas! Ignorando operação" << endl; + return Clock::epoch(); } // Create Emprestimo @@ -42,11 +47,11 @@ chrono::year_month_day Usuario::emprestar(shared_ptr<DescricaoObra> descricao){ return emp.getDataDevolucao(); } catch (const exception&) { cerr << "> Erro: Falha ao criar um emprestimo!" << endl; - return chrono::year_month_day{chrono::year{0}, chrono::month{0}, chrono::day{0}}; + return Clock::epoch(); } } -bool Usuario::devolver(shared_ptr<DescricaoObra> descricao){ +int Usuario::devolver(shared_ptr<DescricaoObra> descricao){ // Search for Borrowed work auto emp_it = find_if(this->emprestimos->begin(), this->emprestimos->end(), [&descricao](Emprestimo& emp){ @@ -55,15 +60,23 @@ bool Usuario::devolver(shared_ptr<DescricaoObra> descricao){ if (emp_it == this->emprestimos->end()){ cerr << "> Erro: Obra não encontrada nos emprestimos do Usuário!" << endl; - return false; + return -1; } - emp_it->removeEmprestimo(); + if (!emp_it->removeEmprestimo()) { + return -1; + } + + chrono::days dias_de_atraso = chrono::duration_cast<chrono::days>(chrono::sys_days(Clock::getTime()) - chrono::sys_days(emp_it->getDataDevolucao())); + + if (dias_de_atraso.count() > 0) { + this->atualizarMulta(dias_de_atraso.count() * 10); + } // Remove work this->emprestimos->erase(emp_it); - return true; + return 0; } // Increase fees diff --git a/sources/Usuario.hpp b/sources/Usuario.hpp index 15bdace32e64aa2706e0dfc45e9bb63b0f120a5f..c515a2c77c493aaf157568ad2e3721e0d06a1180 100644 --- a/sources/Usuario.hpp +++ b/sources/Usuario.hpp @@ -30,7 +30,7 @@ class Usuario { // Methods std::chrono::year_month_day emprestar(shared_ptr<DescricaoObra> descricao); - bool devolver(shared_ptr<DescricaoObra> descricao); + int devolver(shared_ptr<DescricaoObra> descricao); int atualizarMulta(int valor); // Increase fee string getCPF(); int getMulta(); diff --git a/sources/main.cpp b/sources/main.cpp index bce66b0cfeef7c203c98098d4d244cf63e580ce7..bede3b242ec2b63179290566c6dc76f14b86fb8d 100644 --- a/sources/main.cpp +++ b/sources/main.cpp @@ -234,57 +234,3 @@ int main(){ return 0; } - - -// case BORROWWORK: -// cout << "Entre com o CPF do usuário: "; cin >> userCPF; -// cout << "Entre com o tipo da obra (periodico|livro): "; cin >> tipoObra; cin.ignore(); -// if (tipoObra == "periodico") { -// cout << "Entre com o titulo: "; getline(cin, titulo); -// cout << "Entre com o ano: "; cin >> ano; -// cout << "Entre com o volume: "; cin >> volume; -// cout << "Entre com o mês: "; cin >> mes; -// chrono::year_month_day devolucao = contUsuarios.registrarEmprestimo( -// userCPF, make_shared<Periodico>(titulo, 0, 0, 0)); -// if (int(devolucao.year()) == 0 && -// unsigned(devolucao.month()) == 0 && -// unsigned(devolucao.day()) == 0) { -// cerr << "> Erro: Falha ao realizar um emprestimo" << endl; -// } else { cout << "> Emprestimo realizado com sucesso!" << endl; } -// } else if (tipoObra == "livro") { -// cout << "Entre com o titulo: "; getline(cin, titulo); -// cout << "Entre com o ano: "; cin >> ano; cin.ignore(); -// cout << "Entre com o autor: "; getline(cin, autor); -// cout << "Entre com o editora: "; getline(cin, editora); -// chrono::year_month_day devolucao = contUsuarios.registrarEmprestimo( -// userCPF, make_shared<Livro>(titulo, 0, "dummy", "dummy")); -// if (int(devolucao.year()) == 0 && -// unsigned(devolucao.month()) == 0 && -// unsigned(devolucao.day()) == 0) { -// cerr << "> Erro: Falha ao realizar um emprestimo" << endl; -// } else { cout << "> Emprestimo realizado com sucesso!" << endl; } -// } else { cout << "> Erro: Tipo não reconhecido! Ignorando operação" << endl; } -// break; -// -// case RETURNWORK: -// cout << "Entre com o CPF do usuário: "; cin >> userCPF; -// cout << "Entre com o tipo da obra (periodico|livro): "; cin >> tipoObra; cin.ignore(); -// if (tipoObra == "periodico") { -// cout << "Entre com o titulo: "; getline(cin, titulo); -// cout << "Entre com o ano: "; cin >> ano; -// cout << "Entre com o volume: "; cin >> volume; -// cout << "Entre com o mês: "; cin >> mes; -// if (contUsuarios.retornarEmprestimo(userCPF, make_shared<Periodico>(titulo, 0, 0, 0)) < 0){ -// cout << "> Devolução realizada com sucesso!" << endl; -// } -// } else if (tipoObra == "livro") { -// cout << "Entre com o titulo: "; getline(cin, titulo); -// cout << "Entre com o ano: "; cin >> ano; cin.ignore(); -// cout << "Entre com o autor: "; getline(cin, autor); -// cout << "Entre com o editora: "; getline(cin, editora); -// if (contUsuarios.retornarEmprestimo(userCPF, make_shared<Livro>(titulo, 0, "dummy", "dummy")) < 0){ -// cout << "> Devolução realizada com sucesso!" << endl; -// } -// } else { cout << "> Erro: Tipo não reconhecido! Ignorando operação" << endl; } -// break; -//