From 885e9d38c27483bcab8d1568206c51a9fbda401f Mon Sep 17 00:00:00 2001 From: rbasso Date: Thu, 8 Sep 2016 13:27:25 +0900 Subject: [PATCH] pascals-triangle: Rewrite tests to use hspec with fail-fast. - Rewrite tests to use `hspec`. - Change tests to match `x-common`. - Rewrite the stub solution to be simpler and match the new test suite. --- exercises/pascals-triangle/package.yaml | 2 +- exercises/pascals-triangle/src/Example.hs | 15 +++---- exercises/pascals-triangle/src/Triangle.hs | 9 ++-- exercises/pascals-triangle/test/Tests.hs | 52 +++++++++------------- 4 files changed, 31 insertions(+), 47 deletions(-) diff --git a/exercises/pascals-triangle/package.yaml b/exercises/pascals-triangle/package.yaml index 86508d2a6..37e04b94f 100644 --- a/exercises/pascals-triangle/package.yaml +++ b/exercises/pascals-triangle/package.yaml @@ -16,4 +16,4 @@ tests: source-dirs: test dependencies: - pascals-triangle - - HUnit + - hspec diff --git a/exercises/pascals-triangle/src/Example.hs b/exercises/pascals-triangle/src/Example.hs index 38d8c7093..347fb03aa 100644 --- a/exercises/pascals-triangle/src/Example.hs +++ b/exercises/pascals-triangle/src/Example.hs @@ -1,12 +1,7 @@ -module Triangle (triangle, row) where +module Triangle (rows) where -triangle :: Integral a => [[a]] -triangle = map row [1..] +rows :: Integral a => Int -> [[a]] +rows = flip take triangle -row :: (Integral a) => a -> [a] -row n = reflect [] $ scanl choices 1 [1 .. pred n `div` 2] - where - reflect acc [] | odd n = tail acc - | otherwise = acc - reflect acc (x:xs) = x : reflect (x:acc) xs - choices z i = z * (n - i) `div` i +triangle :: Integral a => [[a]] +triangle = iterate (\x -> zipWith (+) (0 : x) (x ++ [0])) [1] diff --git a/exercises/pascals-triangle/src/Triangle.hs b/exercises/pascals-triangle/src/Triangle.hs index cec7ee6a7..eb3e5c724 100644 --- a/exercises/pascals-triangle/src/Triangle.hs +++ b/exercises/pascals-triangle/src/Triangle.hs @@ -1,7 +1,4 @@ -module Triangle (triangle, row) where +module Triangle (rows) where -triangle :: Integral a => [[a]] -triangle = undefined - -row :: Integral a => a -> [a] -row = undefined +rows :: Int -> [[Integer]] +rows = undefined diff --git a/exercises/pascals-triangle/test/Tests.hs b/exercises/pascals-triangle/test/Tests.hs index 629fa52ae..74d447656 100644 --- a/exercises/pascals-triangle/test/Tests.hs +++ b/exercises/pascals-triangle/test/Tests.hs @@ -1,36 +1,28 @@ {-# OPTIONS_GHC -fno-warn-type-defaults #-} -import Test.HUnit (Assertion, (@=?), runTestTT, Test(..), Counts(..)) -import System.Exit (ExitCode(..), exitWith) -import Triangle (row, triangle) +import Data.Foldable (for_) +import Test.Hspec (Spec, describe, it, shouldBe) +import Test.Hspec.Runner (configFastFail, defaultConfig, hspecWith) -exitProperly :: IO Counts -> IO () -exitProperly m = do - counts <- m - exitWith $ if failures counts /= 0 || errors counts /= 0 then ExitFailure 1 else ExitSuccess - -testCase :: String -> Assertion -> Test -testCase label assertion = TestLabel label (TestCase assertion) +import Triangle (rows) main :: IO () -main = exitProperly $ runTestTT $ TestList - [ TestList triangleTests ] +main = hspecWith defaultConfig {configFastFail = True} specs + +specs :: Spec +specs = describe "pascals-triangle" $ do + describe "rows" $ for_ rowsCases rowsTest + where + + rowsTest (description, n, expected) = it description assertion + where + assertion = rows n `shouldBe` expected + + -- Test cases adapted from `exercism/x-common` on 2016-09-14. -triangleTests :: [Test] -triangleTests = - [ testCase "1 row" $ - [[1]] @=? take 1 (triangle :: [[Int]]) - , testCase "2 rows" $ - [[1], [1, 1]] @=? take 2 (triangle :: [[Int]]) - , testCase "3 rows" $ - [[1], [1, 1], [1, 2, 1]] @=? take 3 (triangle :: [[Int]]) - , testCase "4 rows" $ - [[1], [1, 1], [1, 2, 1], [1, 3, 3, 1]] @=? take 4 (triangle :: [[Int]]) - , testCase "5th row" $ - [1, 4, 6, 4, 1] @=? (row 5 :: [Int]) - , testCase "20th row" $ - [(1 :: Int), 19, 171, 969, 3876, 11628, 27132, 50388, 75582, 92378 - , 92378, 75582, 50388, 27132, 11628, 3876, 969, 171, 19, 1] @=? row 20 - , testCase "201st row maximum" $ - (product [101..200] `div` product [1..100] :: Integer) @=? row 201 !! 100 - ] + rowsCases = [ ("no rows" , 0, [ ]) + , ("single row" , 1, [[1] ]) + , ("two rows" , 2, [[1], [1, 1] ]) + , ("three rows" , 3, [[1], [1, 1], [1, 2, 1] ]) + , ("four rows" , 4, [[1], [1, 1], [1, 2, 1], [1, 3, 3, 1]]) + , ("negative rows",-1, [ ]) ]