diff --git a/.Guesser.cpp.swp b/.Guesser.cpp.swp new file mode 100644 index 0000000..0170670 Binary files /dev/null and b/.Guesser.cpp.swp differ diff --git a/.GuesserTest.cpp.swp b/.GuesserTest.cpp.swp new file mode 100644 index 0000000..9cd9074 Binary files /dev/null and b/.GuesserTest.cpp.swp differ diff --git a/Guesser.cpp.gcov b/Guesser.cpp.gcov new file mode 100644 index 0000000..db98bf5 --- /dev/null +++ b/Guesser.cpp.gcov @@ -0,0 +1,154 @@ + -: 0:Source:Guesser.cpp + -: 0:Graph:Guesser.gcno + -: 0:Data:Guesser.gcda + -: 0:Runs:1 + -: 1:#include "Guesser.h" + -: 2:#include + -: 3:#include + -: 4: + -: 5:using std::string; + -: 6: + -: 7:/* + -: 8: Returns an whole number representing the distance between the guess, + -: 9: provided as an argument, and the secret. The distance represents the number + -: 10: of characters that would have to be changed at the same location to match + -: 11: the other string. When the two strings are identical, the distance is 0, + -: 12: but for each letter different, the distance increases by 1. When the + -: 13: strings are different lengths, each of the extra characters in the longer + -: 14: string also counts as an increase in 1 to the distance, up to the length of + -: 15: the secret; in other words, if m_secret has a 10 characters and the guess + -: 16: has 100, the distance is 10. + -: 17:*/ +function _ZN7Guesser8distanceENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE called 16 returned 100% blocks executed 100% + 16: 18:unsigned int Guesser::distance(string guess){ + 16: 19: int length_diff = 0; + 16: 20: if( guess.length() > m_secret.length() ){ +call 0 returned 16 +call 1 returned 16 +branch 2 taken 5 (fallthrough) +branch 3 taken 11 + 5: 21: length_diff += guess.length() - m_secret.length(); +call 0 returned 5 +call 1 returned 5 + -: 22: } + 11: 23: else if( guess.length() < m_secret.length() ){ +call 0 returned 11 +call 1 returned 11 +branch 2 taken 3 (fallthrough) +branch 3 taken 8 + 3: 24: length_diff += m_secret.length() - guess.length(); +call 0 returned 3 +call 1 returned 3 + -: 25: } + 65: 26: for(int i=0; i < m_secret.length() && i < guess.length(); i++ ){ +call 0 returned 65 +branch 1 taken 52 (fallthrough) +branch 2 taken 13 +call 3 returned 52 +branch 4 taken 49 (fallthrough) +branch 5 taken 3 +branch 6 taken 49 +branch 7 taken 16 (fallthrough) + 49: 27: if( m_secret.at(i) != guess.at(i) ){ +call 0 returned 49 +call 1 returned 49 +branch 2 taken 12 (fallthrough) +branch 3 taken 37 + 12: 28: length_diff++; + -: 29: } + -: 30: } + 16: 31: if( length_diff > m_secret.length() ){ +call 0 returned 16 +branch 1 taken 4 (fallthrough) +branch 2 taken 12 + 4: 32: length_diff = m_secret.length(); +call 0 returned 4 + -: 33: } + 16: 34: return length_diff; + -: 35:} + -: 36: + -: 37:/* + -: 38: Constructor requires that the secret phrase is provided its value as + -: 39: an argument. This secret will not change for the lifespan of an instance + -: 40: of any Guesser object and must have a length of 32 characters or less, + -: 41: otherwise, it will be truncated at that length. + -: 42:*/ +function _ZN7GuesserC2ENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE called 13 returned 100% blocks executed 83% + 13: 43:Guesser::Guesser(string secret){ +call 0 returned 13 + 13: 44: if( secret.length() > 32 ){ +call 0 returned 13 +branch 1 taken 1 (fallthrough) +branch 2 taken 12 + 1: 45: m_secret = secret.substr(0, 32); +call 0 returned 1 +branch 1 taken 1 (fallthrough) +branch 2 taken 0 (throw) +call 3 returned 1 +call 4 returned 1 + -: 46: } + -: 47: else{ + 12: 48: m_secret = secret; +call 0 returned 12 +branch 1 taken 12 (fallthrough) +branch 2 taken 0 (throw) + -: 49: } + 13: 50: m_locked = false; + 13: 51: m_remaining = 3; + 13: 52:} +call 0 never executed + -: 53: + -: 54:/* + -: 55: Determines and returns whether the provided guess matches the secret + -: 56: phrase. However, the function also returns false if the secret is locked, + -: 57: which happens if either (or both): + -: 58: (A) there are no remaining guesses allowed + -: 59: (B) the function detects brute force, as indicated by a guess that has a + -: 60: distance greater than 2 from the secret + -: 61: See the distance() functions for specifications regarding determining the + -: 62: distance between a guess and the secret. + -: 63: + -: 64: A Guesser object allows up to + -: 65: three (3) consecutive guesses without a match. If three guesses are made + -: 66: without any being a true match, the secret is locked. However, whenever + -: 67: an unlocked secret is guessed with a true match, the guesses remaining + -: 68: reset to three (3). If the secret is locked for any other reason, such + -: 69: as a big distance in a guess, the count of remaining guesses should still + -: 70: count down as usual to hide that the secret has been locked. + -: 71:*/ +function _ZN7Guesser5matchENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE called 17 returned 100% blocks executed 88% + 17: 72:bool Guesser::match(string guess){ + 17: 73: if( m_remaining < 1 || m_locked ){ +branch 0 taken 15 (fallthrough) +branch 1 taken 2 +branch 2 taken 3 (fallthrough) +branch 3 taken 12 + 5: 74: return false; + -: 75: } + 12: 76: else if( guess != m_secret ){ +call 0 returned 12 +branch 1 taken 11 (fallthrough) +branch 2 taken 1 + 11: 77: unsigned int difference = distance(guess); +call 0 returned 11 +branch 1 taken 11 (fallthrough) +branch 2 taken 0 (throw) +call 3 returned 11 +branch 4 taken 11 (fallthrough) +branch 5 taken 0 (throw) +call 6 returned 11 +call 7 never executed + 11: 78: if( difference > 2 ){ +branch 0 taken 1 (fallthrough) +branch 1 taken 10 + 1: 79: m_locked = true; + -: 80: } + -: 81: else{ + 10: 82: m_remaining--; + -: 83: } + 11: 84: return false; + -: 85: } + -: 86: else{ + 1: 87: return true; + -: 88: } + -: 89:} diff --git a/GuesserTest.cpp b/GuesserTest.cpp index dce8eaa..d0db7d5 100644 --- a/GuesserTest.cpp +++ b/GuesserTest.cpp @@ -14,9 +14,88 @@ class GuesserTest : public ::testing::Test virtual void TearDown(){} //clean up after each test, (before destructor) }; -// Example "smoke test" (can be deleted) -TEST(GuesserTest, smoke_test) +// distance() tests +TEST(GuesserTest, distance) { - Guesser object("Secret"); - ASSERT_EQ( 1+1, 2 ); -} \ No newline at end of file + Guesser g("A"); + int r = g.distance("A"); + ASSERT_EQ(r, 0); +} +TEST(GuesserTest, no_guess) +{ + Guesser g("A"); + int r = g.distance(""); + ASSERT_EQ(r, 1); +} +TEST(GuesserTest, less) +{ + Guesser g("AAA"); + int r = g.distance("A"); + ASSERT_EQ(r, 2); +} +TEST(GuesserTest, more) +{ + Guesser g("A"); + int r = g.distance("AAA"); + ASSERT_EQ(r, 2); +} +TEST(GuesserTest, too_long) +{ + Guesser g("ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"); + int r = g.distance("ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF"); + ASSERT_EQ(r, 0); +} + +// match() tests +TEST(GuesserTest, match) +{ + Guesser g("A"); + bool r = g.match("A"); + ASSERT_EQ(r, 1); +} +TEST(GuesserTest, offBy1) +{ + Guesser g("A"); + bool r = g.match("AB"); + ASSERT_EQ(r, 0); +} +TEST(GuesserTest, offBy2) +{ + Guesser g("A"); + bool r = g.match("ABC"); + ASSERT_EQ(r, 0); +} +TEST(GuesserTest, offBy3) +{ Guesser g("A"); + bool r = g.match("BCD"); + ASSERT_EQ(r, 0); +} +TEST(GuesserTest, no_guess_match) +{ Guesser g("A"); + bool r = g.match(""); + ASSERT_EQ(r, 0); +} +TEST(GuesserTest, too_many_tries) +{ Guesser g("A"); + bool r = g.match("B"); + r = g.match("B"); + r = g.match("B"); + r = g.match("B"); + ASSERT_EQ(r, 0); +} +TEST(GuesserTest, too_many_tries_then_correct) +{ Guesser g("A"); + bool r = g.match("B"); + r = g.match("B"); + r = g.match("B"); + r = g.match("A"); + ASSERT_EQ(r, 0); +} +TEST(GuesserTest, way_off) +{ Guesser g("ABCDE"); + bool r = g.match("BKDSLNKL"); + r = g.match("B"); + r = g.match("B"); + r = g.match("A"); + ASSERT_EQ(r, 0); +}