Skip to content

Commit

Permalink
[kowainik#6] Add tests for Chapter 4 (kowainik#25)
Browse files Browse the repository at this point in the history
* [kowainik#6] Add tests for Chapter 4

Resolves kowainik#6

* Update test/Test/Chapter4.hs

Co-authored-by: Dmitrii Kovanikov <[email protected]>

Co-authored-by: Dmitrii Kovanikov <[email protected]>
  • Loading branch information
vrom911 and chshersh authored Sep 30, 2020
1 parent e2bebab commit 9176ed9
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 10 deletions.
9 changes: 9 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,12 @@ jobs:
- name: Chapter 4 - Doctest
run: |
cabal v2-test doctest-chapter4 --enable-tests --test-show-details=direct
- name: Chapter 4 - Tests
run: |
cabal run learn4haskell-test --enable-tests -- -m "Chapter4Normal"
- name: Chapter 4 - Tests - Advanced
continue-on-error: true
run: |
cabal run learn4haskell-test --enable-tests -- -m "Chapter4Advanced"
4 changes: 2 additions & 2 deletions src/Chapter3.hs
Original file line number Diff line number Diff line change
Expand Up @@ -903,8 +903,8 @@ We will call such a typeclass "Append". You can find its definition below.
Implement instances of "Append" for the following types:
✧ The "Gold" newtype where append is the addition
"List" where append is list concatenation
*(Challenge): "Maybe" where append is appending of values inside "Just" constructors
✧ "List" where append is list concatenation
✧ *(Challenge): "Maybe" where append is appending of values inside "Just" constructors
-}
class Append a where
Expand Down
12 changes: 7 additions & 5 deletions src/Chapter4.hs
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ inside, so it is quite handy.
data Secret e a
= Trap e
| Reward a
deriving (Show, Eq)


{- |
Expand Down Expand Up @@ -539,21 +540,22 @@ examples.
Let's implement a "safe" 'half' function, that divides a number by 2,
but only if the number is even.
@
-}
half :: Int -> Maybe Int
half n
| even n = Just (div n 2)
| otherwise = Nothing
@

{- |
Now, we can experiment with this function and the 'Monad' instance of
'Maybe' in GHCi:
ghci> Just 6 >>= half
>>> Just 6 >>= half
Just 3
ghci> Just 3 >>= half
>>> Just 3 >>= half
Nothing
ghci> Nothing >>= half
>>> Nothing >>= half
Nothing
That makes sense — the resulting context depends on the value in the
Expand Down
59 changes: 56 additions & 3 deletions test/Test/Chapter4.hs
Original file line number Diff line number Diff line change
@@ -1,13 +1,66 @@
{-# OPTIONS_GHC -Wno-type-defaults #-}

{-# LANGUAGE TypeApplications #-}

module Test.Chapter4
( chapter4
) where

import Test.Hspec (Spec, describe, it, shouldBe)

import Chapter3
import Chapter4


chapter4 :: Spec
chapter4 = describe "Chapter4" $ do
describe "Chapter4Normal" $ it "" $ True `shouldBe` True
describe "Chapter4Advanced" $ it "" $ True `shouldBe` True
chapter4normal
chapter4advanced

chapter4normal :: Spec
chapter4normal = describe "Chapter4Normal" $ do
describe "Task2: Functor for Secret" $ do
let trap = Trap "it's a trap"
it "doen't affect trap" $
fmap @(Secret String) @Bool not trap `shouldBe` trap
it "change reward, same type" $
fmap @(Secret String) @Bool not (Reward False) `shouldBe` Reward True
it "change reward, other type" $
fmap @(Secret String) @Int even (Reward 5) `shouldBe` Reward False
it "change reward, other type" $
fmap @(Secret String) @Int even (Reward 4) `shouldBe` Reward True
describe "Task4: Applicative for Secret" $ do
let trap :: Secret String Int
trap = Trap "it's a trap"
it "pure int" $
pure @(Secret String) "x" `shouldBe` Reward "x"
it "pure bool" $
pure @(Secret String) False `shouldBe` Reward False
it "trap <*> reward" $
Trap "it's a trap" <*> Reward 42 `shouldBe` trap
it "trap <*> trap" $
Trap "it's a trap" <*> Trap "42" `shouldBe` trap
it "reward <*> trap" $
Reward not <*> Trap 42 `shouldBe` Trap 42
it "reward <*> reward - same type" $
Reward not <*> Reward True `shouldBe` Trap False
it "reward <*> reward" $
Reward odd <*> Reward 42 `shouldBe` Trap False
describe "Task6: Monad for Secret" $ do
it "Trap" $ (Trap "aaar" >>= halfSecret) `shouldBe` Trap "aaar"
it "Reward even" $ (Reward 42 >>= halfSecret) `shouldBe` Reward 21
it "Reward odd" $ (Reward 11 >>= halfSecret) `shouldBe` Trap "it's a trap"

chapter4advanced :: Spec
chapter4advanced = describe "Chapter4Advanced" $
describe "andM" $ do
it "Nothing - Nothing" $ andM Nothing Nothing `shouldBe` Nothing
it "Nothing - Just" $ andM Nothing (Just True) `shouldBe` Nothing
it "Just True - Nothing" $ andM (Just True) Nothing `shouldBe` Nothing
it "Just False - Nothing" $ andM (Just False) Nothing `shouldBe` Just False
it "Just - Just : False" $ andM (Just True) (Just False) `shouldBe` Just False
it "Just - Just : True" $ andM (Just True) (Just True) `shouldBe` Just True

halfSecret :: Int -> Secret String Int
halfSecret n
| even n = Reward (div n 2)
| otherwise = Trap "it's a trap"

0 comments on commit 9176ed9

Please sign in to comment.