Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions tdd_intro/demo/02_word_count/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,3 @@ such: 1

#include <gtest/gtest.h>
#include <string>
#include <map>

77 changes: 77 additions & 0 deletions tdd_intro/demo/03_word_wrapp/test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
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.

Example:
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

split(hee, 1) -> h, e, e
split(hee, 2) -> he, e
split("ha ha", 2|3|4) -> "ha", "ha"
split("h a", 1) -> "h", "a"

"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 <gtest/gtest.h>
#include <string>
#include <vector>

using StringContainer = std::vector<std::string>;
StringContainer SplitString(const std::string& string, size_t length)
{
auto firstSpaceInSubstr = string.rfind(' ', length);
std::string::size_type offset = length;
if (firstSpaceInSubstr != std::string::npos)
{
offset = firstSpaceInSubstr + 1;
}

StringContainer result {{ string.substr(0, offset) }};

if (length < string.size())
{
result.push_back(string.substr(offset));
}
return result;
}

TEST(SplitString, OnePartForOneSymbol)
{
StringContainer parts = {"a"};
EXPECT_EQ(parts, SplitString("a", 1));
}

TEST(SplitString, AbFirstForAbbaAnd2)
{
EXPECT_EQ("Ab", SplitString("Abba", 2).at(0));
}

TEST(SplitString, BaSecondForAbbba)
{
EXPECT_EQ("ba", SplitString("Abba", 2).at(1));
}

TEST(SplitString, AbForAbAnd4)
{
EXPECT_EQ("Ab", SplitString("Ab", 4).at(0));
}

TEST(SplitString, SplitAb_AbBeforeSpaceReturnsAbAndAb)
{
StringContainer parts = {"Ab", "Ab"};
EXPECT_EQ(parts, SplitString("Ab Ab", 2));
}

TEST(SplitString, SplitAb_AbAtSpaceReturnsAbAndAb)
{
StringContainer parts = {"Ab", "Ab"};
EXPECT_EQ(parts, SplitString("Ab Ab", 3));
}
1 change: 1 addition & 0 deletions tdd_intro/demo/demo.pro
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ SUBDIRS += \
01_fizz_buzz \
02_anagram \
02_word_count \
03_word_wrapp \
#03_allergies \
03_roman_numerals \
04_timer
150 changes: 150 additions & 0 deletions tdd_intro/homework/03_bank_ocr/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,153 @@ const Display s_display123456789 = { " _ _ _ _ _ _ _ ",
" | _| _||_||_ |_ ||_||_|",
" ||_ _| | _||_| ||_| _|"
};

/*
* Decomposition:
* - CompareDigit(const Digit& a, const Digit& b) -> bool - compares two digits, and returns true if it equals
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Определять на этапе планирования интерфейсы функций не очень гуд - таким образом снижается эффект от очень важной фичи TDD проектирования кода исходя из потребностей. И если в данном случае, это не является проблемой в виду 4-х функций, на бОльших системах это может снижать удобство использования интерфейсов

* - ParseDigit(const Digit& digit) -> int - parses digit from 3x3 char matrix
* - SplitDigits(const Display& display) -> vector<Digit> - split display to separate digits
* - ParseAccountNumber(const Display& display) -> int - parses account number from Display
* Test list:
* - CompareDigit
* -- Should return true for identical digits
* -- Should return false for different digits
* - ParseDigit
* -- It should return -1 for invalid digit
* -- It should return digit's number if it is in list of known digits
* - SplitDigits
* -- It should return vector of splitted digits from display
* - ParseAccountNumber
* -- Should return account number for display
*/

/* Functions */
static Digit s_digits[] = {
s_digit0, s_digit1, s_digit2, s_digit3, s_digit4,
s_digit5, s_digit6, s_digit7, s_digit8, s_digit9
};

bool CompareDigit(const Digit& a, const Digit& b)
{
for (size_t i = 0; i < g_linesInDigit; ++i)
{
if (a.lines[i] != b.lines[i])
{
return false;
}
}
return true;
}
int ParseDigit(const Digit& digit)
{
for (int i = 0; i < 10; ++i)
{
if (CompareDigit(digit, s_digits[i]))
{
return i;
}
}
return 0;
}
std::vector<Digit> SplitDigits(const Display& display)
{
std::vector<Digit> result(g_digitsOnDisplay);
for (int j = 0; j < g_digitsOnDisplay; ++j)
{
for (int i = 0; i < g_linesInDigit; ++i)
{
result.at(j).lines[i] = display.lines[i].substr(j * g_digitLen, g_digitLen);
}
}
return std::move(result);
}
int ParseAccountNumber(const Display& display)
{
int result = 0;
std::vector<Digit> splittedDigits = SplitDigits(display);
for (const Digit& digit : splittedDigits)
{
result = result * 10 + ParseDigit(digit);
}
return result;
}

