From 7f22c4d1f57fac10ef53f3be1e1f0956e6e0db59 Mon Sep 17 00:00:00 2001 From: Jonathan Morocho Date: Tue, 28 Mar 2017 15:58:24 -0500 Subject: [PATCH] Add tests for homework 7 to 11 using hspec package --- homework07/editor.cabal | 2 +- homework07/stack.yaml | 2 +- homework07/test/examples/Main.hs | 115 +++++++++++++++++++++++++++---- homework08/party.cabal | 5 +- homework08/stack.yaml | 2 +- homework08/test/examples/Main.hs | 56 ++++++++++++--- homework10/aparser.cabal | 2 +- homework10/stack.yaml | 2 +- homework10/test/examples/Main.hs | 94 ++++++++++++++++++++++--- homework11/sexpr.cabal | 2 +- homework11/src/SExpr.hs | 4 +- homework11/stack.yaml | 2 +- homework11/test/examples/Main.hs | 84 +++++++++++++++++++--- homework12/stack.yaml | 2 +- 14 files changed, 318 insertions(+), 56 deletions(-) diff --git a/homework07/editor.cabal b/homework07/editor.cabal index 410b34a..d80c750 100644 --- a/homework07/editor.cabal +++ b/homework07/editor.cabal @@ -28,7 +28,7 @@ test-suite examples base , editor , mtl - , doctest >= 0.10 + , hspec default-language: Haskell2010 diff --git a/homework07/stack.yaml b/homework07/stack.yaml index 35cf59e..a43da4b 100644 --- a/homework07/stack.yaml +++ b/homework07/stack.yaml @@ -1 +1 @@ -resolver: lts-5.10 +resolver: lts-7.14 diff --git a/homework07/test/examples/Main.hs b/homework07/test/examples/Main.hs index a5abfa1..fdc9685 100644 --- a/homework07/test/examples/Main.hs +++ b/homework07/test/examples/Main.hs @@ -1,16 +1,107 @@ module Main - ( main - ) - where - --- doctest -import qualified Test.DocTest as DocTest + ( main ) +where +import JoinList hiding (main) +import Scrabble +import Buffer +import Editor +import Sized +import Test.Hspec main :: IO () -main = - DocTest.doctest - [ "-isrc" - , "src/JoinList.hs" - , "src/Scrabble.hs" - ] +main = hspec $ do + + describe "(+++) (append function)" $ do + context "when provided with Empty and Single values" $ + it "returns new JoinList" $ + (+++) Empty (Single (Size 1) "a") `shouldBe` Append (Size 1) Empty (Single (Size 1) "a") + + context "when provided with Single and Append values" $ + it "returns new JoinList" $ + (+++) (Single (Size 1) "a") (Append (Size 2) Empty Empty) + `shouldBe` Append (Size 3) (Single (Size 1) "a") (Append (Size 2) Empty Empty) + + context "when provided with Empty and Append values" $ + it "returns new JoinList" $ + (+++) Empty (Append (Size 2) (Single (Size 1) "a") (Single (Size 2) "b")) + `shouldBe` Append (Size 2) Empty (Append (Size 2) (Single (Size 1) "a") (Single (Size 2) "b")) + + describe "indexJ" $ do + context "when provided with Empty value" $ + it "returns Nothing" $ + indexJ 10 (Empty :: JoinList Size String) `shouldBe` Nothing + + context "when provided with Single value" $ do + context "when index is equals to zero" $ + it "returns a Just value" $ + indexJ 0 (Single (Size 1) "a") `shouldBe` Just "a" + + context "when index is out of range" $ + it "returns Nothing" $ + indexJ 1 (Single (Size 1) "a") `shouldBe` Nothing + + context "when provided with Append value" $ do + context "when index is in range" $ + it "returns a Just value" $ + indexJ 0 (Append (Size 2) (Single (Size 1) "a") (Single (Size 2) "b")) + `shouldBe` Just "a" + + context "when index is out of range" $ + it "returns Nothing" $ + indexJ 2 (Append (Size 2) (Single (Size 1) "a") (Single (Size 2) "b")) + `shouldBe` Nothing + + describe "dropJ" $ do + context "when provided with Empty value" $ + it "returns Empty" $ + dropJ 10 (Empty :: JoinList Size String) `shouldBe` Empty + + context "when provided with Single value" $ do + context "when number of elements to drop is zero" $ + it "returns original JoinList" $ + dropJ 0 (Single (Size 1) "a") `shouldBe` (Single (Size 1) "a") + + context "when number of elements to drop is valid" $ + it "returns Empty" $ + dropJ 1 (Single (Size 1) "a") `shouldBe` Empty + + context "when provided with Append value" $ do + context "when number of elements to drop is zero" $ + it "returns original JoinList" $ + dropJ 0 (Append (Size 2) (Single (Size 1) "a") (Single (Size 2) "b")) + `shouldBe` (Append (Size 2) (Single (Size 1) "a") (Single (Size 2) "b")) + + context "when number of elements to drop is valid" $ + it "drops the first n elements from a JoinList" $ + dropJ 1 (Append (Size 2) (Single (Size 1) "a") (Single (Size 2) "b")) + `shouldBe` Single (Size 2) "b" + + describe "takeJ" $ do + context "when provided with Empty value" $ + it "returns Empty" $ + takeJ 10 (Empty :: JoinList Size String) `shouldBe` Empty + + context "when provided with Single value" $ do + context "when number of elements to take is zero" $ + it "returns Empty value" $ + takeJ 0 (Single (Size 1) "a") `shouldBe` Empty + + context "when number of elements to take is valid" $ + it "returns original JoinList" $ + takeJ 1 (Single (Size 1) "a") `shouldBe` (Single (Size 1) "a") + + context "when provided with Append value" $ do + context "when number of elements to take is zero" $ + it "returns Empty value" $ + takeJ 0 (Append (Size 2) (Single (Size 1) "a") (Single (Size 2) "b")) + `shouldBe` Empty + + context "when number of elements to take is valid" $ + it "takes the first n elements from a JoinList" $ + takeJ 1 (Append (Size 2) (Single (Size 1) "a") (Single (Size 2) "b")) + `shouldBe` Append (Size 1) (Single (Size 1) "a") Empty + + describe "scoreLine" $ + it "returns JoinList with scrabble score" $ + scoreLine "haskell" `shouldBe` Single (Score 14) "haskell" \ No newline at end of file diff --git a/homework08/party.cabal b/homework08/party.cabal index c833879..d72b1f8 100644 --- a/homework08/party.cabal +++ b/homework08/party.cabal @@ -6,7 +6,9 @@ cabal-version: >= 1.10 library hs-source-dirs: src - exposed-modules: Party + exposed-modules: + Party + Employee build-depends: containers , base >= 4.7 && < 5 @@ -24,6 +26,7 @@ test-suite examples , containers , party , doctest >= 0.10 + , hspec default-language: Haskell2010 diff --git a/homework08/stack.yaml b/homework08/stack.yaml index 35cf59e..a43da4b 100644 --- a/homework08/stack.yaml +++ b/homework08/stack.yaml @@ -1 +1 @@ -resolver: lts-5.10 +resolver: lts-7.14 diff --git a/homework08/test/examples/Main.hs b/homework08/test/examples/Main.hs index 49f4604..da09cde 100644 --- a/homework08/test/examples/Main.hs +++ b/homework08/test/examples/Main.hs @@ -1,15 +1,49 @@ module Main - ( main - ) - where - --- doctest -import qualified Test.DocTest as DocTest + ( main ) +where +import Employee +import qualified Party as P +import Data.Tree +import Test.Hspec main :: IO () -main = - DocTest.doctest - [ "-isrc" - , "src/Party.hs" - ] +main = hspec $ do + + describe "glCons" $ + it "adds an Employee to the GuestList" $ do + let guestList = GL [Emp "Stan" 9, Emp "Bob" 2] 11 + P.glCons (Emp "Joe" 5) guestList + `shouldBe` GL [Emp "Stan" 9, Emp "Bob" 2, Emp "Joe" 5] 16 + + describe "moreFun" $ + it "returns the GuestList with more fun" $ do + let firstGuestList = GL [Emp "Stan" 9, Emp "Bob" 2] 11 + let secondGuestList = GL [Emp "John" 1, Emp "Sue" 5] 6 + P.moreFun firstGuestList secondGuestList + `shouldBe` GL [Emp "Stan" 9, Emp "Bob" 2] 11 + + describe "treeFold" $ + it "folds function with a tree" $ do + let first = Node { rootLabel = 1::Integer, subForest = [] } + let second = Node { rootLabel = 2::Integer, subForest = [] } + let third = Node { rootLabel = 3::Integer, subForest = [] } + let tree = Node { rootLabel = 4::Integer, subForest = [first, second, third] } + P.treeFold (\x xs -> x + (sum xs)) [0] tree `shouldBe` 10 + + describe "nextLevel" $ + it "returns the best guest list both with and without the given boss" $ do + let firstGuestList = GL [Emp "Stan" 9, Emp "Bob" 2] 16 + let secondGuestList = GL [Emp "John" 1, Emp "Sue" 5] 6 + P.nextLevel (Emp "Joe" 5) [(firstGuestList, secondGuestList)] + `shouldBe` (GL [Emp "John" 1, Emp "Sue" 5, Emp "Joe" 5] 11, GL [Emp "Stan" 9, Emp "Bob" 2] 16) + + describe "maxFun" $ + it "returns a fun-maximizing guest list" $ + P.maxFun testCompany `shouldBe` GL [Emp "Sarah" 17] 17 + + describe "main" $ + it "prints out a formatted guest list" $ do + mainResult <- P.main + formattedGuestList <- putStrLn $ "Total fun: 268\nFrancis Deluzain\nHenri Bishop\nMargareth Adix\n" + mainResult `shouldBe` formattedGuestList \ No newline at end of file diff --git a/homework10/aparser.cabal b/homework10/aparser.cabal index 9786710..c03caab 100644 --- a/homework10/aparser.cabal +++ b/homework10/aparser.cabal @@ -20,7 +20,7 @@ test-suite examples build-depends: base , aparser - , doctest >= 0.10 + , hspec default-language: Haskell2010 diff --git a/homework10/stack.yaml b/homework10/stack.yaml index 2a4df46..a43da4b 100644 --- a/homework10/stack.yaml +++ b/homework10/stack.yaml @@ -1 +1 @@ -resolver: lts-4.1 +resolver: lts-7.14 diff --git a/homework10/test/examples/Main.hs b/homework10/test/examples/Main.hs index 6d3c22a..5b18747 100644 --- a/homework10/test/examples/Main.hs +++ b/homework10/test/examples/Main.hs @@ -1,15 +1,87 @@ module Main - ( main - ) - where - --- doctest -import qualified Test.DocTest as DocTest + ( main ) +where +import Control.Applicative +import AParser +import Data.Char +import Test.Hspec main :: IO () -main = - DocTest.doctest - [ "-isrc" - , "src/AParser.hs" - ] +main = hspec $ do + + describe "fmap (Parser)" $ + it "returns the result of fmap in Parser value" $ do + let concatStr str = Just(str, str ++ "haskell") + let parserStr = map toUpper <$> Parser concatStr + runParser parserStr "abc" `shouldBe` Just ("ABC","abchaskell") + + describe "pure (Parser)" $ + it "returns pure value of Applicative instance for Parser" $ do + let parser = pure "ABC" + runParser parser "abc" `shouldBe` Just ("ABC","abc") + + describe "<*> (Parser)" $ + it "returns sequential application of Applicative instance for Parser" $ do + let concatStr str = Just(str, str ++ "haskell") + let pureParser = pure $ map toUpper + let parserStr = pureParser <*> Parser concatStr + runParser parserStr "abc" `shouldBe` Just ("ABC","abchaskell") + + describe "abParser" $ do + context "when the first characters of the input are 'a' and 'b'" $ + it "returns a Just value with (a,b) tuple and the input without this characters" $ + runParser abParser "abcdef" `shouldBe` Just (('a','b'),"cdef") + + context "when the first characters of the input aren't 'a' and 'b'" $ + it "returns Nothing" $ + runParser abParser "aebcdf" `shouldBe` Nothing + + describe "abParser_" $ do + context "when the first characters of the input are 'a' and 'b'" $ + it "returns a Just value with empty tuple and the input without 'a' and 'b' characters" $ + runParser abParser_ "abcdef" `shouldBe` Just ((),"cdef") + + context "when the first characters of the input aren't 'a' and 'b'" $ + it "returns Nothing" $ + runParser abParser_ "aebcdf" `shouldBe` Nothing + + describe "intPair" $ do + context "when the input contains two integer values separated by a space" $ + it "returns the integer values in a list" $ + runParser intPair "12 34" `shouldBe` Just ([12,34],"") + + context "when the input does not contains two integer values separated by a space" $ + it "returns Nothing" $ + runParser intPair "a b" `shouldBe` Nothing + + describe "empty (Parser)" $ + it "returns Nothing" $ do + let parser = empty :: Parser [Integer] + runParser parser "abc" `shouldBe` Nothing + + describe "<|> (Parser)" $ do + context "when the first parser succeeds" $ + it "returns the result of the first parser" $ do + let firstParser = runParser intPair "12 34" + let secondParser = runParser intPair "56 78" + (firstParser <|> secondParser) `shouldBe` Just ([12,34],"") + + context "when the first parser fails" $ + it "returns the result of the second parser" $ do + let firstParser = runParser intPair "a b" + let secondParser = runParser intPair "56 78" + (firstParser <|> secondParser) `shouldBe` Just ([56,78],"") + + describe "intOrUppercase" $ do + context "when the first characters of the input are numbers" $ + it "returns a Just value with empty tuple and the input without numbers" $ + runParser intOrUppercase "342abcd" `shouldBe` Just ((),"abcd") + + context "when the first characters of the input are uppercase" $ + it "returns a Just value with empty tuple and the input without first character" $ + runParser intOrUppercase "XYZ" `shouldBe` Just ((),"YZ") + + context "when the first characters of the input aren't numbers or uppercase" $ + it "returns Nothing" $ + runParser intOrUppercase "foo" `shouldBe` Nothing diff --git a/homework11/sexpr.cabal b/homework11/sexpr.cabal index 0da6a06..661d0b7 100644 --- a/homework11/sexpr.cabal +++ b/homework11/sexpr.cabal @@ -22,7 +22,7 @@ test-suite examples build-depends: base , sexpr - , doctest >= 0.10 + , hspec default-language: Haskell2010 diff --git a/homework11/src/SExpr.hs b/homework11/src/SExpr.hs index fc30fe1..5d64210 100644 --- a/homework11/src/SExpr.hs +++ b/homework11/src/SExpr.hs @@ -74,13 +74,13 @@ type Ident = data Atom = N Integer | I Ident - deriving Show + deriving (Show, Eq) data SExpr = A Atom | Comb [SExpr] - deriving Show + deriving (Show, Eq) -- | diff --git a/homework11/stack.yaml b/homework11/stack.yaml index 2a4df46..a43da4b 100644 --- a/homework11/stack.yaml +++ b/homework11/stack.yaml @@ -1 +1 @@ -resolver: lts-4.1 +resolver: lts-7.14 diff --git a/homework11/test/examples/Main.hs b/homework11/test/examples/Main.hs index fdfdaa2..3502805 100644 --- a/homework11/test/examples/Main.hs +++ b/homework11/test/examples/Main.hs @@ -1,15 +1,77 @@ module Main - ( main - ) - where - --- doctest -import qualified Test.DocTest as DocTest + ( main ) +where +import AParser +import Data.Char +import SExpr +import Test.Hspec main :: IO () -main = - DocTest.doctest - [ "-isrc" - , "src/SExpr.hs" - ] +main = hspec $ do + + describe "zeroOrMore" $ + context "when input is 'satisfy isUpper' parser" $ do + context "when the first characters of the input of runParser are uppercase" $ + it "returns a Just value with the first uppercase characters and the rest of input in a tuple" $ + runParser (zeroOrMore (satisfy isUpper)) "ABCdEfgH" `shouldBe` Just ("ABC","dEfgH") + + context "when the first characters of the input of runParser aren't uppercase" $ + it "returns a Just value with empty string and input in a tuple" $ + runParser (zeroOrMore (satisfy isUpper)) "abcdeFGh" `shouldBe` Just ("","abcdeFGh") + + describe "oneOrMore" $ + context "when input is 'satisfy isUpper' parser" $ do + context "when the first characters of the input of runParser are uppercase" $ + it "returns a Just value with the first uppercase characters and the rest of input in a tuple" $ + runParser (oneOrMore (satisfy isUpper)) "ABCdEfgH" `shouldBe` Just ("ABC","dEfgH") + + context "when the first characters of runParser's input aren't uppercase" $ + it "returns Nothing" $ + runParser (oneOrMore (satisfy isUpper)) "abcdeFGh" `shouldBe` Nothing + + describe "spaces" $ + context "when the first characters of the input are spaces" $ + it "returns a Just value with the first space characters and the rest of input in a tuple" $ + runParser spaces " foobar baz" `shouldBe` Just (" ","foobar baz") + + describe "ident" $ do + context "when the input has characters at the begining" $ do + context "when the input has spaces" $ + it "returns a Just value with the first characters before first space and the rest of input in a tuple" $ + runParser ident "foobar baz" `shouldBe` Just ("foobar"," baz") + + context "when the input hasn't spaces" $ + it "returns a Just value with input and empty string in a tuple" $ + runParser ident "foobar" `shouldBe` Just ("foobar","") + + context "when the input has characters and numbers at the begining" $ + it "returns a Just value with input and empty string in a tuple" $ + runParser ident "foo33fA" `shouldBe` Just ("foo33fA","") + + context "when the input has numbers at the begining" $ + it "returns Nothing" $ + runParser ident "2bad" `shouldBe` Nothing + + context "when the input is an empty string" $ + it "returns Nothing" $ + runParser ident "" `shouldBe` Nothing + + describe "parseSExpr" $ do + context "when expression is well-formed" $ do + context "when expression is a number" $ + it "returns a Just value with a S-expression and empty string in a tuple" $ + runParser parseSExpr "3" `shouldBe` Just (A (N 3),"") + + context "when expression is a string" $ + it "returns a Just value with a S-expression and empty string in a tuple" $ + runParser parseSExpr "foo" `shouldBe` Just (A (I "foo"),"") + + context "when expression has numbers and characters" $ + it "returns a Just value with a S-expression and empty string in a tuple" $ + runParser parseSExpr "(lambda x x) 3" + `shouldBe` Just (Comb [A (I "lambda"),A (I "x"),A (I "x")],"3") + + context "when expression isn't well-formed" $ + it "returns Nothing" $ + runParser parseSExpr "(lambda x x" `shouldBe` Nothing \ No newline at end of file diff --git a/homework12/stack.yaml b/homework12/stack.yaml index 2a4df46..a43da4b 100644 --- a/homework12/stack.yaml +++ b/homework12/stack.yaml @@ -1 +1 @@ -resolver: lts-4.1 +resolver: lts-7.14