-- Charles Dickens, A Tale of Two Cities
I enjoy the FizzBuzz kata. I find that it offers endless amounts of flexibility, but yet it is very simple to understand and yet still has some complexity to it.
Now we have everything in place to prove that the FizzBuzz works.
Next time we'll do the same kata but using the Transformation Priority Premise (TPP).
I enjoy the FizzBuzz kata. I find that it offers endless amounts of flexibility, but yet it is very simple to understand and yet still has some complexity to it.
TDD
Note when doing TDD, you write the test case first and have it fail before you write the code to pass it, I will not be showing that step.
Case 1: x == 3 -> "Fizz"
import Test.HUnit
fizzBuzzer::Int->String
fizzBuzzer x
| ((==) x 3) = "Fizz"
t3 = TestCase (assertEqual "3 is Fizz" "Fizz" (fizzBuzzer 3))
tests = TestList [TestLabel "3 is Fizz" t3]
*Main> runTestTT tests
Cases: 1 Tried: 0 Errors: 0 Failures: 0
Case 2: x % 3 == 0 -> "Fizz"
import Test.HUnit
fizzBuzzer::Int->String
fizzBuzzer x
| (mod x 3 == 0) = "Fizz"
t3 = TestCase (assertEqual "3 is Fizz" "Fizz" (fizzBuzzer 3))
t6 = TestCase (assertEqual "6 is Fizz" "Fizz" (fizzBuzzer 6))
tests = TestList [TestLabel "3 is Fizz" t3
,TestLabel "6 is Fizz" t6]
*Main> runTestTT tests
Cases: 2 Tried: 0 Errors: 0 Failures: 0
Cases: 2 Tried: 1 Errors: 0 Failures: 0
Case 3: x % 3 != 0 -> "x" when x = 2
import Test.HUnit
fizzBuzzer::Int->String
fizzBuzzer x
| (mod x 3 == 0) = "Fizz"
| otherwise = show x
t3 = TestCase (assertEqual "3 is Fizz" "Fizz" (fizzBuzzer 3))
t6 = TestCase (assertEqual "6 is Fizz" "Fizz" (fizzBuzzer 6))
t2 = TestCase (assertEqual "2 is 2" "2" (fizzBuzzer 2))
tests = TestList [TestLabel "3 is Fizz" t3
,TestLabel "6 is Fizz" t6
,TestLabel "2 is 2" t2]
*Main> runTestTT tests
Cases: 3 Tried: 0 Errors: 0 Failures: 0
Cases: 3 Tried: 1 Errors: 0 Failures: 0
Cases: 3 Tried: 2 Errors: 0 Failures: 0
Cases: 3 Tried: 2 Errors: 0 Failures: 0
Case 4: x % 3 != 0 -> "x" when x = 4
This is a interesting test case since the code already passes it.
import Test.HUnit
fizzBuzzer::Int->String
fizzBuzzer x
| (mod x 3 == 0) = "Fizz"
| otherwise = show x
t3 = TestCase (assertEqual "3 is Fizz" "Fizz" (fizzBuzzer 3))
t6 = TestCase (assertEqual "6 is Fizz" "Fizz" (fizzBuzzer 6))
t2 = TestCase (assertEqual "2 is 2" "2" (fizzBuzzer 2))
t4 = TestCase (assertEqual "4 is 4" "4" (fizzBuzzer 4))
tests = TestList [TestLabel "3 is Fizz" t3
,TestLabel "6 is Fizz" t6
,TestLabel "2 is 2" t2
,TestLabel "4 is 4" t4]
*Main> runTestTT tests
Cases: 4 Tried: 0 Errors: 0 Failures: 0
Cases: 4 Tried: 1 Errors: 0 Failures: 0
Cases: 4 Tried: 2 Errors: 0 Failures: 0
Cases: 4 Tried: 3 Errors: 0 Failures: 0
Cases: 4 Tried: 2 Errors: 0 Failures: 0
Cases: 4 Tried: 3 Errors: 0 Failures: 0
Case 5: x == 5 -> "Buzz"
We can use the mod if we want but we'll have to live with breaking strict TDD.
import Test.HUnit
fizzBuzzer::Int->String
fizzBuzzer x
| (mod x 3 == 0) = "Fizz"
| (mod x 5 == 0) = "Buzz"
| otherwise = show x
t3 = TestCase (assertEqual "3 is Fizz" "Fizz" (fizzBuzzer 3))
t6 = TestCase (assertEqual "6 is Fizz" "Fizz" (fizzBuzzer 6))
t2 = TestCase (assertEqual "2 is 2" "2" (fizzBuzzer 2))
t4 = TestCase (assertEqual "4 is 4" "4" (fizzBuzzer 4))
t5 = TestCase (assertEqual "5 is Buzz" "Buzz" (fizzBuzzer 5))
tests = TestList [TestLabel "3 is Fizz" t3
,TestLabel "6 is Fizz" t6
,TestLabel "2 is 2" t2
,TestLabel "4 is 4" t4
,TestLabel "5 is Buzz" t5]
*Main> runTestTT tests
Cases: 5 Tried: 0 Errors: 0 Failures: 0
Cases: 5 Tried: 1 Errors: 0 Failures: 0
Cases: 5 Tried: 2 Errors: 0 Failures: 0
Cases: 5 Tried: 3 Errors: 0 Failures: 0
Cases: 5 Tried: 4 Errors: 0 Failures: 0
Cases: 5 Tried: 2 Errors: 0 Failures: 0
Cases: 5 Tried: 3 Errors: 0 Failures: 0
Cases: 5 Tried: 4 Errors: 0 Failures: 0
Case 6: x % 5 == 0 -> "Buzz"
Again we already have the code in place to pass this test case.
import Test.HUnit
fizzBuzzer::Int->String
fizzBuzzer x
| (mod x 3 == 0) = "Fizz"
| (mod x 5 == 0) = "Buzz"
| otherwise = show x
t3 = TestCase (assertEqual "3 is Fizz" "Fizz" (fizzBuzzer 3))
t6 = TestCase (assertEqual "6 is Fizz" "Fizz" (fizzBuzzer 6))
t2 = TestCase (assertEqual "2 is 2" "2" (fizzBuzzer 2))
t4 = TestCase (assertEqual "4 is 4" "4" (fizzBuzzer 4))
t5 = TestCase (assertEqual "5 is Buzz" "Buzz" (fizzBuzzer 5))
t25 = TestCase (assertEqual "25 is Buzz" "Buzz" (fizzBuzzer 25))
tests = TestList [TestLabel "3 is Fizz" t3
,TestLabel "6 is Fizz" t6
,TestLabel "2 is 2" t2
,TestLabel "4 is 4" t4
,TestLabel "5 is Buzz" t5
,TestLabel "25 is Buzz" t25]
*Main> runTestTT tests
Cases: 6 Tried: 0 Errors: 0 Failures: 0
Cases: 6 Tried: 1 Errors: 0 Failures: 0
Cases: 6 Tried: 2 Errors: 0 Failures: 0
Cases: 6 Tried: 3 Errors: 0 Failures: 0
Cases: 6 Tried: 4 Errors: 0 Failures: 0
Cases: 6 Tried: 5 Errors: 0 Failures: 0
Cases: 6 Tried: 2 Errors: 0 Failures: 0
Cases: 6 Tried: 3 Errors: 0 Failures: 0
Cases: 6 Tried: 4 Errors: 0 Failures: 0
Cases: 6 Tried: 5 Errors: 0 Failures: 0
Case 7: x == 15 -> "FizzBuzz"
We'll break strict TDD and use a mod 15.
import Test.HUnit
fizzBuzzer::Int->String
fizzBuzzer x
| (mod x 15 == 0) = "FizzBuzz"
| (mod x 3 == 0) = "Fizz"
| (mod x 5 == 0) = "Buzz"
| otherwise = show x
t3 = TestCase (assertEqual "3 is Fizz" "Fizz" (fizzBuzzer 3))
t6 = TestCase (assertEqual "6 is Fizz" "Fizz" (fizzBuzzer 6))
t2 = TestCase (assertEqual "2 is 2" "2" (fizzBuzzer 2))
t4 = TestCase (assertEqual "4 is 4" "4" (fizzBuzzer 4))
t5 = TestCase (assertEqual "5 is Buzz" "Buzz" (fizzBuzzer 5))
t25 = TestCase (assertEqual "25 is Buzz" "Buzz" (fizzBuzzer 25))
t15 = TestCase (assertEqual "15 is FizzBuzz" "FizzBuzz" (fizzBuzzer 15))
tests = TestList [TestLabel "3 is Fizz" t3
,TestLabel "6 is Fizz" t6
,TestLabel "2 is 2" t2
,TestLabel "4 is 4" t4
,TestLabel "5 is Buzz" t5
,TestLabel "25 is Buzz" t25
,TestLabel "15 is FizzBuzz" t15]
*Main> runTestTT tests
Cases: 7 Tried: 0 Errors: 0 Failures: 0
Cases: 7 Tried: 1 Errors: 0 Failures: 0
Cases: 7 Tried: 2 Errors: 0 Failures: 0
Cases: 7 Tried: 3 Errors: 0 Failures: 0
Cases: 7 Tried: 4 Errors: 0 Failures: 0
Cases: 7 Tried: 5 Errors: 0 Failures: 0
Cases: 7 Tried: 6 Errors: 0 Failures: 0
Cases: 7 Tried: 2 Errors: 0 Failures: 0
Cases: 7 Tried: 3 Errors: 0 Failures: 0
Cases: 7 Tried: 4 Errors: 0 Failures: 0
Cases: 7 Tried: 5 Errors: 0 Failures: 0
Cases: 7 Tried: 6 Errors: 0 Failures: 0
Case 8: x % 15 == 0 -> "FizzBuzz"
Again, this test case already passes.
import Test.HUnit
fizzBuzzer::Int->String
fizzBuzzer x
| (mod x 15 == 0) = "FizzBuzz"
| (mod x 3 == 0) = "Fizz"
| (mod x 5 == 0) = "Buzz"
| otherwise = show x
t3 = TestCase (assertEqual "3 is Fizz" "Fizz" (fizzBuzzer 3))
t6 = TestCase (assertEqual "6 is Fizz" "Fizz" (fizzBuzzer 6))
t2 = TestCase (assertEqual "2 is 2" "2" (fizzBuzzer 2))
t4 = TestCase (assertEqual "4 is 4" "4" (fizzBuzzer 4))
t5 = TestCase (assertEqual "5 is Buzz" "Buzz" (fizzBuzzer 5))
t25 = TestCase (assertEqual "25 is Buzz" "Buzz" (fizzBuzzer 25))
t15 = TestCase (assertEqual "15 is FizzBuzz" "FizzBuzz" (fizzBuzzer 15))
t30 = TestCase (assertEqual "30 is FizzBuzz" "FizzBuzz" (fizzBuzzer 30))
tests = TestList [TestLabel "3 is Fizz" t3
,TestLabel "6 is Fizz" t6
,TestLabel "2 is 2" t2
,TestLabel "4 is 4" t4
,TestLabel "5 is Buzz" t5
,TestLabel "25 is Buzz" t25
,TestLabel "15 is FizzBuzz" t15
,TestLabel "30 is FizzBuzz" t30]
*Main> runTestTT tests
Cases: 8 Tried: 0 Errors: 0 Failures: 0
Cases: 8 Tried: 1 Errors: 0 Failures: 0
Cases: 8 Tried: 2 Errors: 0 Failures: 0
Cases: 8 Tried: 3 Errors: 0 Failures: 0
Cases: 8 Tried: 4 Errors: 0 Failures: 0
Cases: 8 Tried: 5 Errors: 0 Failures: 0
Cases: 8 Tried: 6 Errors: 0 Failures: 0
Cases: 8 Tried: 7 Errors: 0 Failures: 0
Cases: 8 Tried: 2 Errors: 0 Failures: 0
Cases: 8 Tried: 3 Errors: 0 Failures: 0
Cases: 8 Tried: 4 Errors: 0 Failures: 0
Cases: 8 Tried: 5 Errors: 0 Failures: 0
Cases: 8 Tried: 6 Errors: 0 Failures: 0
Cases: 8 Tried: 7 Errors: 0 Failures: 0
Now we have everything in place to prove that the FizzBuzz works.
Next time we'll do the same kata but using the Transformation Priority Premise (TPP).