diff --git a/tdd_intro/cleanroom/ChatClient.mpp b/tdd_intro/cleanroom/ChatClient.mpp new file mode 100644 index 0000000..ca3ea39 Binary files /dev/null and b/tdd_intro/cleanroom/ChatClient.mpp differ diff --git a/tdd_intro/cleanroom/chatclient/chatclient.pro b/tdd_intro/cleanroom/chatclient/chatclient.pro index 013729f..8f007ce 100644 --- a/tdd_intro/cleanroom/chatclient/chatclient.pro +++ b/tdd_intro/cleanroom/chatclient/chatclient.pro @@ -6,9 +6,13 @@ CONFIG -= app_bundle CONFIG -= qt SOURCES += \ - test.cpp + test.cpp \ + socketwrapper.cpp LIBS += \ Ws2_32.lib \ Mswsock.lib \ AdvApi32.lib + +HEADERS += \ + socketwrapper.h diff --git a/tdd_intro/cleanroom/chatclient/socketwrapper.cpp b/tdd_intro/cleanroom/chatclient/socketwrapper.cpp new file mode 100644 index 0000000..7d755ec --- /dev/null +++ b/tdd_intro/cleanroom/chatclient/socketwrapper.cpp @@ -0,0 +1,107 @@ +#define WIN32_LEAN_AND_MEAN +#define _WINSOCK_DEPRECATED_NO_WARNINGS + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "SocketWrapper.h" + +namespace +{ + std::string GetExceptionString(const std::string& message, int errorCode) + { + std::stringstream stream; + stream << message; + stream << errorCode; + stream << std::endl; + return stream.str(); + } +} + +SocketWrapper::SocketWrapper() + : m_socket(INVALID_SOCKET) +{ + m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (m_socket == INVALID_SOCKET) + { + throw std::runtime_error(GetExceptionString("Failed to create socket to listen on.", WSAGetLastError())); + } +} + +SocketWrapper::SocketWrapper(SOCKET & other) + : m_socket(other) +{ +} + +SocketWrapper::~SocketWrapper() +{ + closesocket(m_socket); +} + +void SocketWrapper::Bind(const std::string& addr, int16_t port) +{ + sockaddr_in addres; + addres.sin_family = AF_INET; + addres.sin_addr.s_addr = inet_addr(addr.data()); + addres.sin_port = htons(port); + if (bind(m_socket, reinterpret_cast(&addres), sizeof(addres)) == SOCKET_ERROR) + { + throw std::runtime_error(GetExceptionString("Failed to bind socket to address.", WSAGetLastError())); + } +} + +void SocketWrapper::Listen() +{ + if (listen(m_socket, SOMAXCONN) == SOCKET_ERROR) + { + throw std::runtime_error(GetExceptionString("Failed to listen on socket.", WSAGetLastError())); + } +} + +ISocketWrapperPtr SocketWrapper::Accept() +{ +// SOCKET other = accept(m_socket, nullptr, nullptr); +// if (other == INVALID_SOCKET) +// { +// throw std::runtime_error(GetExceptionString("Failed to connect to client.", WSAGetLastError())); +// } +// return SocketWrapper(other); + return nullptr; +} + +ISocketWrapperPtr SocketWrapper::Connect(const std::string& addr, int16_t port) +{ +// sockaddr_in addres; +// addres.sin_family = AF_INET; +// addres.sin_addr.s_addr = inet_addr(addr.data()); +// addres.sin_port = htons(port); +// SOCKET other = connect(m_socket, reinterpret_cast(&addres), sizeof(addres)); +// if (other == INVALID_SOCKET) +// { +// throw std::runtime_error(GetExceptionString("Failed to connect to server.", WSAGetLastError())); +// } +// return SocketWrapper(other); + return nullptr; +} + +void SocketWrapper::Read(std::string& buffer) +{ + std::vector bufferTmp; + bufferTmp.resize(buffer.size()); + if (SOCKET_ERROR == recv(m_socket, bufferTmp.data(), bufferTmp.size(), 0)) + { + throw std::runtime_error(GetExceptionString("Failed to connect to server.", WSAGetLastError())); + } + buffer.assign(bufferTmp.begin(), bufferTmp.end()); +} + +void SocketWrapper::Write(const std::string& buffer) +{ + send(m_socket, buffer.data(), buffer.size(), 0); +} diff --git a/tdd_intro/cleanroom/chatclient/socketwrapper.h b/tdd_intro/cleanroom/chatclient/socketwrapper.h new file mode 100644 index 0000000..6ec33f9 --- /dev/null +++ b/tdd_intro/cleanroom/chatclient/socketwrapper.h @@ -0,0 +1,35 @@ +#pragma once +#include +#include +#include + +class ISocketWrapper; +using ISocketWrapperPtr = std::shared_ptr; + +class ISocketWrapper +{ +public: + virtual void Bind(const std::string& addr, int16_t port) = 0; + virtual void Listen()= 0; + virtual ISocketWrapperPtr Accept() = 0; + virtual ISocketWrapperPtr Connect(const std::string& addr, int16_t port)= 0; + virtual void Read(std::string& buffer)= 0; + virtual void Write(const std::string& buffer)= 0; +}; + +class SocketWrapper : public ISocketWrapper +{ +public: + SocketWrapper(); + explicit SocketWrapper(SOCKET& other); + ~SocketWrapper(); + void Bind(const std::string& addr, int16_t port); + void Listen(); + ISocketWrapperPtr Accept(); + ISocketWrapperPtr Connect(const std::string& addr, int16_t port); + void Read(std::string& buffer); + void Write(const std::string& buffer); + +private: + SOCKET m_socket; +}; diff --git a/tdd_intro/cleanroom/chatclient/test.cpp b/tdd_intro/cleanroom/chatclient/test.cpp index 5d0332e..cad5e8d 100644 --- a/tdd_intro/cleanroom/chatclient/test.cpp +++ b/tdd_intro/cleanroom/chatclient/test.cpp @@ -1,5 +1,6 @@ #include #include +#include "socketwrapper.h" using namespace testing; /* @@ -38,3 +39,83 @@ Implement chat application, that communicates via TCP sockets. * If user enters '!exit!' message, application must close connection and exit * If user runs app with 'me' nickname - error with text "Username me is reserved and can not be used" is displayed and application exits */ + +class MockSocketWrapper : public ISocketWrapper +{ +public: + MOCK_METHOD2(Bind, void(const std::string& addr, int16_t port)); + MOCK_METHOD0(Listen, void()); + MOCK_METHOD0(Accept, ISocketWrapperPtr()); + MOCK_METHOD2(Connect, ISocketWrapperPtr(const std::string& addr, int16_t port)); + MOCK_METHOD1(Read, void(std::string& buffer)); + MOCK_METHOD1(Write, void(const std::string& buffer)); + +}; + +class Channel +{ +public: + explicit Channel(ISocketWrapper& wrapper): m_wrapper(wrapper) {} + void Send(const std::string& message) { m_wrapper.Write(message);} + void Receive(std::string& message) { m_wrapper.Read(message);} + +private: + ISocketWrapper& m_wrapper; +}; + +void ClientHandshake(Channel& channel, const std::string& login) +{ + std::string buffer; + channel.Send(login + ":HELLO"); + channel.Receive(buffer); + +} + +void ServerHandshake(Channel& channel, const std::string& login) +{ + std::string buffer; + channel.Receive(buffer); + channel.Send(login + ":HELLO!"); +} + +TEST(SocketWrapperTest, Sending) +{ + MockSocketWrapper socket; + Channel channel(socket); + + EXPECT_CALL(socket, Write("Hello")).Times(1); + channel.Send("Hello"); +} + +TEST(SocketWrapperTest, Receiving) +{ + MockSocketWrapper socket; + Channel channel(socket); + + std::string buffer; + EXPECT_CALL(socket, Read(_)).WillOnce(SetArgReferee<0>("Hello")); + channel.Receive(buffer); + + EXPECT_EQ("Hello", buffer); +} + +TEST(SocketWrapperTest, ClientHandshake) +{ + MockSocketWrapper socket; + Channel channel(socket); + InSequence sequence; + EXPECT_CALL(socket, Write("metizik:HELLO")).Times(1); + EXPECT_CALL(socket, Read(_)).Times(1); + ClientHandshake(channel, "metizik"); +} + +TEST(SocketWrapperTest, ServerHandshake) +{ + MockSocketWrapper socket; + Channel channel(socket); + EXPECT_CALL(socket, Read(_)).Times(1); + EXPECT_CALL(socket, Write("user:HELLO!")).Times(1); + ServerHandshake(channel, "user"); +} + + diff --git a/tdd_intro/homework/06_bank_ocr/06_bank_ocr.pro b/tdd_intro/homework/05_bank_ocr/05_bank_ocr.pro similarity index 100% rename from tdd_intro/homework/06_bank_ocr/06_bank_ocr.pro rename to tdd_intro/homework/05_bank_ocr/05_bank_ocr.pro diff --git a/tdd_intro/homework/05_bank_ocr/test.cpp b/tdd_intro/homework/05_bank_ocr/test.cpp new file mode 100644 index 0000000..e7852dc --- /dev/null +++ b/tdd_intro/homework/05_bank_ocr/test.cpp @@ -0,0 +1,187 @@ +/*### Bank OCR + +Your manager has recently purchased a machine that assists in reading letters and faxes sent in by branch offices. The machine scans the paper documents, and produces a file with a number of entries. You will write a program to parse this file. + +#### Specification +#### User Story 1 + +The following format is created by the machine: +``` + _ _ _ _ _ _ _ + | _| _||_||_ |_ ||_||_| + ||_ _| | _||_| ||_| _| +``` +Each entry is 3 lines long, and each line has 27 characters. 3 lines of each entry contain an account number written using pipes and underscores. + +Each account number should have 9 digits, all of which should be in the range 0-9. A normal file contains around 500 entries. + +Write a program that can take this file and parse it into actual account numbers. + +Example input and output +``` + _ _ _ _ _ _ _ _ _ +| || || || || || || || || | +|_||_||_||_||_||_||_||_||_| + +=> 000000000 + + | | | | | | | | | + | | | | | | | | | + +=> 111111111 + + _ _ _ _ _ _ _ _ _ + _| _| _| _| _| _| _| _| _| +|_ |_ |_ |_ |_ |_ |_ |_ |_ + +=> 222222222 + + _ _ _ _ _ _ _ _ _ + _| _| _| _| _| _| _| _| _| + _| _| _| _| _| _| _| _| _| + +=> 333333333 + +|_||_||_||_||_||_||_||_||_| + | | | | | | | | | + +=> 444444444 + + _ _ _ _ _ _ _ _ _ +|_ |_ |_ |_ |_ |_ |_ |_ |_ + _| _| _| _| _| _| _| _| _| + +=> 555555555 + + _ _ _ _ _ _ _ _ _ +|_ |_ |_ |_ |_ |_ |_ |_ |_ +|_||_||_||_||_||_||_||_||_| + +=> 666666666 + + _ _ _ _ _ _ _ _ _ + | | | | | | | | | + | | | | | | | | | + +=> 777777777 + + _ _ _ _ _ _ _ _ _ +|_||_||_||_||_||_||_||_||_| +|_||_||_||_||_||_||_||_||_| + +=> 888888888 + + _ _ _ _ _ _ _ _ _ +|_||_||_||_||_||_||_||_||_| + _| _| _| _| _| _| _| _| _| + +=> 999999999 + + _ _ _ _ _ _ _ + | _| _||_||_ |_ ||_||_| + ||_ _| | _||_| ||_| _| + +=> 123456789 +``` +*/ +#include + +// check matrix for one digit 3x3 +// parse one digit + // - parse 1 + // - parse 2 + // - parse 0-9 + // - check invalid one digit +// parse several digits (27x3) +// parse 27x3 (9 digits) + // - check matrix 27x3 + // - parse +// parse several lines + +using Digit = std::vector; + +const Digit s_1({" ", + " |", + " |"}); + +const Digit s_2({" _ ", + " _|", + "|_ "}); + +std::vector s_digits({ + +}); + +bool CheckMatrixDimension(const Digit& digit) +{ + const size_t prefferedSize = 3; + + if (digit.size() != prefferedSize) + { + return false; + } + + for (const std::string& line : digit) + { + if (line.size() != prefferedSize) + { + return false; + } + } + + return true; +} + +std::string ParseDigit(const Digit& digit) +{ + if (digit == Digit({" ", + " |", + " |"})) + { + return "1"; + } + else if (digit == Digit({" _ ", + " _|", + "|_ "})) + { + return "2"; + } + + return "8"; +} + +TEST(BankOCRTests, Check_Matrix_dimension_true) +{ + Digit digit = {" ", " ", " "}; + EXPECT_TRUE(CheckMatrixDimension(digit)); +} + +TEST(BankOCRTests, Check_Matrix_dimension_false) +{ + Digit digit = {" ", "! ", " "}; + EXPECT_FALSE(CheckMatrixDimension(digit)); +} + +TEST(BankOCRTests, ParseDigit_1) +{ + Digit digit = {" ", + " |", + " |"}; + EXPECT_EQ("1", ParseDigit(digit)); +} + +TEST(BankOCRTests, ParseDigit_2) +{ + Digit digit = {" _ ", + " _|", + "|_ "}; + EXPECT_EQ("2", ParseDigit(digit)); +} + +TEST(BankOCRTests, ParseDigit_8) +{ + Digit digit = {" _ ", + "|_|", + "|_|"}; + EXPECT_EQ("8", ParseDigit(digit)); +} diff --git a/tdd_intro/homework/05_word_wrapp/test.cpp b/tdd_intro/homework/05_word_wrapp/test.cpp index f29c0fa..bdba21b 100644 --- a/tdd_intro/homework/05_word_wrapp/test.cpp +++ b/tdd_intro/homework/05_word_wrapp/test.cpp @@ -5,4 +5,84 @@ last space should be used to wrapp this line. If there are no spaces - wrapp it */ #include -#include +#include +#include +#include + +//List of tests: +// 1. Check zero string. +// 2. Check string splitting before limit +// 3. Check string splitting without spaces by limit. +// 4. Check string splitting with one space in the end. +// 5. Check string splitting with one space at start. +// 6. Check string splitting with multiple spaces at start. +// 7. Check string splitting with multiple spaces in the end of string. + +namespace +{ + using StringList = std::list; + + StringList wrapp(const std::string& str, size_t limit) + { + if (str.empty()) + { + return StringList{""}; + } + + StringList result; + std::string tmp; + size_t space_pos = 0; + const char DELIMITER = ' '; + size_t length = str.length(); + for (size_t startPos = 0; startPos < length;) + { + tmp = str.substr(startPos, limit); + space_pos = tmp.find_last_of(DELIMITER); + auto spaces_count = std::count(tmp.begin(), tmp.end(), DELIMITER); + if (spaces_count > 1 || tmp.back() == DELIMITER && space_pos != tmp.npos) + { + tmp = tmp.substr(0, space_pos); + startPos += tmp.length() + 1; + } + else + { + startPos += limit; + } + result.push_back(tmp); + } + return result; + } +} + + +TEST(WordWrapTests, TakeZeroString_GetZeroString) +{ + EXPECT_EQ(StringList{""}, wrapp("", 0)); +} + +TEST(WordWrapTests, TakeStringBeforeLimit_GetString) +{ + const std::string txt = "Hello world!"; + EXPECT_EQ(StringList({txt}), wrapp(txt, 30)); +} + +TEST(WordWrapTests, TakeStringUnderLimit_GetStringList) +{ + const std::string txt = "Hello!I_said_hello!_Hey!"; + StringList res = {"Hello!I_sa", "id_hello!_", "Hey!"}; + EXPECT_EQ(res, wrapp(txt, 10)); +} + +TEST(WordWrapTests, TakeStringUnderLimitWithSpaces_GetSplittedString) +{ + const std::string txt = "Hello Man! Money!Monkey!Mikki!"; + StringList res = {"Hello Man!", "Money!Monkey!", "Mikki!"}; + EXPECT_EQ(res, wrapp(txt, 13)); +} + +TEST(WordWrapTests, TakeNumberStringWithSpaces_GetRightSplitted) +{ + const std::string txt = "12345 6 123456789 123456789"; + StringList res = {"12345", "6 1234", "56789", "123456", "789"}; + EXPECT_EQ(res, wrapp(txt, 6)); +} diff --git a/tdd_intro/workshops/03_anagram/03_anagram.pro b/tdd_intro/homework/06_allergies/06_allergies.pro similarity index 100% rename from tdd_intro/workshops/03_anagram/03_anagram.pro rename to tdd_intro/homework/06_allergies/06_allergies.pro diff --git a/tdd_intro/homework/06_allergies/test.cpp b/tdd_intro/homework/06_allergies/test.cpp new file mode 100644 index 0000000..c6c6ce3 --- /dev/null +++ b/tdd_intro/homework/06_allergies/test.cpp @@ -0,0 +1,25 @@ +/* +Given a person's allergy score, determine whether or not they're allergic to a given item, and their full list of allergies. +An allergy test produces a single numeric score which contains the information about all the allergies the person has (that they were tested for). +The list of items (and their value) that were tested are: + eggs (1) + peanuts (2) + shellfish (4) + strawberries (8) + tomatoes (16) + chocolate (32) + pollen (64) + cats (128) +So if Tom is allergic to peanuts and chocolate, he gets a score of 34. + +Now, given just that score of 34, your program should be able: + To say have Tom allergic to specific product or not. + To give list of all allergens Tom is allergic to. + +E.g. it can be class with methods IsAllergicTo(string), List() and receiving allergyScore in constructor + +Note: a given score may include allergens not listed above (i.e. allergens that score 256, 512, 1024, etc.). +Your program should ignore those components of the score. +For example, if the allergy score is 257, your program should only report the eggs (1) allergy. +*/ +#include diff --git a/tdd_intro/homework/06_bank_ocr/test.cpp b/tdd_intro/homework/06_bank_ocr/test.cpp deleted file mode 100644 index a4dfe1f..0000000 --- a/tdd_intro/homework/06_bank_ocr/test.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/*### Bank OCR - -Your manager has recently purchased a machine that assists in reading letters and faxes sent in by branch offices. The machine scans the paper documents, and produces a file with a number of entries. You will write a program to parse this file. - -#### Specification -#### User Story 1 - -The following format is created by the machine: -``` - _ _ _ _ _ _ _ - | _| _||_||_ |_ ||_||_| - ||_ _| | _||_| ||_| _| -``` -Each entry is 3 lines long, and each line has 27 characters. 3 lines of each entry contain an account number written using pipes and underscores. - -Each account number should have 9 digits, all of which should be in the range 0-9. A normal file contains around 500 entries. - -Write a program that can take this file and parse it into actual account numbers. - -Example input and output -``` - _ _ _ _ _ _ _ _ _ -| || || || || || || || || | -|_||_||_||_||_||_||_||_||_| - -=> 000000000 - - | | | | | | | | | - | | | | | | | | | - -=> 111111111 - - _ _ _ _ _ _ _ _ _ - _| _| _| _| _| _| _| _| _| -|_ |_ |_ |_ |_ |_ |_ |_ |_ - -=> 222222222 - - _ _ _ _ _ _ _ _ _ - _| _| _| _| _| _| _| _| _| - _| _| _| _| _| _| _| _| _| - -=> 333333333 - -|_||_||_||_||_||_||_||_||_| - | | | | | | | | | - -=> 444444444 - - _ _ _ _ _ _ _ _ _ -|_ |_ |_ |_ |_ |_ |_ |_ |_ - _| _| _| _| _| _| _| _| _| - -=> 555555555 - - _ _ _ _ _ _ _ _ _ -|_ |_ |_ |_ |_ |_ |_ |_ |_ -|_||_||_||_||_||_||_||_||_| - -=> 666666666 - - _ _ _ _ _ _ _ _ _ - | | | | | | | | | - | | | | | | | | | - -=> 777777777 - - _ _ _ _ _ _ _ _ _ -|_||_||_||_||_||_||_||_||_| -|_||_||_||_||_||_||_||_||_| - -=> 888888888 - - _ _ _ _ _ _ _ _ _ -|_||_||_||_||_||_||_||_||_| - _| _| _| _| _| _| _| _| _| - -=> 999999999 - - _ _ _ _ _ _ _ - | _| _||_||_ |_ ||_||_| - ||_ _| | _||_| ||_| _| - -=> 123456789 -``` -*/ -#include - diff --git a/tdd_intro/homework/README.MD b/tdd_intro/homework/README.MD index 7457706..fc7a47c 100644 --- a/tdd_intro/homework/README.MD +++ b/tdd_intro/homework/README.MD @@ -86,6 +86,29 @@ It should be wrapped by length of 30 into this sequence of lines (ommiting quote If your language provides a method in the standard library to perform the conversion, pretend it doesn't exist and implement it yourself. +### Allergies + +Given a person's allergy score, determine whether or not they're allergic to a given item, and their full list of allergies. +An allergy test produces a single numeric score which contains the information about all the allergies the person has (that they were tested for). +The list of items (and their value) that were tested are: + eggs (1) + peanuts (2) + shellfish (4) + strawberries (8) + tomatoes (16) + chocolate (32) + pollen (64) + cats (128) +So if Tom is allergic to peanuts and chocolate, he gets a score of 34. + +Now, given just that score of 34, your program should be able: +1. To say have Tom allergic to specific product or not. +2. To give list of all allergens Tom is allergic to. + +Note: a given score may include allergens not listed above (i.e. allergens that score 256, 512, 1024, etc.). Your program should ignore those components of the score. For example, if the allergy score is 257, your program should only report the eggs (1) allergy. + +_from http://exercism.io/_ + ## Functionality decomposition training: ### Bank OCR diff --git a/tdd_intro/homework/homework.pro b/tdd_intro/homework/homework.pro index dd4d892..a20ef88 100644 --- a/tdd_intro/homework/homework.pro +++ b/tdd_intro/homework/homework.pro @@ -3,9 +3,9 @@ TEMPLATE = subdirs SUBDIRS += \ 01_bob \ 02_leap_year \ - 03_anagram \ 04_trinary_numbers \ 05_word_wrapp \ - 06_bank_ocr \ + 05_bank_ocr \ + 06_allergies \ 07_filecopier \ 08_timer diff --git a/tdd_intro/tdd_intro.pro.user b/tdd_intro/tdd_intro.pro.user index a2f1674..ef80ac5 100644 --- a/tdd_intro/tdd_intro.pro.user +++ b/tdd_intro/tdd_intro.pro.user @@ -1,10 +1,10 @@ - + EnvironmentId - {a9e7f687-ac9f-466e-a5b0-c81b575a0a1d} + {3ef9886a-cbcd-4fe0-9b84-ff1ef2e5e4f3} ProjectExplorer.Project.ActiveTarget @@ -30,7 +30,7 @@ 2 UTF-8 - true + false 4 false 80 @@ -45,11 +45,11 @@ 0 8 true - 1 + 2 true true true - false + true @@ -59,14 +59,14 @@ ProjectExplorer.Project.Target.0 - Qt 5.7.0 (windows) - Qt 5.7.0 (windows) - {bb54e87c-a17e-4f34-bfa2-da2794ff8a10} + MSVC2013 + MSVC2013 + {6bc13111-c0a0-4966-8096-5a3b0fa4dd67} 0 0 - 11 + 0 - D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug + G:/tdd-course-2/build-tdd_intro-MSVC2013-Debug true @@ -120,7 +120,7 @@ true - D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Release + G:/tdd-course-2/build-tdd_intro-MSVC2013-Release true @@ -174,7 +174,7 @@ true - D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Profile + G:/tdd-course-2/build-tdd_intro-MSVC2013-Profile true @@ -286,13 +286,13 @@ chatclient - Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/cleanroom/chatclient/chatclient.pro + Qt4ProjectManager.Qt4RunConfiguration:G:/tdd-course-2/tdd_intro/cleanroom/chatclient/chatclient.pro true cleanroom/chatclient/chatclient.pro false - D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/cleanroom/chatclient + 3768 false true @@ -344,13 +344,13 @@ 01_bob - Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/homework/01_bob/01_bob.pro + Qt4ProjectManager.Qt4RunConfiguration:G:/tdd-course-2/tdd_intro/homework/01_bob/01_bob.pro true homework/01_bob/01_bob.pro false - D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/homework/01_bob + 3768 false true @@ -400,15 +400,15 @@ 2 - 02_word_count + 01_fizz_buzz - Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/workshops/02_word_count/02_word_count.pro + Qt4ProjectManager.Qt4RunConfiguration:G:/tdd-course-2/tdd_intro/workshops/01_fizz_buzz/01_fizz_buzz.pro true - workshops/02_word_count/02_word_count.pro + workshops/01_fizz_buzz/01_fizz_buzz.pro false - D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/workshops/02_word_count + 3768 false true @@ -458,15 +458,15 @@ 2 - 03_anagram - 03_anagram2 - Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/workshops/03_anagram/03_anagram.pro + 02_word_count + + Qt4ProjectManager.Qt4RunConfiguration:G:/tdd-course-2/tdd_intro/workshops/02_word_count/02_word_count.pro true - workshops/03_anagram/03_anagram.pro + workshops/02_word_count/02_word_count.pro false - D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/workshops/03_anagram + 3768 false true @@ -516,15 +516,15 @@ 2 - 04_trinary_numbers - 04_trinary_numbers2 - Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/workshops/04_trinary_numbers/04_trinary_numbers.pro + 03_armstrong_number + + Qt4ProjectManager.Qt4RunConfiguration:G:/tdd-course-2/tdd_intro/workshops/03_armstrong_number/03_armstrong_number.pro true - workshops/04_trinary_numbers/04_trinary_numbers.pro + workshops/03_armstrong_number/03_armstrong_number.pro false - D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/workshops/04_trinary_numbers + 3768 false true @@ -533,6 +533,122 @@ true + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + 04_roman_numerals + + Qt4ProjectManager.Qt4RunConfiguration:G:/tdd-course-2/tdd_intro/workshops/04_roman_numerals/04_roman_numerals.pro + true + + workshops/04_roman_numerals/04_roman_numerals.pro + false + + + 3768 + false + true + false + false + true + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + 05_bank_ocr + 05_bank_ocr2 + Qt4ProjectManager.Qt4RunConfiguration:G:/tdd-course-2/tdd_intro/workshops/05_bank_ocr/05_bank_ocr.pro + true + + workshops/05_bank_ocr/05_bank_ocr.pro + false + + + 3768 + false + true + false + false + true + + false false 1000 @@ -576,13 +692,71 @@ 05_word_wrapp 05_word_wrapp2 - Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/workshops/05_word_wrapp/05_word_wrapp.pro + Qt4ProjectManager.Qt4RunConfiguration:G:/tdd-course-2/tdd_intro/workshops/05_word_wrapp/05_word_wrapp.pro true workshops/05_word_wrapp/05_word_wrapp.pro false - D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/workshops/05_word_wrapp + + 3768 + false + true + false + false + true + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + 07_coffee + + Qt4ProjectManager.Qt4RunConfiguration:G:/tdd-course-2/tdd_intro/workshops/07_coffee/07_coffee.pro + true + + workshops/07_coffee/07_coffee.pro + false + + 3768 false true @@ -634,13 +808,13 @@ 02_leap_year - Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/homework/02_leap_year/02_leap_year.pro + Qt4ProjectManager.Qt4RunConfiguration:G:/tdd-course-2/tdd_intro/homework/02_leap_year/02_leap_year.pro true homework/02_leap_year/02_leap_year.pro false - D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/homework/02_leap_year + 3768 false true @@ -692,13 +866,13 @@ 03_anagram - Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/homework/03_anagram/03_anagram.pro + Qt4ProjectManager.Qt4RunConfiguration:G:/tdd-course-2/tdd_intro/homework/03_anagram/03_anagram.pro true homework/03_anagram/03_anagram.pro false - D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/homework/03_anagram + 3768 false true @@ -750,13 +924,13 @@ 04_trinary_numbers - Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/homework/04_trinary_numbers/04_trinary_numbers.pro + Qt4ProjectManager.Qt4RunConfiguration:G:/tdd-course-2/tdd_intro/homework/04_trinary_numbers/04_trinary_numbers.pro true homework/04_trinary_numbers/04_trinary_numbers.pro false - D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/homework/04_trinary_numbers + 3768 false true @@ -806,15 +980,15 @@ 2 - 05_word_wrapp + 05_bank_ocr - Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/homework/05_word_wrapp/05_word_wrapp.pro + Qt4ProjectManager.Qt4RunConfiguration:G:/tdd-course-2/tdd_intro/homework/05_bank_ocr/05_bank_ocr.pro true - homework/05_word_wrapp/05_word_wrapp.pro + homework/05_bank_ocr/05_bank_ocr.pro false - D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/homework/05_word_wrapp + 3768 false true @@ -864,15 +1038,15 @@ 2 - 06_bank_ocr + 05_word_wrapp - Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/homework/06_bank_ocr/06_bank_ocr.pro + Qt4ProjectManager.Qt4RunConfiguration:G:/tdd-course-2/tdd_intro/homework/05_word_wrapp/05_word_wrapp.pro true - homework/06_bank_ocr/06_bank_ocr.pro + homework/05_word_wrapp/05_word_wrapp.pro false - D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/homework/06_bank_ocr + 3768 false true @@ -922,15 +1096,15 @@ 2 - 07_filecopier + 06_allergies - Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/homework/07_filecopier/07_filecopier.pro + Qt4ProjectManager.Qt4RunConfiguration:G:/tdd-course-2/tdd_intro/homework/06_allergies/06_allergies.pro true - homework/07_filecopier/07_filecopier.pro + homework/06_allergies/06_allergies.pro false - D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/homework/07_filecopier + 3768 false true @@ -980,15 +1154,15 @@ 2 - 08_timer + 07_filecopier - Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/homework/08_timer/08_timer.pro + Qt4ProjectManager.Qt4RunConfiguration:G:/tdd-course-2/tdd_intro/homework/07_filecopier/07_filecopier.pro true - homework/08_timer/08_timer.pro + homework/07_filecopier/07_filecopier.pro false - D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/homework/08_timer + 3768 false true @@ -1038,15 +1212,15 @@ 2 - 01_fizz_buzz + 08_timer - Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/workshops/01_fizz_buzz/01_fizz_buzz.pro + Qt4ProjectManager.Qt4RunConfiguration:G:/tdd-course-2/tdd_intro/homework/08_timer/08_timer.pro true - workshops/01_fizz_buzz/01_fizz_buzz.pro + homework/08_timer/08_timer.pro false - D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/workshops/01_fizz_buzz + 3768 false true @@ -1054,7 +1228,7 @@ false true - 14 + 17 diff --git a/tdd_intro/tdd_intro.pro.user.a9e7f68 b/tdd_intro/tdd_intro.pro.user.a9e7f68 new file mode 100644 index 0000000..d2e0159 --- /dev/null +++ b/tdd_intro/tdd_intro.pro.user.a9e7f68 @@ -0,0 +1,1072 @@ + + + + + + EnvironmentId + {a9e7f687-ac9f-466e-a5b0-c81b575a0a1d} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + true + 4 + false + 80 + true + false + 1 + true + false + 0 + true + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + + ProjectExplorer.Project.Target.0 + + Qt 5.7.0 (windows) + Qt 5.7.0 (windows) + {bb54e87c-a17e-4f34-bfa2-da2794ff8a10} + 0 + 0 + 13 + + D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + + D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Profile + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + true + false + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 3 + + + 0 + Deploy + + ProjectExplorer.BuildSteps.Deploy + + 1 + Deploy locally + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + chatclient + + Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/cleanroom/chatclient/chatclient.pro + true + + cleanroom/chatclient/chatclient.pro + false + + D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/cleanroom/chatclient + 3768 + false + true + false + false + true + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + 01_bob + + Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/homework/01_bob/01_bob.pro + true + + homework/01_bob/01_bob.pro + false + + D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/homework/01_bob + 3768 + false + true + false + false + true + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + 02_word_count + + Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/workshops/02_word_count/02_word_count.pro + true + + workshops/02_word_count/02_word_count.pro + false + + D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/workshops/02_word_count + 3768 + false + true + false + false + true + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + 05_word_wrapp + 05_word_wrapp2 + Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/workshops/05_word_wrapp/05_word_wrapp.pro + true + + workshops/05_word_wrapp/05_word_wrapp.pro + false + + D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/workshops/05_word_wrapp + 3768 + false + true + false + false + true + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + 03_armstrong_number + + Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/workshops/03_armstrong_number/03_armstrong_number.pro + true + + workshops/03_armstrong_number/03_armstrong_number.pro + false + + D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/workshops/03_armstrong_number + 3768 + false + true + false + false + true + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + 04_roman_numerals + + Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/workshops/04_roman_numerals/04_roman_numerals.pro + true + + workshops/04_roman_numerals/04_roman_numerals.pro + false + + D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/workshops/04_roman_numerals + 3768 + false + true + false + false + true + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + 02_leap_year + + Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/homework/02_leap_year/02_leap_year.pro + true + + homework/02_leap_year/02_leap_year.pro + false + + D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/homework/02_leap_year + 3768 + false + true + false + false + true + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + 03_anagram + + Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/homework/03_anagram/03_anagram.pro + true + + homework/03_anagram/03_anagram.pro + false + + D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/homework/03_anagram + 3768 + false + true + false + false + true + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + 04_trinary_numbers + + Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/homework/04_trinary_numbers/04_trinary_numbers.pro + true + + homework/04_trinary_numbers/04_trinary_numbers.pro + false + + D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/homework/04_trinary_numbers + 3768 + false + true + false + false + true + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + 05_word_wrapp + + Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/homework/05_word_wrapp/05_word_wrapp.pro + true + + homework/05_word_wrapp/05_word_wrapp.pro + false + + D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/homework/05_word_wrapp + 3768 + false + true + false + false + true + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + 06_bank_ocr + + Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/homework/06_bank_ocr/06_bank_ocr.pro + true + + homework/06_bank_ocr/06_bank_ocr.pro + false + + D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/homework/06_bank_ocr + 3768 + false + true + false + false + true + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + 07_filecopier + + Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/homework/07_filecopier/07_filecopier.pro + true + + homework/07_filecopier/07_filecopier.pro + false + + D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/homework/07_filecopier + 3768 + false + true + false + false + true + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + 08_timer + + Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/homework/08_timer/08_timer.pro + true + + homework/08_timer/08_timer.pro + false + + D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/homework/08_timer + 3768 + false + true + false + false + true + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + 01_fizz_buzz + + Qt4ProjectManager.Qt4RunConfiguration:D:/Study/tdd-course-2/tdd_intro/workshops/01_fizz_buzz/01_fizz_buzz.pro + true + + workshops/01_fizz_buzz/01_fizz_buzz.pro + false + + D:/Study/tdd-course-2/build-tdd_intro-Qt_5_7_0_windows-Debug/workshops/01_fizz_buzz + 3768 + false + true + false + false + true + + 14 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 18 + + + Version + 18 + + diff --git a/tdd_intro/workshops/02_word_count/test.cpp b/tdd_intro/workshops/02_word_count/test.cpp index 82612fe..572b8a2 100644 --- a/tdd_intro/workshops/02_word_count/test.cpp +++ b/tdd_intro/workshops/02_word_count/test.cpp @@ -12,3 +12,117 @@ free: 1 #include #include +#include +#include + +using MyMap = std::map; + +MyMap WordsCount(const std::string& str) +{ + if (str.empty()) + { + return {}; + } + + MyMap result; + + std::istringstream f(str); + std::string s; + + while(std::getline(f, s, ' ')) + { + if (!s.empty()) + { + ++result[s]; + } + } + + + return result; +} + + +TEST(WordsCountTests, TakeEmptyString_ReturnEmptyMap) +{ + EXPECT_EQ(MyMap(), WordsCount("")); +} + +TEST(WordsCountTests, TakeOneWord_ReturnOneOccurForThisWord) +{ + const std::string word = "Word"; + MyMap myMap; + myMap[word] = 1; + EXPECT_EQ(myMap, WordsCount(word)); +} + +TEST(WordsCountTests, TakeOneWord_Hello_ReturnOneOccurForThisWord) +{ + const std::string word = "Hello"; + MyMap myMap; + myMap[word] = 1; + EXPECT_EQ(myMap, WordsCount(word)); +} + +TEST(WordsCountTests, TakeOneWithSpaceInTheEnd_ReturnOneOccur) +{ + const std::string word = "word "; + MyMap myMap; + myMap["word"] = 1; + EXPECT_EQ(myMap, WordsCount(word)); +} + +TEST(WordsCountTests, TakeOneWithSpace_ReturnOneOccur) +{ + const std::string word = " word"; + MyMap myMap; + myMap["word"] = 1; + EXPECT_EQ(myMap, WordsCount(word)); +} + +TEST(WordsCountTests, TakeTwoDiffWords_ReturnOneOccurForEach) +{ + const std::string word = "Hello word"; + MyMap myMap; + myMap["word"] = 1; + myMap["Hello"] = 1; + EXPECT_EQ(myMap, WordsCount(word)); +} + +TEST(WordsCountTests, TakeALotOfDifferentWords_ReturnOneOccurForEach) +{ + const std::string word = "qwerty qwerty1 qwerty2 qwerty3 qwerty4 qwerty5"; + EXPECT_EQ(1, WordsCount(word).at("qwerty")); + EXPECT_EQ(1, WordsCount(word).at("qwerty1")); + EXPECT_EQ(1, WordsCount(word).at("qwerty2")); + EXPECT_EQ(1, WordsCount(word).at("qwerty3")); + EXPECT_EQ(1, WordsCount(word).at("qwerty4")); + EXPECT_EQ(1, WordsCount(word).at("qwerty5")); +} + +TEST(WordsCountTests, TakeTwoEqualWords_ReturnTwoOccurForIt) +{ + const std::string phrase = "qwerty qwerty"; + MyMap myMap; + myMap["qwerty"] = 2; + EXPECT_EQ(myMap, WordsCount(phrase)); +} + +TEST(WordsCountTests, AcceptanceTest) +{ + const std::string phrase = "olly olly in come free"; + MyMap myMap; + myMap["olly"] = 2; + myMap["in"] = 1; + myMap["come"] = 1; + myMap["free"] = 1; + + EXPECT_EQ(myMap, WordsCount(phrase)); +} + +TEST(WordsCountTests, TakeTwoWordsWithManuSpaces_ReturnTwoOccurForIt) +{ + const std::string phrase = " qwerty qwerty "; + MyMap myMap; + myMap["qwerty"] = 2; + EXPECT_EQ(myMap, WordsCount(phrase)); +} diff --git a/tdd_intro/workshops/03_anagram/test.cpp b/tdd_intro/workshops/03_anagram/test.cpp deleted file mode 100644 index 2fea6eb..0000000 --- a/tdd_intro/workshops/03_anagram/test.cpp +++ /dev/null @@ -1,8 +0,0 @@ -/* -Given a word and a list of possible anagrams, select the correct sublist. - -Given "listen" and a list of candidates like "enlists" "google" "inlets" "banana" the program should return a list containing "inlets". - -_from http://exercism.io/_ -*/ -#include \ No newline at end of file diff --git a/tdd_intro/workshops/04_trinary_numbers/04_trinary_numbers.pro b/tdd_intro/workshops/03_armstrong_number/03_armstrong_number.pro similarity index 100% rename from tdd_intro/workshops/04_trinary_numbers/04_trinary_numbers.pro rename to tdd_intro/workshops/03_armstrong_number/03_armstrong_number.pro diff --git a/tdd_intro/workshops/03_armstrong_number/test.cpp b/tdd_intro/workshops/03_armstrong_number/test.cpp new file mode 100644 index 0000000..78a9291 --- /dev/null +++ b/tdd_intro/workshops/03_armstrong_number/test.cpp @@ -0,0 +1,134 @@ +/* +An Armstrong number is a number that is the sum of its own digits each raised to the power of the number of digits. + +For example: + +9 is an Armstrong number, because 9 = 9^1 = 9 +10 is not an Armstrong number, because 10 != 1^2 + 0^2 = 1 +153 is an Armstrong number, because: 153 = 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153 +154 is not an Armstrong number, because: 154 != 1^3 + 5^3 + 4^3 = 1 + 125 + 64 = 190 +9474 is an Armstrong number + +Write some code to determine whether a number is an Armstrong number. + +Acceptance test +5 - true +100 - false +9475 - false +9926315 - true +9926314 - false + +_from http://exercism.io/_ +*/ +#include +#include + +using Digits = std::multiset; + +Digits GetDidgitList(unsigned int num) +{ + Digits res; + + if (num == 0) + { + res.insert(0); + } + + while (num > 0) + { + res.insert(num % 10); + num /= 10; + } + + return res; +} + +bool IsArmstrongNumber(unsigned int num) +{ + Digits digits = GetDidgitList(num); + unsigned int sum = 0; + size_t digits_size = digits.size(); + + for (auto digit : digits) + { + sum += static_cast(std::pow(digit, digits_size )); + } + + return num == sum; +} + +TEST(IsArmstrongNumberTest, Input_9_Return_True) +{ + EXPECT_TRUE(IsArmstrongNumber(9)); +} + +TEST(IsArmstrongNumberTest, Input_10_Return_False) +{ + EXPECT_FALSE(IsArmstrongNumber(10)); +} + +TEST(IsArmstrongNumberTest, Input_7_Return_True) +{ + EXPECT_TRUE(IsArmstrongNumber(7)); +} + +TEST(IsArmstrongNumberTest, Input_153_Return_True) +{ + EXPECT_TRUE(IsArmstrongNumber(153)); +} + +TEST(IsArmstrongNumberTest, Input_370_Return_True) +{ + EXPECT_TRUE(IsArmstrongNumber(370)); +} + +TEST(IsArmstrongNumberTest, Input_1634_Return_True) +{ + EXPECT_TRUE(IsArmstrongNumber(1634)); +} + +TEST(IsArmstrongNumberTest, Input_9926315_Return_True) +{ + EXPECT_TRUE(IsArmstrongNumber(9926315)); +} + +TEST(IsArmstrongNumberTest, Input_9926314_Return_False) +{ + EXPECT_FALSE(IsArmstrongNumber(9926314)); +} + +TEST(IsArmstrongNumberTest, AcceptanceTest) +{ + EXPECT_TRUE(IsArmstrongNumber(5)); + EXPECT_TRUE(IsArmstrongNumber(9926315)); + EXPECT_FALSE(IsArmstrongNumber(100)); + EXPECT_FALSE(IsArmstrongNumber(9475)); + EXPECT_FALSE(IsArmstrongNumber(9926314)); +} + +TEST(GetDidgitListTest, Input_0) +{ + Digits res; + res.insert(0); + EXPECT_EQ(res, GetDidgitList(0)); +} + +TEST(GetDidgitListTest, Input_35) +{ + Digits res; + res.insert(3); + res.insert(5); + EXPECT_EQ(res, GetDidgitList(35)); +} + +TEST(GetDidgitListTest, Input_945) +{ + Digits res; + res.insert(9); + res.insert(4); + res.insert(5); + EXPECT_EQ(res, GetDidgitList(945)); +} + + + diff --git a/tdd_intro/workshops/04_roman_numerals/04_roman_numerals.pro b/tdd_intro/workshops/04_roman_numerals/04_roman_numerals.pro new file mode 100644 index 0000000..c7fec38 --- /dev/null +++ b/tdd_intro/workshops/04_roman_numerals/04_roman_numerals.pro @@ -0,0 +1,9 @@ +include(../../gtest.pri) + +TEMPLATE = app +CONFIG += console c++11 +CONFIG -= app_bundle +CONFIG -= qt + +SOURCES += \ + test.cpp diff --git a/tdd_intro/workshops/04_roman_numerals/test.cpp b/tdd_intro/workshops/04_roman_numerals/test.cpp new file mode 100644 index 0000000..69756ab --- /dev/null +++ b/tdd_intro/workshops/04_roman_numerals/test.cpp @@ -0,0 +1,94 @@ +#include +#include +/* +Write a function to convert from normal numbers to Roman Numerals. + +The Romans wrote numbers using letters - I, V, X, L, C, D, M. (converter http://www.novaroma.org/via_romana/numbers.html) + +There is no need to be able to convert numbers larger than about 3000. (The Romans themselves didn't tend to go any higher) + +Wikipedia says: Modern Roman numerals ... are written by expressing each digit separately starting with the left most digit and skipping any digit with a value of zero. + +To see this in practice, consider the example of 1990. +In Roman numerals 1990 is MCMXC: +1000=M 900=CM 90=XC + +2008 is written as MMVIII: +2000=MM 8=VIII + +1998 is written as MCMXCVIII. +*/ + +std::string ConvertToRoman(unsigned short num) +{ + if(num == 10) + { + return std::string("X"); + } + else if (num == 0) + { + return std::string(); + } + + std::string result; + if (num / 5 > 0) + { + result = "V"; + num -= 5; + } + + if (num == 4) + { + result = "IV"; + } + else if (num == 9) + { + result = "IX"; + } + else + { + while (num--) + { + result += "I"; + } + } + return result; +} + +TEST(ConvertToRomanTest, insert_zero_return_empty_string) +{ + EXPECT_EQ("", ConvertToRoman(0)); +} + +TEST(ConvertToRomanTest, insert_one_return_I) +{ + EXPECT_EQ("I", ConvertToRoman(1)); +} + +TEST(ConvertToRomanTest, insert_2_return_II) +{ + EXPECT_EQ("II", ConvertToRoman(2)); +} + +TEST(ConvertToRomanTest, insert_5_return_V) +{ + EXPECT_EQ("V", ConvertToRoman(5)); +} + +TEST(ConvertToRomanTest, insert_4_return_IV) +{ + EXPECT_EQ("IV", ConvertToRoman(4)); +} + +TEST(ConvertToRomanTest, insert_10_return_X) +{ + EXPECT_EQ("X", ConvertToRoman(10)); +} + +TEST(ConvertToRomanTest, AcceptanceLess10) +{ + EXPECT_EQ("III", ConvertToRoman(3)); + EXPECT_EQ("VI", ConvertToRoman(6)); + EXPECT_EQ("VII", ConvertToRoman(7)); + EXPECT_EQ("VIII", ConvertToRoman(8)); +} diff --git a/tdd_intro/workshops/04_trinary_numbers/test.cpp b/tdd_intro/workshops/04_trinary_numbers/test.cpp deleted file mode 100644 index c35967c..0000000 --- a/tdd_intro/workshops/04_trinary_numbers/test.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include - -/* -Convert a trinary number, represented as a string (e.g. '102012'), to its decimal equivalent using first principles. - -The program should consider strings specifying an invalid trinary as the value 0. - -Trinary numbers contain three symbols: 0, 1, and 2. - -The last place in a trinary number is the 1's place. The second to last is the 3's place, the third to last is the 9's place, etc. - -# "102012" - 1 0 2 0 1 2 # the number -1*3^5 + 0*3^4 + 2*3^3 + 0*3^2 + 1*3^1 + 2*3^0 # the value - 243 + 0 + 54 + 0 + 3 + 2 = 302 - -If your language provides a method in the standard library to perform the conversion, pretend it doesn't exist and implement it yourself. -*/ diff --git a/tdd_intro/workshops/05_bank_ocr/05_bank_ocr.pro b/tdd_intro/workshops/05_bank_ocr/05_bank_ocr.pro new file mode 100644 index 0000000..c7fec38 --- /dev/null +++ b/tdd_intro/workshops/05_bank_ocr/05_bank_ocr.pro @@ -0,0 +1,9 @@ +include(../../gtest.pri) + +TEMPLATE = app +CONFIG += console c++11 +CONFIG -= app_bundle +CONFIG -= qt + +SOURCES += \ + test.cpp diff --git a/tdd_intro/workshops/05_bank_ocr/test.cpp b/tdd_intro/workshops/05_bank_ocr/test.cpp new file mode 100644 index 0000000..e7852dc --- /dev/null +++ b/tdd_intro/workshops/05_bank_ocr/test.cpp @@ -0,0 +1,187 @@ +/*### Bank OCR + +Your manager has recently purchased a machine that assists in reading letters and faxes sent in by branch offices. The machine scans the paper documents, and produces a file with a number of entries. You will write a program to parse this file. + +#### Specification +#### User Story 1 + +The following format is created by the machine: +``` + _ _ _ _ _ _ _ + | _| _||_||_ |_ ||_||_| + ||_ _| | _||_| ||_| _| +``` +Each entry is 3 lines long, and each line has 27 characters. 3 lines of each entry contain an account number written using pipes and underscores. + +Each account number should have 9 digits, all of which should be in the range 0-9. A normal file contains around 500 entries. + +Write a program that can take this file and parse it into actual account numbers. + +Example input and output +``` + _ _ _ _ _ _ _ _ _ +| || || || || || || || || | +|_||_||_||_||_||_||_||_||_| + +=> 000000000 + + | | | | | | | | | + | | | | | | | | | + +=> 111111111 + + _ _ _ _ _ _ _ _ _ + _| _| _| _| _| _| _| _| _| +|_ |_ |_ |_ |_ |_ |_ |_ |_ + +=> 222222222 + + _ _ _ _ _ _ _ _ _ + _| _| _| _| _| _| _| _| _| + _| _| _| _| _| _| _| _| _| + +=> 333333333 + +|_||_||_||_||_||_||_||_||_| + | | | | | | | | | + +=> 444444444 + + _ _ _ _ _ _ _ _ _ +|_ |_ |_ |_ |_ |_ |_ |_ |_ + _| _| _| _| _| _| _| _| _| + +=> 555555555 + + _ _ _ _ _ _ _ _ _ +|_ |_ |_ |_ |_ |_ |_ |_ |_ +|_||_||_||_||_||_||_||_||_| + +=> 666666666 + + _ _ _ _ _ _ _ _ _ + | | | | | | | | | + | | | | | | | | | + +=> 777777777 + + _ _ _ _ _ _ _ _ _ +|_||_||_||_||_||_||_||_||_| +|_||_||_||_||_||_||_||_||_| + +=> 888888888 + + _ _ _ _ _ _ _ _ _ +|_||_||_||_||_||_||_||_||_| + _| _| _| _| _| _| _| _| _| + +=> 999999999 + + _ _ _ _ _ _ _ + | _| _||_||_ |_ ||_||_| + ||_ _| | _||_| ||_| _| + +=> 123456789 +``` +*/ +#include + +// check matrix for one digit 3x3 +// parse one digit + // - parse 1 + // - parse 2 + // - parse 0-9 + // - check invalid one digit +// parse several digits (27x3) +// parse 27x3 (9 digits) + // - check matrix 27x3 + // - parse +// parse several lines + +using Digit = std::vector; + +const Digit s_1({" ", + " |", + " |"}); + +const Digit s_2({" _ ", + " _|", + "|_ "}); + +std::vector s_digits({ + +}); + +bool CheckMatrixDimension(const Digit& digit) +{ + const size_t prefferedSize = 3; + + if (digit.size() != prefferedSize) + { + return false; + } + + for (const std::string& line : digit) + { + if (line.size() != prefferedSize) + { + return false; + } + } + + return true; +} + +std::string ParseDigit(const Digit& digit) +{ + if (digit == Digit({" ", + " |", + " |"})) + { + return "1"; + } + else if (digit == Digit({" _ ", + " _|", + "|_ "})) + { + return "2"; + } + + return "8"; +} + +TEST(BankOCRTests, Check_Matrix_dimension_true) +{ + Digit digit = {" ", " ", " "}; + EXPECT_TRUE(CheckMatrixDimension(digit)); +} + +TEST(BankOCRTests, Check_Matrix_dimension_false) +{ + Digit digit = {" ", "! ", " "}; + EXPECT_FALSE(CheckMatrixDimension(digit)); +} + +TEST(BankOCRTests, ParseDigit_1) +{ + Digit digit = {" ", + " |", + " |"}; + EXPECT_EQ("1", ParseDigit(digit)); +} + +TEST(BankOCRTests, ParseDigit_2) +{ + Digit digit = {" _ ", + " _|", + "|_ "}; + EXPECT_EQ("2", ParseDigit(digit)); +} + +TEST(BankOCRTests, ParseDigit_8) +{ + Digit digit = {" _ ", + "|_|", + "|_|"}; + EXPECT_EQ("8", ParseDigit(digit)); +} diff --git a/tdd_intro/workshops/05_word_wrapp/test.cpp b/tdd_intro/workshops/05_word_wrapp/test.cpp index f29c0fa..7281e37 100644 --- a/tdd_intro/workshops/05_word_wrapp/test.cpp +++ b/tdd_intro/workshops/05_word_wrapp/test.cpp @@ -1,8 +1,89 @@ /* Write a function, that is given a string and a length limit, splits provided string into sequence of string, where length of each string is not more, than provided limit. If there are spaces under provided limit - -last space should be used to wrapp this line. If there are no spaces - wrapp it on provided length limit. +last space should be used to Wrappp this line. If there are no spaces - Wrappp it on provided length limit. + +When pos is specified, the search only includes sequences of characters that begin at or before position pos, ignoring any possible match beginning after pos. + +"When pos is specified, the", +"search only includes sequences", +"of characters that begin at or", +"before position pos, ignoring", +"any possible match beginning", +"after pos." */ #include #include +#include +//1. Empty test. +//2. Short word and big limit. +//3. Big word and short limit. +//4. Input string with all spaces. +//5. String with 2 words and space before limit. +//6. String with 2 words and space after limit. +//7. String with 2 words and space on limit. +//8. String with 2 words and several spaces before limit. +//9. String with words and different count of spaces. +//10. + +using Strings_vt = std::vector; +std::vector WordWrapp(std::string data, unsigned int limit) +{ + Strings_vt result; + if (data.empty()) + { + return result; + } + + for (int pos = 0; pos < data.size(); pos += limit) + { + + std::string word(data.substr(pos, limit)); + if (word != " ") + { + if (word.back() == ' ') + { + word.pop_back(); + } + result.push_back(word); + } + } + + return result; +} + +TEST(WordWrappTests, Put_empty_get_empty) +{ + EXPECT_EQ(Strings_vt{}, WordWrapp("", 5)); +} + +TEST(WordWrappTests, Put_ShortWord_with_BigLimit) +{ + EXPECT_EQ(Strings_vt{"Word"}, WordWrapp("Word", 5)); +} + +TEST(WordWrappTests, Put_ShortWord_with_space) +{ + EXPECT_EQ(Strings_vt{"Word"}, WordWrapp("Word ", 4)); +} + +TEST(WordWrappTests, BigWord_ShortLimit) +{ + EXPECT_EQ(Strings_vt({"01234", "56789"}), WordWrapp("0123456789", 5)); +} + +TEST(WordWrappTests, BigWord_ShortLimit_ThreeWords) +{ + EXPECT_EQ(Strings_vt({"01234", "56789", "01234"}), WordWrapp("012345678901234", 5)); +} + +TEST(WordWrappTests, TwoWordWithSpace) +{ + EXPECT_EQ(Strings_vt({"0123", "4567"}), WordWrapp("0123 4567", 5)); +} + +TEST(WordWrappTests, ThreeWordWithSingleSpaces) +{ + EXPECT_EQ(Strings_vt({"012 3", "45678"}), WordWrapp("012 3 45678", 5)); +} diff --git a/tdd_intro/workshops/07_coffee/07_coffee.pro b/tdd_intro/workshops/07_coffee/07_coffee.pro new file mode 100644 index 0000000..dec9b6a --- /dev/null +++ b/tdd_intro/workshops/07_coffee/07_coffee.pro @@ -0,0 +1,9 @@ +include(../../gmock.pri) + +TEMPLATE = app +CONFIG += console c++11 +CONFIG -= app_bundle +CONFIG -= qt + +SOURCES += \ + test.cpp diff --git a/tdd_intro/workshops/07_coffee/test.cpp b/tdd_intro/workshops/07_coffee/test.cpp new file mode 100644 index 0000000..fb96119 --- /dev/null +++ b/tdd_intro/workshops/07_coffee/test.cpp @@ -0,0 +1,159 @@ +/* +We have several coffee machines. We have to create class which makes a coffee. +class ICoffeCore +{ +public: + ~ICoffeCore(){} + virtual void SetCupSize(int gram) = 0; + virtual void AddWater(int gram, int temperature) = 0; + virtual void AddSugar(int gram) = 0; + virtual void AddCoffee(int gram) = 0; + virtual void AddMilk(int gram) = 0; + virtual void AddMilkFoam(int gram) = 0; + virtual void AddChocolate(int gram) = 0; + virtual void AddCream(int gram) = 0; +}; + +We produce: +- americano: water & coffee 1:2 or 1:3. Water temp 60C +- cappuccino - milk & coffee & milk foam 1:3, 1:3, 1:3. Water temp 80C +- latte - milk & coffee & milk foam 1:4, 1:2, 1:4. Water temp 90C +- marochino - chocolate & coffee & milk foam, 1:4, 1:4, 1:4 and 1:4 is empty + +We have 2 size of cup, it is: +- little 100 gram +- big 140 gram +*/ + +// 1. test cup creation of the certain size +// 2. test adding the water (weight and temperature) +// 3. test americano +// 4. test cappuccino +// 5. test latte +// (optional) 6. test marochino + +#include +#include + +class ICoffeCore +{ +public: + ~ICoffeCore(){} + virtual void AddWater(int gram, int temperature) = 0; + virtual void AddSugar(int gram) = 0; + virtual void AddCoffee(int gram) = 0; + virtual void AddMilk(int gram) = 0; + virtual void AddMilkFoam(int gram) = 0; + virtual void AddChocolate(int gram) = 0; + virtual void AddCream(int gram) = 0; +}; + +class CoffeeCoreMock : public ICoffeCore +{ +public: + MOCK_METHOD2(AddWater, void(int, int)); + MOCK_METHOD1(AddSugar, void(int)); + MOCK_METHOD1(AddCoffee, void(int)); + MOCK_METHOD1(AddMilk, void(int)); + MOCK_METHOD1(AddMilkFoam, void(int)); + MOCK_METHOD1(AddChocolate, void(int)); + MOCK_METHOD1(AddCream, void(int)); +}; + +enum CupSize +{ + CupSizeInvalid = 0, + CupSizeLittle = 100, + CupSizeBig = 140 +}; + +class CoffeeMachine +{ +public: + CoffeeMachine(ICoffeCore& core); + + void CreateLittleCup(); + void CreateBigCup(); + void CreateHotWaterCup(); + void CreateAmericano(); +private: + ICoffeCore& m_core; + CupSize m_size; +}; + +CoffeeMachine::CoffeeMachine(ICoffeCore& core) + : m_core(core), + m_size(CupSizeInvalid) +{ +} + +void CoffeeMachine::CreateLittleCup() +{ + m_size = CupSizeLittle; +} + +void CoffeeMachine::CreateBigCup() +{ + m_size = CupSizeBig; +} + +void CoffeeMachine::CreateHotWaterCup() +{ + m_core.AddWater(CupSizeBig, 95); +} + +void CoffeeMachine::CreateAmericano() +{ + if(m_size == CupSizeInvalid) + { + throw std::runtime_error("cap is empty"); + } + m_core.AddWater(m_size / 2, 60); + m_core.AddCoffee(m_size / 2); +} + +TEST(CoffeCoretest, CreateHotWater) +{ + CoffeeCoreMock mock; + CoffeeMachine machine(mock); + + EXPECT_CALL(mock, AddWater(CupSizeBig, 95)).Times(1); + machine.CreateBigCup(); + machine.CreateHotWaterCup(); +} + +// FIX: sequence +//- americano: water & coffee 1:2 or 1:3. Water temp 60C +TEST(CoffeCoretest, CreateAmericanoBig) +{ + CoffeeCoreMock mock; + CoffeeMachine machine(mock); + + EXPECT_CALL(mock, AddWater(CupSizeBig / 2, 60)).Times(1); + EXPECT_CALL(mock, AddCoffee(CupSizeBig / 2)).Times(1); + machine.CreateBigCup(); + machine.CreateAmericano(); +} + +TEST(CoffeCoretest, CreateAmericanoLittle) +{ + CoffeeCoreMock mock; + CoffeeMachine machine(mock); + + EXPECT_CALL(mock, AddWater(CupSizeLittle / 2, 60)).Times(1); + EXPECT_CALL(mock, AddCoffee(CupSizeLittle / 2)).Times(1); + machine.CreateLittleCup(); + machine.CreateAmericano(); +} + +TEST(CoffeCoretest, CreateAmericanoLittle_NoCup) +{ + CoffeeCoreMock mock; + CoffeeMachine machine(mock); + + EXPECT_CALL(mock, AddWater(testing::_, testing::_)).Times(0); + EXPECT_CALL(mock, AddCoffee(testing::_)).Times(0); + EXPECT_THROW(machine.CreateAmericano(), std::runtime_error); +} + +// add other tests diff --git a/tdd_intro/workshops/README.MD b/tdd_intro/workshops/README.MD index 85013db..442e1e7 100644 --- a/tdd_intro/workshops/README.MD +++ b/tdd_intro/workshops/README.MD @@ -37,31 +37,135 @@ Example declaration of function required can be something like this: std::map WordsCount(std::string) ``` -### Anagram +### Armstrong number -Given a word and a list of possible anagrams, select the correct sublist. +An Armstrong number is a number that is the sum of its own digits each raised to the power of the number of digits. -Given "listen" and a list of candidates like "enlists" "google" "inlets" "banana" the program should return a list containing "inlets". +For example: + +9 is an Armstrong number, because 9 = 9^1 = 9 +10 is not an Armstrong number, because 10 != 1^2 + 0^2 = 1 +153 is an Armstrong number, because: 153 = 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153 +154 is not an Armstrong number, because: 154 != 1^3 + 5^3 + 4^3 = 1 + 125 + 64 = 190 +9474 is an Armstrong number + +Write some code to determine whether a number is an Armstrong number. + +Acceptance test +5 - true +100 - false +9475 - false +9926315 - true +9926314 - false _from http://exercism.io/_ -### Trinary +### Roman numerals + +Write a function to convert from normal numbers to Roman Numerals. + +The Romans wrote numbers using letters - I, V, X, L, C, D, M. (converter http://www.novaroma.org/via_romana/numbers.html) + +There is no need to be able to convert numbers larger than about 3000. (The Romans themselves didn't tend to go any higher) + +Wikipedia says: Modern Roman numerals ... are written by expressing each digit separately starting with the left most digit and skipping any digit with a value of zero. + +To see this in practice, consider the example of 1990. +In Roman numerals 1990 is MCMXC: +1000=M 900=CM 90=XC + +2008 is written as MMVIII: +2000=MM 8=VIII + +1998 is written as MCMXCVIII. + +## Functionality decomposition training: -Convert a trinary number, represented as a string (e.g. '102012'), to its decimal equivalent using first principles. +### Bank OCR -The program should consider strings specifying an invalid trinary as the value 0. +Your manager has recently purchased a machine that assists in reading letters and faxes sent in by branch offices. The machine scans the paper documents, and produces a file with a number of entries. You will write a program to parse this file. -Trinary numbers contain three symbols: 0, 1, and 2. +#### Specification +#### User Story 1 -The last place in a trinary number is the 1's place. The second to last is the 3's place, the third to last is the 9's place, etc. +The following format is created by the machine: ``` -# "102012" - 1 0 2 0 1 2 # the number -1*3^5 + 0*3^4 + 2*3^3 + 0*3^2 + 1*3^1 + 2*3^0 # the value - 243 + 0 + 54 + 0 + 3 + 2 = 302 + _ _ _ _ _ _ _ + | _| _||_||_ |_ ||_||_| + ||_ _| | _||_| ||_| _| ``` +Each entry is 3 lines long, and each line has 27 characters. 3 lines of each entry contain an account number written using pipes and underscores. + +Each account number should have 9 digits, all of which should be in the range 0-9. A normal file contains around 500 entries. + +Write a program that can take this file and parse it into actual account numbers. + +Example input and output +``` + _ _ _ _ _ _ _ _ _ +| || || || || || || || || | +|_||_||_||_||_||_||_||_||_| + +=> 000000000 + + | | | | | | | | | + | | | | | | | | | + +=> 111111111 + + _ _ _ _ _ _ _ _ _ + _| _| _| _| _| _| _| _| _| +|_ |_ |_ |_ |_ |_ |_ |_ |_ + +=> 222222222 + + _ _ _ _ _ _ _ _ _ + _| _| _| _| _| _| _| _| _| + _| _| _| _| _| _| _| _| _| -If your language provides a method in the standard library to perform the conversion, pretend it doesn't exist and implement it yourself. +=> 333333333 + +|_||_||_||_||_||_||_||_||_| + | | | | | | | | | + +=> 444444444 + + _ _ _ _ _ _ _ _ _ +|_ |_ |_ |_ |_ |_ |_ |_ |_ + _| _| _| _| _| _| _| _| _| + +=> 555555555 + + _ _ _ _ _ _ _ _ _ +|_ |_ |_ |_ |_ |_ |_ |_ |_ +|_||_||_||_||_||_||_||_||_| + +=> 666666666 + + _ _ _ _ _ _ _ _ _ + | | | | | | | | | + | | | | | | | | | + +=> 777777777 + + _ _ _ _ _ _ _ _ _ +|_||_||_||_||_||_||_||_||_| +|_||_||_||_||_||_||_||_||_| + +=> 888888888 + + _ _ _ _ _ _ _ _ _ +|_||_||_||_||_||_||_||_||_| + _| _| _| _| _| _| _| _| _| + +=> 999999999 + + _ _ _ _ _ _ _ + | _| _||_||_ |_ ||_||_| + ||_ _| | _||_| ||_| _| + +=> 123456789 +``` ### Word Wrapp @@ -81,3 +185,32 @@ It should be wrapped by length of 30 into this sequence of lines (ommiting quote "after pos." ``` +### Coffee +We have several coffee machines. We have to create class which makes a coffee. +``` +class ICoffeCore +{ +public: + ~ICoffeCore(){} + virtual void SetCupSize(int gram) = 0; + virtual void AddWater(int gram, int temperature) = 0; + virtual void AddSugar(int gram) = 0; + virtual void AddCoffee(int gram) = 0; + virtual void AddMilk(int gram) = 0; + virtual void AddMilkFoam(int gram) = 0; + virtual void AddChocolate(int gram) = 0; + virtual void AddCream(int gram) = 0; +}; +``` + +We produce: +(sequence) +- americano: water & coffee 1:2 or 1:3. Water temp 60C +- cappuccino - milk & coffee & milk foam 1:3, 1:3, 1:3. Water temp 80C +- latte - milk & coffee & milk foam 1:4, 1:2, 1:4. Water temp 90C +- marochino - chocolate & coffee & milk foam, 1:4, 1:4, 1:4 and 1:4 is empty + +We have 2 size of cup, it is: +- little 100 gram +- big 140 gram + diff --git a/tdd_intro/workshops/workshops.pro b/tdd_intro/workshops/workshops.pro index 3bcc2e2..72daf7c 100644 --- a/tdd_intro/workshops/workshops.pro +++ b/tdd_intro/workshops/workshops.pro @@ -3,6 +3,8 @@ TEMPLATE = subdirs SUBDIRS += \ 01_fizz_buzz \ 02_word_count \ - 03_anagram \ - 04_trinary_numbers \ - 05_word_wrapp + 03_armstrong_number \ + 04_roman_numerals \ + 05_word_wrapp \ + 05_bank_ocr\ + 07_coffee