#include "tests.h"
int main()
{
RunTests();
return 0;
}
#ifndef ADDRESS_H_
#define ADDRESS_H_
#include <string>
class Address {
public:
std::string name_;
std::string street_;
std::string city_;
int zip_code_ = 0;
void Write() const;
};
#endif // ADDRESS_H_
#include "address.h"
#include <iostream>
void Address::Write() const
{
std::cout << "Name: " << name_ << "\n";
std::cout << "Street: " << street_ << "\n";
std::cout << "City: " << zip_code_ << " " << city_ << "\n";
}
#ifndef ADDRESS_MANAGEMENT_H_
#define ADDRESS_MANAGEMENT_H_
#include <string>
#include <vector>
#include "address.h"
class AddressManagement {
public:
std::vector<Address> addresses_;
explicit AddressManagement(int number_of_addresses);
void ReadAllAddresses();
void WriteAllAddresses() const;
int GetNumberOfAddresses() const noexcept;
private:
static void ReadAddress(Address* address);
static std::string ReadText(const std::string& message);
static int ReadNumber(const std::string& message);
};
#endif // ADDRESS_MANAGEMENT_H_
#include "address_management.h"
#include <iostream>
AddressManagement::AddressManagement(int number_of_addresses)
{
addresses_.reserve(number_of_addresses);
for (auto i = 0; i < number_of_addresses; ++i) {
addresses_.emplace_back();
}
}
void AddressManagement::ReadAllAddresses()
{
for (auto& address : addresses_) {
ReadAddress(&address);
std::cout << "\n";
}
}
void AddressManagement::WriteAllAddresses() const
{
for (auto address : addresses_) {
address.Write();
}
}
int AddressManagement::GetNumberOfAddresses() const noexcept
{
return addresses_.size();
}
void AddressManagement::ReadAddress(Address* address)
{
address->name_ = ReadText("Please enter the name:");
address->street_ = ReadText("Please enter the street:");
address->zip_code_ = ReadNumber("Please enter the zip code:");
address->city_ = ReadText("Please enter the city:");
}
std::string AddressManagement::ReadText(const std::string& message)
{
std::string text;
std::cout << message << " ";
std::cin >> text;
return text;
}
int AddressManagement::ReadNumber(const std::string& message)
{
while (true) {
int result;
std::cout << message << " ";
std::cin >> result;
if (!std::cin.fail()) {
return result;
}
else {
std::cout << "Your mistake!"
<< "\n";
std::cin.clear();
std::cin.ignore();
}
}
}
#ifndef TESTS_H_
#define TESTS_H_
void RunTests();
#endif // TESTS_H_
#include "tests.h"
#include <iostream>
#include <sstream>
#include <string>
#include "test_functions.h"
#include "address.h"
#include "address_management.h"
void AddAddress(std::ostream& stream, const char* name, const int zip_code)
{
stream << name << "_a"
<< "\n";
stream << name << "_b"
<< "\n";
stream << zip_code << "\n";
stream << name << "_c"
<< "\n";
}
void PrepareAdresses(std::ostream& stream, const int number)
{
char buffer[2];
auto start_name = 'a';
auto start_number = 1;
for (auto i = 0; i < number; ++i) {
buffer[0] = start_name;
buffer[1] = '\0';
AddAddress(stream, buffer, start_number);
++start_number;
++start_name;
}
std::cin.rdbuf(stream.rdbuf());
}
std::string CheckPart(const std::string& output,
const std::string& search_string)
{
const auto index = output.find(search_string);
if (index == std::string::npos) {
auto message = std::string("Error: ") + search_string + " not found";
throw std::logic_error(message.c_str());
}
auto rest = output.substr(index);
return rest;
}
std::string CheckAdress(const std::string& output, const std::string& name,
const int zip_code)
{
auto rest = CheckPart(output, name + "_a");
rest = CheckPart(rest, name + "_b");
rest = CheckPart(rest, std::to_string(zip_code));
rest = CheckPart(rest, name + "_c");
return rest;
}
void CheckAdresses(const std::string& output, const int number)
{
char buffer[2];
auto start_name = 'a';
auto start_number = 1;
auto rest = output;
for (auto i = 0; i < number; ++i) {
buffer[0] = start_name;
buffer[1] = '\0';
rest = CheckAdress(rest, buffer, start_number);
++start_number;
++start_name;
}
}
TEST(TestAddressManagementInit)
{
const auto expected = 3;
AddressManagement management(expected);
ASSERT(management.GetNumberOfAddresses() == expected,
"AddressManagement initialization failed");
}
TEST(TestAddressManagementReadWrite)
{
const auto number_of_addresses = 3;
std::stringstream input;
std::stringstream output;
std::stringstream trash;
const auto old_buffer = std::cout.rdbuf();
AddressManagement management(number_of_addresses);
PrepareAdresses(input, management.GetNumberOfAddresses());
std::cout.rdbuf(trash.rdbuf());
management.ReadAllAddresses();
std::cout.rdbuf(output.rdbuf());
management.WriteAllAddresses();
auto output_string = output.str();
std::cout.rdbuf(old_buffer);
try {
CheckAdresses(output_string, management.GetNumberOfAddresses());
}
catch (std::exception& ex) {
ASSERT(false, ex.what());
}
}
TEST_SUITE(TestAddressManagement)
{
RUN_TEST(TestAddressManagementInit);
RUN_TEST(TestAddressManagementReadWrite);
}
void RunTests() { RUN_TEST_SUITE(TestAddressManagement); }
// Copyright 2018 MicroConsult GmbH
#ifndef TEST_FUNCTIONS_H_
#define TEST_FUNCTIONS_H_
#include <stdio.h>
static const int test_message_buffer_size = 1024;
static char test_message_buffer[test_message_buffer_size];
#define TEST(fx) static void fx(const char** message)
#define TEST_SUITE(fx) void fx(int* tests_total, int* tests_successful)
#define RUN_TEST(test) \
do { \
const char* message = nullptr; \
++*tests_total; \
test(&message); \
if (message) { \
printf("--- ERROR (%s): %s \n", #test, message); \
} \
else { \
++*tests_successful; \
printf("+++ passed: %s\n", #test); \
} \
} while (0)
#define RUN_TEST_SUITE(test_suite) \
do { \
int tests_total = 0; \
int tests_successful = 0; \
test_suite(&tests_total, &tests_successful); \
printf("-----------------------------------------------\n"); \
if (tests_successful == tests_total) { \
printf("+ Test Suite '%s': all %d tests passed\n\n", #test_suite, \
tests_total); \
} \
else { \
printf("- Test Suite '%s': %d of %d tests passed\n\n", #test_suite, \
tests_successful, tests_total); \
} \
} while (false)
#define ASSERT(test, error_message) \
do { \
if (test) { \
*message = nullptr; \
} \
else { \
snprintf(test_message_buffer, test_message_buffer_size - 1, \
error_message); \
*message = test_message_buffer; \
return; \
} \
} while (false)
#define ASSERT_INT(value, expected) \
do { \
if (value == expected) { \
*message = nullptr; \
} \
else { \
snprintf(test_message_buffer, test_message_buffer_size - 1, \
"Wrong value - expected: %d, current value: %d", expected, \
value); \
*message = test_message_buffer; \
return; \
} \
} while (false)
#endif // TEST_FUNCTIONS_H_