diff --git a/tdd_intro/demo/02_word_count/test.cpp b/tdd_intro/demo/02_word_count/test.cpp index 6bdc8367..268c4d8f 100644 --- a/tdd_intro/demo/02_word_count/test.cpp +++ b/tdd_intro/demo/02_word_count/test.cpp @@ -15,5 +15,3 @@ such: 1 #include #include -#include - diff --git a/tdd_intro/homework/05_word_wrapp/05_word_wrapp.pro b/tdd_intro/demo/03_word_wrapp/03_word_wrapp.pro similarity index 100% rename from tdd_intro/homework/05_word_wrapp/05_word_wrapp.pro rename to tdd_intro/demo/03_word_wrapp/03_word_wrapp.pro diff --git a/tdd_intro/demo/03_word_wrapp/test.cpp b/tdd_intro/demo/03_word_wrapp/test.cpp new file mode 100644 index 00000000..83821e4e --- /dev/null +++ b/tdd_intro/demo/03_word_wrapp/test.cpp @@ -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 +#include +#include + +using StringContainer = std::vector; +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)); +} diff --git a/tdd_intro/demo/demo.pro b/tdd_intro/demo/demo.pro index 9e9ba630..37ec0908 100644 --- a/tdd_intro/demo/demo.pro +++ b/tdd_intro/demo/demo.pro @@ -5,6 +5,7 @@ SUBDIRS += \ 01_fizz_buzz \ 02_anagram \ 02_word_count \ + 03_word_wrapp \ #03_allergies \ 03_roman_numerals \ 04_timer diff --git a/tdd_intro/homework/03_bank_ocr/test.cpp b/tdd_intro/homework/03_bank_ocr/test.cpp index a01540b9..2fc0a569 100644 --- a/tdd_intro/homework/03_bank_ocr/test.cpp +++ b/tdd_intro/homework/03_bank_ocr/test.cpp @@ -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 + * - ParseDigit(const Digit& digit) -> int - parses digit from 3x3 char matrix + * - SplitDigits(const Display& display) -> vector - 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 SplitDigits(const Display& display) +{ + std::vector 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 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 expected = { + s_digit1, s_digit2, s_digit3, + s_digit4, s_digit5, s_digit6, + s_digit7, s_digit8, s_digit9 + }; + std::vector 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)); +} diff --git a/tdd_intro/homework/05_word_wrapp/test.cpp b/tdd_intro/homework/05_word_wrapp/test.cpp deleted file mode 100644 index 77e47210..00000000 --- a/tdd_intro/homework/05_word_wrapp/test.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* -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 - -"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 - -// empty string -// string shorter than wrap number -// word longer than wrap number -// word much longer than wrap number (more than 2 strings) -// string longer than wrap number - -// string wrapped by several whitespaces (less than wrapLength) -// string wrapped by several whitespaces (more than wrapLength) -// only whitespaces in string - -using WrappedStrings = std::vector; - -WrappedStrings WrapString(const std::string& str, size_t wrapLength) -{ - WrappedStrings result; - for(size_t i = 0; i < str.length(); i += wrapLength) - { - std::string cur = str.substr(i, wrapLength); - if (cur.back() == ' ') - { - cur.pop_back(); - } - - if(!cur.empty() && cur.front() == ' ') - { - cur = cur.substr(1); - } - - if(!cur.empty()) - { - result.push_back(cur); - } - } - - return result; -} - -TEST(WrapString, EmptyString) -{ - ASSERT_EQ(WrappedStrings(), WrapString("", 25)); -} - -TEST(WrapString, StringShorterWrapNumber) -{ - ASSERT_EQ(WrappedStrings{"asdf"}, WrapString("asdf", 8)); -} - -TEST(WrapString, StringLongerThanWrapNumber) -{ - WrappedStrings expected = {"asd", "f"}; - ASSERT_EQ(expected, WrapString("asdf", 3)); -} - -TEST(WrapString, StringLongerThanWrapNumberSeveralParts) -{ - WrappedStrings expected = {"12", "34", "56"}; - ASSERT_EQ(expected, WrapString("123456", 2)); -} - -TEST(WrapString, MultipleWordsLonger) -{ - WrappedStrings expected = {"1", "2"}; - ASSERT_EQ(expected, WrapString("1 2", 1)); -} - -TEST(WrapString, SpaceStringEnd) -{ - WrappedStrings expected = {"1", "2"}; - ASSERT_EQ(expected, WrapString("1 2", 2)); -} - -TEST(WrapString, StringWrappedBySeveralWhitespace) -{ - WrappedStrings expected = {"12", "34"}; - ASSERT_EQ(expected, WrapString("12 34", 3)); -} diff --git a/tdd_intro/homework/homework.pro b/tdd_intro/homework/homework.pro index cf6c01b9..7e131270 100644 --- a/tdd_intro/homework/homework.pro +++ b/tdd_intro/homework/homework.pro @@ -5,5 +5,4 @@ SUBDIRS += \ 02_ternary_numbers \ 03_bank_ocr \ 04_weather_client \ - 05_word_wrapp \ 06_coffee