From 85357b0c414b7ef4541c5888c67f5b7bcaa5a22e Mon Sep 17 00:00:00 2001 From: Jonathan Morocho Date: Tue, 21 Feb 2017 15:39:50 -0500 Subject: [PATCH] Add tests for homework 1 to 6 using hspec package. --- .gitignore | 18 +++++++ homework01/basis.cabal | 2 +- homework01/stack.yaml | 2 +- homework01/test/examples/Main.hs | 72 ++++++++++++++++++++++----- homework02/data-types.cabal | 2 +- homework02/stack.yaml | 2 +- homework02/test/examples/Main.hs | 52 ++++++++++++++----- homework03/rec-poly.cabal | 2 +- homework03/stack.yaml | 2 +- homework03/test/examples/Main.hs | 48 +++++++++++++----- homework04/stack.yaml | 2 +- homework04/test/examples/Main.hs | 52 ++++++++++++++----- homework04/wholemeal.cabal | 2 +- homework05/data-types.cabal | 2 +- homework05/src/StackVM.hs | 2 +- homework05/stack.yaml | 2 +- homework05/test/examples/Main.hs | 85 +++++++++++++++++++++++++++----- homework06/fibonacci.cabal | 2 +- homework06/stack.yaml | 2 +- homework06/test/examples/Main.hs | 53 +++++++++++++++----- 20 files changed, 327 insertions(+), 79 deletions(-) diff --git a/.gitignore b/.gitignore index 3a5b475..8f86552 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,19 @@ +*.swp +dist +dist-* +cabal-dev +*.o +*.hi +*.chi +*.chs.h +*.dyn_o +*.dyn_hi +.hpc +.hsenv +.cabal-sandbox/ +cabal.sandbox.config +*.prof +*.aux +*.hp +*.eventlog .stack-work/ diff --git a/homework01/basis.cabal b/homework01/basis.cabal index b66270b..e70d7e0 100644 --- a/homework01/basis.cabal +++ b/homework01/basis.cabal @@ -20,7 +20,7 @@ test-suite examples build-depends: base , basis - , doctest >= 0.10 + , hspec default-language: Haskell2010 diff --git a/homework01/stack.yaml b/homework01/stack.yaml index 50c452a..a43da4b 100644 --- a/homework01/stack.yaml +++ b/homework01/stack.yaml @@ -1 +1 @@ -resolver: lts-5.6 +resolver: lts-7.14 diff --git a/homework01/test/examples/Main.hs b/homework01/test/examples/Main.hs index 83c5e46..07708a4 100644 --- a/homework01/test/examples/Main.hs +++ b/homework01/test/examples/Main.hs @@ -1,15 +1,65 @@ module Main - ( main - ) - where - --- doctest -import qualified Test.DocTest as DocTest + ( main ) +where +import Basis +import Test.Hspec main :: IO () -main = - DocTest.doctest - [ "-isrc" - , "src/Basis.hs" - ] +main = hspec $ do + + describe "toDigits" $ do + context "when the number is greater than 0" $ + it "returns a list of digits" $ + toDigits 1234 `shouldBe` [1, 2, 3, 4] + + context "when the number is 0" $ + it "returns an empty list" $ + toDigits 0 `shouldBe` [] + + context "when the number is less than 0" $ + it "returns an empty list" $ + toDigits (-17) `shouldBe` [] + + describe "toDigitsRev" $ do + context "when the number is greater than 0" $ + it "returns a list of digits reversed" $ + toDigitsRev 9876 `shouldBe` [6, 7, 8, 9] + + context "when the number is 0" $ + it "returns an empty list" $ + toDigitsRev 0 `shouldBe` [] + + context "when the number is less than 0" $ + it "returns an empty list" $ + toDigitsRev (-1) `shouldBe` [] + + describe "doubleEveryOther" $ do + context "when the list has an even number of elements" $ + it "doubles every other number beginning from the right" $ + doubleEveryOther [8, 7, 6, 5] `shouldBe` [16, 7, 12, 5] + + context "when the list has an odd number of elements" $ + it "doubles every other number beginning from the right" $ + doubleEveryOther [1, 2, 3] `shouldBe` [1, 4, 3] + + describe "sumDigits" $ + it "calculates the sum of sums of the digits of each element in a list" $ + sumDigits [16, 7, 12, 5] `shouldBe` 22 + + describe "validate" $ do + context "when the credit card number is valid" $ + it "returns True" $ + validate 4012888888881881 `shouldBe` True + + context "when the credit card number is invalid" $ + it "returns False" $ + validate 4012888888881882 `shouldBe` False + + describe "hanoi" $ + context "when the stack discs moves from first peg to second" $ do + it "gets a list of moves whit 2 discs" $ + hanoi 2 "a" "b" "c" `shouldBe` [("a", "c"), ("a", "b"), ("c", "b")] + + it "gets a list of moves whit 3 discs" $ + hanoi 3 "a" "b" "c" `shouldBe` [("a","b"),("a","c"),("b","c"),("a","b"),("c","a"),("c","b"),("a","b")] diff --git a/homework02/data-types.cabal b/homework02/data-types.cabal index 0fb0549..fce49ab 100644 --- a/homework02/data-types.cabal +++ b/homework02/data-types.cabal @@ -21,7 +21,7 @@ test-suite examples build-depends: base , data-types - , doctest >= 0.10 + , hspec default-language: Haskell2010 test-suite suggestions diff --git a/homework02/stack.yaml b/homework02/stack.yaml index 50c452a..a43da4b 100644 --- a/homework02/stack.yaml +++ b/homework02/stack.yaml @@ -1 +1 @@ -resolver: lts-5.6 +resolver: lts-7.14 diff --git a/homework02/test/examples/Main.hs b/homework02/test/examples/Main.hs index 690e9d4..7560f5a 100644 --- a/homework02/test/examples/Main.hs +++ b/homework02/test/examples/Main.hs @@ -1,15 +1,45 @@ module Main - ( main - ) - where - --- doctest -import qualified Test.DocTest as DocTest + ( main ) +where +import Log +import LogAnalysis +import Test.Hspec main :: IO () -main = - DocTest.doctest - [ "-isrc" - , "src/LogAnalysis.hs" - ] +main = hspec $ do + + describe "parseMessage" $ do + it "parses an error message" $ + parseMessage "E 2 562 help help" `shouldBe` LogMessage (Error 2) 562 "help help" + + it "parses an info message" $ + parseMessage "I 29 la la la" `shouldBe` LogMessage Info 29 "la la la" + + it "parses an Unknown message" $ + parseMessage "This is not in the right format" `shouldBe` Unknown "This is not in the right format" + + describe "insert" $ + it "returns a tree with LogMessage inserted" $ do + let tree = Node Leaf (LogMessage (Error 2) 562 "help help") Leaf + insert (LogMessage Info 29 "la") tree + `shouldBe` Node (Node Leaf (LogMessage Info 29 "la") Leaf) (LogMessage (Error 2) 562 "help help") Leaf + + describe "build" $ + it "builds up a MessageTree containing the messages in a list" $ do + let messageTreeSet = [LogMessage (Error 2) 562 "help help", LogMessage Info 29 "la"] + build messageTreeSet + `shouldBe` Node (Node Leaf (LogMessage Info 29 "la") Leaf) (LogMessage (Error 2) 562 "help help") Leaf + + describe "inOrder" $ + it "produces a list of all LogMessages it contains, sorted by timestamp from smallest to biggest" $ do + let messageTreeSet = [LogMessage (Error 2) 562 "help help",LogMessage Info 29 "la"] + inOrder (build messageTreeSet) + `shouldBe` [LogMessage Info 29 "la",LogMessage (Error 2) 562 "help help"] + + describe "whatWentWrong" $ + context "with a severity of 50 or greater" $ + it "returns a list of the messages corresponding to any errors sorted by timestamp" $ do + parseTest <- testWhatWentWrong parse whatWentWrong "src/sample.log" + parseTest + `shouldBe` ["Way too many pickles","Bad pickle-flange interaction detected","Flange failed!"] diff --git a/homework03/rec-poly.cabal b/homework03/rec-poly.cabal index 541e18c..4720324 100644 --- a/homework03/rec-poly.cabal +++ b/homework03/rec-poly.cabal @@ -18,7 +18,7 @@ test-suite examples build-depends: base , rec-poly - , doctest >= 0.10 + , hspec default-language: Haskell2010 test-suite suggestions diff --git a/homework03/stack.yaml b/homework03/stack.yaml index 50c452a..a43da4b 100644 --- a/homework03/stack.yaml +++ b/homework03/stack.yaml @@ -1 +1 @@ -resolver: lts-5.6 +resolver: lts-7.14 diff --git a/homework03/test/examples/Main.hs b/homework03/test/examples/Main.hs index c87129a..9829b79 100644 --- a/homework03/test/examples/Main.hs +++ b/homework03/test/examples/Main.hs @@ -1,15 +1,41 @@ module Main - ( main - ) - where - --- doctest -import qualified Test.DocTest as DocTest + ( main ) +where +import Golf +import Test.Hspec main :: IO () -main = - DocTest.doctest - [ "-isrc" - , "src/Golf.hs" - ] +main = hspec $ do + + describe "skips" $ do + it "skips list of Chars (length 4)" $ + skips "ABCD" `shouldBe` ["ABCD", "BD", "C", "D"] + + it "skips list of Chars (length 6)" $ + skips "hello!" `shouldBe` ["hello!", "el!", "l!", "l", "o", "!"] + + it "skips list of one element" $ + skips [1] `shouldBe` [[1]] + + it "skips list of Booleans" $ + skips [True,False] `shouldBe` [[True,False], [False]] + + it "skips empty list" $ + skips ([] :: [String]) `shouldBe` ([] :: [[String]]) + + describe "localMaxima" $ do + context "when at least one element of list is greater than both elements immediately before and after it" $ do + it "returns two local maximums" $ + localMaxima [2,9,5,6,1] `shouldBe` [9,6] + + it "returns one local maximum" $ + localMaxima [2,3,4,1,5] `shouldBe` [4] + + context "when no element of list is greater than both elements immediately before and after it" $ + it "returns zero local maximum" $ + localMaxima [1,2,3,4,5] `shouldBe` [] + + describe "histogram" $ + it "outputs a vertical histogram" $ + histogram [1,1,1,5] `shouldBe` " * \n * \n * * \n==========\n0123456789\n" diff --git a/homework04/stack.yaml b/homework04/stack.yaml index 35cf59e..a43da4b 100644 --- a/homework04/stack.yaml +++ b/homework04/stack.yaml @@ -1 +1 @@ -resolver: lts-5.10 +resolver: lts-7.14 diff --git a/homework04/test/examples/Main.hs b/homework04/test/examples/Main.hs index ceaeb1c..4c9e2ae 100644 --- a/homework04/test/examples/Main.hs +++ b/homework04/test/examples/Main.hs @@ -1,15 +1,45 @@ module Main - ( main - ) - where - --- doctest -import qualified Test.DocTest as DocTest + ( main ) +where +import Wholemeal +import Test.Hspec main :: IO () -main = - DocTest.doctest - [ "-isrc" - , "src/Wholemeal.hs" - ] +main = hspec $ do + + describe "fun1'" $ + it "returns same output of fun1" $ + fun1' [1,3,5,7] `shouldBe` fun1 [1,3,5,7] + + describe "fun2'" $ + it "returns same output of fun2" $ + fun2' 10 `shouldBe` fun2 10 + + describe "foldTree" $ + -- Because you can have many implementations of foldTree, you will only test the height of the tree + it "returns heigh of a balanced binary tree" $ do + let height (Node x _ _ _) = x + height (foldTree "ABCDEFGHIJ") `shouldBe` 3 + + describe "xor" $ do + context "when list has an odd number of True values" $ + it "returns True" $ + xor [False, True, False] `shouldBe` True + + context "when list has an even number of True values" $ + it "returns False" $ + xor [False, True, False, False, True] `shouldBe` False + + describe "map'" $ do + context "when list is not empty" $ + it "returns same output of standard map function" $ + map' (+1) [1,2,3] `shouldBe` map (+1) [1,2,3] + + context "when list is empty" $ + it "returns same output of standard map function" $ + map' (*2) [] `shouldBe` map (*2) [] + + describe "sieveSundaram" $ + it "returns a list of prime numbers less than 2*n + 2" $ + sieveSundaram 20 `shouldBe` [3,5,7,11,13,17,19,23,29,31,37,41] diff --git a/homework04/wholemeal.cabal b/homework04/wholemeal.cabal index ab42fcd..8cda904 100644 --- a/homework04/wholemeal.cabal +++ b/homework04/wholemeal.cabal @@ -20,7 +20,7 @@ test-suite examples build-depends: base , wholemeal - , doctest >= 0.10 + , hspec default-language: Haskell2010 diff --git a/homework05/data-types.cabal b/homework05/data-types.cabal index 1a27e0d..3de9ae5 100644 --- a/homework05/data-types.cabal +++ b/homework05/data-types.cabal @@ -28,7 +28,7 @@ test-suite examples base , data-types , mtl - , doctest >= 0.10 + , hspec default-language: Haskell2010 test-suite suggestions diff --git a/homework05/src/StackVM.hs b/homework05/src/StackVM.hs index 5b2591a..f041776 100644 --- a/homework05/src/StackVM.hs +++ b/homework05/src/StackVM.hs @@ -11,7 +11,7 @@ data StackExp = PushI Integer | Mul | And | Or - deriving Show + deriving (Show, Eq) type Stack = [StackVal] type Program = [StackExp] diff --git a/homework05/stack.yaml b/homework05/stack.yaml index 35cf59e..a43da4b 100644 --- a/homework05/stack.yaml +++ b/homework05/stack.yaml @@ -1 +1 @@ -resolver: lts-5.10 +resolver: lts-7.14 diff --git a/homework05/test/examples/Main.hs b/homework05/test/examples/Main.hs index f751422..8ebeb62 100644 --- a/homework05/test/examples/Main.hs +++ b/homework05/test/examples/Main.hs @@ -1,15 +1,78 @@ module Main - ( main - ) - where - --- doctest -import qualified Test.DocTest as DocTest + ( main ) +where +import ExprT +import Calc +import Parser +import StackVM +import Test.Hspec main :: IO () -main = - DocTest.doctest - [ "-isrc" - , "src/Calc.hs" - ] +main = hspec $ do + + describe "eval" $ + it "returns result of applying add and multiply operations" $ + eval (ExprT.Mul (ExprT.Add (ExprT.Lit 2) (ExprT.Lit 3)) (ExprT.Lit (-4))) `shouldBe` (-20) + + describe "evalStr" $ do + context "when an expression is well-formed" $ do + context "and when the expression has parentheses" $ + it "returns value of expression" $ + evalStr "(2+3)*(-4)" `shouldBe` Just (-20) + + context "and when the expression does not have parentheses" $ + it "returns value of expression" $ + evalStr "2+3*4" `shouldBe` Just 14 + + context "when an expression is not well-formed" $ do + context "and when the expression has parentheses" $ + it "returns Nothing" $ + evalStr "(2+3)*" `shouldBe` Nothing + + context "and when the expression does not have parentheses" $ + it "returns Nothing" $ + evalStr "2+3*" `shouldBe` Nothing + + describe "reify" $ + it "makes an instance of Expr to ExprT type" $ + reify (mul (add (lit 2) (lit 3)) (lit (-4))) + `shouldBe` ExprT.Mul (ExprT.Add (ExprT.Lit 2) (ExprT.Lit 3)) (ExprT.Lit (-4)) + + describe "parseExp" $ do + context "when provided with an Integer data type" $ + it "returns value of expression" $ do + let testInteger = parseExp lit add mul "(3 * 4) + (-5)" :: Maybe Integer + testInteger `shouldBe` Just 7 + + context "when provided with a Bool data type" $ + it "returns value of expression" $ do + let testBool = parseExp lit add mul "(3 * 4) + (-5)" :: Maybe Bool + testBool `shouldBe` Just True + + context "when provided with a MinMax data type" $ + it "returns value of expression" $ do + let testMM = parseExp lit add mul "(3 * 4) + (-5)" :: Maybe MinMax + testMM `shouldBe` Just (MinMax 3) + + context "when provided with a Mod7 data type" $ + it "returns value of expression" $ do + let testSat = parseExp lit add mul "(3 * 4) + (-5)" :: Maybe Mod7 + testSat `shouldBe` Just (Mod7 0) + + describe "compile" $ + it "returns stack operations" $ + compile "(3*4)" `shouldBe` ((Just [PushI 3,PushI 4,StackVM.Mul]) :: Maybe Program) + + describe "withVars" $ do + context "when the provided variable exists in operation of Expr class" $ + it "returns value of expression" $ + withVars [("x", -6)] (add (lit 3) (var "x")) `shouldBe` Just (-3) + + context "when the provided variables exists in operation of Expr class" $ + it "returns value of expression" $ + withVars [("x", 6), ("y", 3)] (mul (var "x") (add (var "y") (var "x"))) `shouldBe` Just 54 + + context "when the provided variable does not exists in operation of Expr class" $ + it "returns Nothing" $ + withVars [("x", 6)] (add (lit 3) (var "y")) `shouldBe` Nothing diff --git a/homework06/fibonacci.cabal b/homework06/fibonacci.cabal index 68b05e7..69e0d47 100644 --- a/homework06/fibonacci.cabal +++ b/homework06/fibonacci.cabal @@ -20,7 +20,7 @@ test-suite examples build-depends: base , fibonacci - , doctest >= 0.10 + , hspec default-language: Haskell2010 diff --git a/homework06/stack.yaml b/homework06/stack.yaml index 35cf59e..a43da4b 100644 --- a/homework06/stack.yaml +++ b/homework06/stack.yaml @@ -1 +1 @@ -resolver: lts-5.10 +resolver: lts-7.14 diff --git a/homework06/test/examples/Main.hs b/homework06/test/examples/Main.hs index 5133d40..75224fc 100644 --- a/homework06/test/examples/Main.hs +++ b/homework06/test/examples/Main.hs @@ -1,15 +1,46 @@ module Main - ( main - ) - where - --- doctest -import qualified Test.DocTest as DocTest + ( main ) +where +import Fibonacci +import Test.Hspec main :: IO () -main = - DocTest.doctest - [ "-isrc" - , "src/Fibonacci.hs" - ] +main = hspec $ do + + describe "fib" $ + it "calculates 7th number of Fibonacci sequence" $ + fib 7 `shouldBe` 13 + + describe "fibs1" $ + it "gets first 10 numbers of Fibonacci sequence" $ + take 10 fibs1 `shouldBe` [0,1,1,2,3,5,8,13,21,34] + + describe "fibs2" $ + it "gets first 12 numbers of Fibonacci sequence" $ + take 12 fibs2 `shouldBe` [0,1,1,2,3,5,8,13,21,34,55,89] + + describe "show" $ + it "takes first 20 elements of infinite list of Stream data type" $ do + let createStream x = Cons x (createStream x) + show (createStream 4) `shouldBe` "[4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4]" + + describe "streamRepeat" $ + it "generates a stream containing many copies of the given element" $ + show (streamRepeat 'a') `shouldBe` "\"aaaaaaaaaaaaaaaaaaaa\"" + + describe "streamMap" $ + it "applies a function to every element of a stream" $ + show (streamMap (+1) (streamRepeat 1)) `shouldBe` "[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2]" + + describe "streamFromSeed" $ + it "generates a stream form a `seed` of the given type" $ + show (streamFromSeed (+10) 1) `shouldBe` "[1,11,21,31,41,51,61,71,81,91,101,111,121,131,141,151,161,171,181,191]" + + describe "nats" $ + it "gets first 20 numbers of the infinite list of natural numbers" $ + show nats `shouldBe` "[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]" + + describe "ruler" $ + it "gets first 20 numbers of a ruler function" $ + show ruler `shouldBe` "[0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2]"