Skip to content

Commit aac2e52

Browse files
committed
Ch6 add exercise tests
1 parent 17713e0 commit aac2e52

File tree

4 files changed

+253
-20
lines changed

4 files changed

+253
-20
lines changed

exercises/chapter6/spago.dhall

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@
22
Welcome to a Spago project!
33
You can edit this file as you like.
44
-}
5-
{ name =
6-
"my-project"
5+
{ name = "my-project"
76
, dependencies =
8-
[ "console", "effect", "either", "psci-support", "strings", "tuples" ]
9-
, packages =
10-
./packages.dhall
11-
, sources =
12-
[ "src/**/*.purs", "test/**/*.purs" ]
7+
[ "console"
8+
, "effect"
9+
, "either"
10+
, "psci-support"
11+
, "strings"
12+
, "test-unit"
13+
, "tuples"
14+
]
15+
, packages = ./packages.dhall
16+
, sources = [ "src/**/*.purs", "test/**/*.purs" ]
1317
}

exercises/chapter6/src/Main.purs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,15 @@ module Main where
33
import Prelude
44

55
import Effect (Effect)
6-
import Effect.Console (log)
6+
import Effect.Class.Console (logShow)
7+
import Data.Hashable (hash, hashEqual)
78

89
main :: Effect Unit
910
main = do
10-
log "🍝"
11+
logShow $ hash 123
12+
logShow (hash true)
13+
logShow (hash [1, 2, 3])
14+
logShow (hash "testing")
15+
logShow (hash 'a')
16+
logShow ("foo" `hashEqual` "foo")
17+
logShow ("foo" `hashEqual` "bar")

exercises/chapter6/test/Main.purs

Lines changed: 184 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,190 @@
11
module Test.Main where
22

33
import Prelude
4-
4+
import Data.Foldable (foldMap, foldl, foldr)
5+
import Data.Hashable (hash)
6+
import Data.List (List(..), (:))
57
import Effect (Effect)
6-
import Effect.Class.Console (logShow)
7-
import Data.Hashable (hash, hashEqual)
8+
import Partial.Unsafe (unsafePartial)
9+
import Test.Solutions (Complex(..), Extended(..), Hour(..), Multiply(..), NonEmpty(..), OneMore(..), Self(..), act)
10+
import Test.Unit (suite, test)
11+
import Test.Unit.Assert as Assert
12+
import Test.Unit.Main (runTest)
813

914
main :: Effect Unit
10-
main = do
11-
logShow (hash 123)
12-
logShow (hash true)
13-
logShow (hash [1, 2, 3])
14-
logShow (hash "testing")
15-
logShow (hash 'a')
16-
logShow ("foo" `hashEqual` "foo")
17-
logShow ("foo" `hashEqual` "bar")
15+
main =
16+
runTest do
17+
suite "Exercise Group 1" do
18+
suite "Exercise 1 - Show Shape" do
19+
-- This should probably be added as an exercise to the end of chapter 5
20+
-- with a note to revisit as first exercise in chapter 6
21+
test "Show Shape todo"
22+
$ Assert.equal "todo" "todo" -- (show myShape)
23+
suite "Exercise Group 2" do
24+
suite "Exercise 1 - Show and Eq for Complex" do
25+
test "Show Complex"
26+
$ Assert.equal "1.0+2.0i"
27+
$ show
28+
$ Complex { real: 1.0, imaginary: 2.0 }
29+
{- Move this block comment starting point to enable more tests
30+
test "Show Negative Complex"
31+
$ Assert.equal "1.0-2.0i"
32+
$ show
33+
$ Complex { real: 1.0, imaginary: -2.0 }
34+
test "Eq Complex"
35+
$ Assert.equal (Complex { real: 1.0, imaginary: 2.0 })
36+
$ Complex { real: 1.0, imaginary: 2.0 }
37+
test "Eq Complex - not equal"
38+
$ Assert.expectFailure "should not be equal"
39+
$ Assert.equal (Complex { real: 5.0, imaginary: 2.0 })
40+
$ Complex { real: 1.0, imaginary: 2.0 }
41+
suite "Exercise Group 3" do
42+
suite "Exercise 1 - Eq for NonEmpty" do
43+
test "NonEmpty equals"
44+
$ Assert.equal (NonEmpty 1 [ 2, 3 ])
45+
$ NonEmpty 1 [ 2, 3 ]
46+
test "NonEmpty not equals"
47+
$ Assert.expectFailure "should not be equal"
48+
$ Assert.equal (NonEmpty 1 [ 2, 3 ])
49+
$ NonEmpty 2 [ 2, 3 ]
50+
suite "Exercise 2 - Semigroup for NonEmpty" do
51+
test "NonEmpty append"
52+
$ Assert.equal (NonEmpty 1 [ 2, 3, 4, 5, 6 ])
53+
$ NonEmpty 1 [ 2, 3 ]
54+
<> NonEmpty 4 [ 5, 6 ]
55+
suite "Exercise 3 - Functor for NonEmpty" do
56+
test "NonEmpty append"
57+
$ Assert.equal (NonEmpty 10 [ 20, 30 ])
58+
$ map (_ * 10)
59+
$ NonEmpty 1 [ 2, 3 ]
60+
suite "Exercise 4 - Ord for Extended" do
61+
-- Type annotation necessary to ensure there is an Ord instance for inner type (Int in this case)
62+
test "Extended compare inf inf"
63+
$ Assert.equal EQ
64+
$ compare Infinite (Infinite :: Extended Int)
65+
test "Extended compare inf 5"
66+
$ Assert.equal GT
67+
$ compare Infinite
68+
$ Finite 5
69+
test "Extended compare 5 inf"
70+
$ Assert.equal LT
71+
$ compare (Finite 5) Infinite
72+
test "Extended compare 5 5"
73+
$ Assert.equal EQ
74+
$ compare (Finite 5)
75+
$ Finite 5
76+
test "Extended compare 6 5"
77+
$ Assert.equal GT
78+
$ compare (Finite 6)
79+
$ Finite 5
80+
test "Extended compare 5 6"
81+
$ Assert.equal LT
82+
$ compare (Finite 5)
83+
$ Finite 6
84+
suite "Exercise 5 - Foldable for NonEmpty" do
85+
test "NonEmpty foldl"
86+
$ Assert.equal 123
87+
$ foldl (\acc x -> acc * 10 + x) 0
88+
$ NonEmpty 1 [ 2, 3 ]
89+
test "NonEmpty foldr"
90+
$ Assert.equal 321
91+
$ foldr (\x acc -> acc * 10 + x) 0
92+
$ NonEmpty 1 [ 2, 3 ]
93+
test "NonEmpty foldMap"
94+
$ Assert.equal "123"
95+
$ foldMap (\x -> show x)
96+
$ NonEmpty 1 [ 2, 3 ]
97+
suite "Exercise 6 - Foldable for OneMore" do
98+
test "OneMore foldl"
99+
$ Assert.equal 123
100+
$ foldl (\acc x -> acc * 10 + x) 0
101+
$ OneMore 1 (2 : 3 : Nil)
102+
test "OneMore foldr"
103+
$ Assert.equal 321
104+
$ foldr (\x acc -> acc * 10 + x) 0
105+
$ OneMore 1 (2 : 3 : Nil)
106+
test "OneMore foldMap"
107+
$ Assert.equal "123"
108+
$ foldMap (\x -> show x)
109+
$ OneMore 1 (2 : 3 : Nil)
110+
suite "Exercise Group 4" do
111+
suite "Exercise 1 - Partial maximum" do
112+
test "unsafeMaximum"
113+
$ Assert.equal 42
114+
$ unsafePartial
115+
$ unsafeMaximum [ 1, 2, 42, 3 ]
116+
let
117+
m1 = Multiply 3
118+
119+
m2 = Multiply 4
120+
suite "Exercise 2 - Action Class" do
121+
-- Getting Multiply Int to work is a warm-up
122+
suite "Multiply Int" do
123+
let
124+
a = 5
125+
test "Multiply Int mempty"
126+
$ Assert.equal a
127+
$ act (mempty :: Multiply) a
128+
test "Multiply Int append"
129+
$ Assert.equal (act m1 (act m2 a))
130+
$ act (m1 <> m2) a
131+
-- Multiply String is the actual exercise question
132+
suite "Multiply String" do
133+
let
134+
a = "foo"
135+
test "Multiply String mempty"
136+
$ Assert.equal a
137+
$ act (mempty :: Multiply) a
138+
test "Multiply String append"
139+
$ Assert.equal (act m1 (act m2 a))
140+
$ act (m1 <> m2) a
141+
suite "Exercise 3 - Action Array" do
142+
suite "Multiply Array Int" do
143+
let
144+
a = [ 1, 2, 3 ]
145+
test "Multiply Array Int mempty"
146+
$ Assert.equal a
147+
$ act (mempty :: Multiply) a
148+
test "Multiply Arary Int append"
149+
$ Assert.equal (act m1 (act m2 a))
150+
$ act (m1 <> m2) a
151+
suite "Multiply Array String" do
152+
let
153+
a = [ "foo", "bar", "baz" ]
154+
test "Multiply Array String mempty"
155+
$ Assert.equal a
156+
$ act (mempty :: Multiply) a
157+
test "Multiply Array String append"
158+
$ Assert.equal (act m1 (act m2 a))
159+
$ act (m1 <> m2) a
160+
suite "Exercise 4 - Action Self" do
161+
let
162+
a = Self m1
163+
test "Multiply Self mempty"
164+
$ Assert.equal a
165+
$ act (mempty :: Multiply) a
166+
test "Multiply Self append"
167+
$ Assert.equal (act m1 (act m2 a))
168+
$ act (m1 <> m2) a
169+
suite "Exercise Group 5" do
170+
suite "Exercise 2 - Array Duplicates" do
171+
test "No dupe"
172+
$ Assert.equal false
173+
$ arrayHasDuplicates [ 1, 2, 3 ]
174+
test "Dupe"
175+
$ Assert.equal true
176+
$ arrayHasDuplicates [ 1, 1, 3 ]
177+
test "Only hash dupe"
178+
$ Assert.equal false
179+
$ arrayHasDuplicates [ 65536, 1, 2, 3 ]
180+
suite "Exercise 3 - Hash Hour" do
181+
test "Match"
182+
$ Assert.equal (hash $ Hour 1)
183+
$ hash
184+
$ Hour 13
185+
test "Mismatch"
186+
$ Assert.expectFailure "should not be equal"
187+
$ Assert.equal (hash $ Hour 1)
188+
$ hash
189+
$ Hour 14
190+
-}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
module Test.Solutions where
2+
3+
import Prelude
4+
5+
newtype Complex
6+
= Complex
7+
{ real :: Number
8+
, imaginary :: Number
9+
}
10+
11+
data NonEmpty a
12+
= NonEmpty a (Array a)
13+
14+
data Extended a
15+
= Finite a
16+
| Infinite
17+
18+
data OneMore f a
19+
= OneMore a (f a)
20+
21+
-- instance foldableOneMore :: Foldable f => Foldable (OneMore f) where
22+
-- todo
23+
-- unsafeMaximum :: Partial => Array Int -> Int
24+
-- todo
25+
class
26+
Monoid m <= Action m a where
27+
act :: m -> a -> a
28+
29+
newtype Multiply
30+
= Multiply Int
31+
32+
instance semigroupMultiply :: Semigroup Multiply where
33+
append (Multiply n) (Multiply m) = Multiply (n * m)
34+
35+
instance monoidMultiply :: Monoid Multiply where
36+
mempty = Multiply 1
37+
38+
-- instance repeatAction :: Action Multiply String where
39+
-- todo
40+
-- instance actionArray :: Action m a => Action m (Array a) where
41+
-- todo
42+
newtype Self m
43+
= Self m
44+
45+
newtype Hour
46+
= Hour Int
47+
48+
instance eqHour :: Eq Hour where
49+
eq (Hour n) (Hour m) = mod n 12 == mod m 12

0 commit comments

Comments
 (0)