/* Tests */
TEST(CompareDigitTest, ItShouldReturnFalseForDifferendDigits)
{
EXPECT_FALSE(CompareDigit(s_digit0, s_digit1));
}
TEST(CompareDigitTest, ItShouldReturnTrueForIdendicalDigits)
{
EXPECT_TRUE(CompareDigit(s_digit0, s_digit0));
}

TEST(ParseDigitTest, ItShouldReturn0ForDigit0)
{
EXPECT_EQ(0, ParseDigit(s_digit0));
}
TEST(ParseDigitTest, ItShouldReturn1ForDigit1)
{
EXPECT_EQ(1, ParseDigit(s_digit1));
}
TEST(ParseDigitTest, ItShouldReturnIntegerDigitForAnyDigitFromList)
{
for (int i = 0; i < 10; ++i)
{
EXPECT_EQ(i, ParseDigit(s_digits[i]));
}
}

TEST(SplitDigitsTest, ItShouldReturnVectorWithSizeNine)
{
EXPECT_EQ(9, SplitDigits(s_displayAll0).size());
}
TEST(SplitDigitsTest, FirstDigitMustBeZeroForAllZeroes)
{
EXPECT_TRUE(CompareDigit(s_digit0, SplitDigits(s_displayAll0).front()));
}
TEST(SplitDigitsTest, FirstDigitMustBeOneForAllOnes)
{
EXPECT_TRUE(CompareDigit(s_digit1, SplitDigits(s_displayAll1).front()));
}
TEST(SplitDigitsTest, SecondDigitMustBeTwoForAllTwos)
{
EXPECT_TRUE(CompareDigit(s_digit2, SplitDigits(s_displayAll2).at(1)));
}
TEST(SplitDigitsTest, ItShouldParseEachDigitOnDisplay)
{
std::vector<Digit> expected = {
s_digit1, s_digit2, s_digit3,
s_digit4, s_digit5, s_digit6,
s_digit7, s_digit8, s_digit9
};
std::vector<Digit> splitted = SplitDigits(s_display123456789);

for (size_t i = 0; i < g_digitsOnDisplay; i++)
{
EXPECT_TRUE(CompareDigit(expected.at(i), splitted.at(i)));
}
}

TEST(ParseAccountNumberTest, ItShouldReturnNineOnesForAll1)
{
EXPECT_EQ(111111111, ParseAccountNumber(s_displayAll1));
}
TEST(ParseAccountNumberTest, ItShouldReturnNineTwosForAll2)
{
EXPECT_EQ(222222222, ParseAccountNumber(s_displayAll2));
}
TEST(ParseAccountNumberTest, AcceptanceUserStory1)
{
EXPECT_EQ(0, ParseAccountNumber(s_displayAll0));
EXPECT_EQ(111111111, ParseAccountNumber(s_displayAll1));
EXPECT_EQ(222222222, ParseAccountNumber(s_displayAll2));
EXPECT_EQ(333333333, ParseAccountNumber(s_displayAll3));
EXPECT_EQ(444444444, ParseAccountNumber(s_displayAll4));
EXPECT_EQ(555555555, ParseAccountNumber(s_displayAll5));
EXPECT_EQ(666666666, ParseAccountNumber(s_displayAll6));
EXPECT_EQ(777777777, ParseAccountNumber(s_displayAll7));
EXPECT_EQ(888888888, ParseAccountNumber(s_displayAll8));
EXPECT_EQ(999999999, ParseAccountNumber(s_displayAll9));
EXPECT_EQ(123456789, ParseAccountNumber(s_display123456789));
}
96 changes: 0 additions & 96 deletions tdd_intro/homework/05_word_wrapp/test.cpp

This file was deleted.

1 change: 0 additions & 1 deletion tdd_intro/homework/homework.pro
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@ SUBDIRS += \
02_ternary_numbers \
03_bank_ocr \
04_weather_client \
05_word_wrapp \
06_coffee