forked from paf31/purescript-book
-
Notifications
You must be signed in to change notification settings - Fork 190
/
Main.purs
268 lines (264 loc) · 8.73 KB
/
Main.purs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
module Test.Main where
import Prelude
import Test.Examples
import Test.MySolutions
import Test.NoPeeking.Solutions -- This line should have been automatically deleted by resetSolutions.sh. See Chapter 2 for instructions.
import Data.Array (sort)
import Data.Foldable (sequence_)
import Data.Maybe (Maybe(..))
import Data.Path (Path(..), filename, root)
import Data.Tuple.Nested ((/\))
import Effect (Effect)
import Test.Unit (TestSuite, suite, test)
import Test.Unit.Assert (assert, assertFalse)
import Test.Unit.Assert as Assert
import Test.Unit.Main (runTest)
main :: Effect Unit
main =
runTest do
runChapterExamples
{- Move this block comment starting point to enable more tests
This line should have been automatically deleted by resetSolutions.sh. See Chapter 2 for instructions. -}
suite "Exercise Group - Recursion" do
suite "Exercise - isEven" do
test "0 is even" do
Assert.equal true
$ isEven 0
test "1 is odd" do
Assert.equal false
$ isEven 1
test "20 is even" do
Assert.equal true
$ isEven 20
test "19 is odd" do
Assert.equal false
$ isEven 19
test "-1 is odd" do
Assert.equal false
$ isEven (-1)
test "-20 is even" do
Assert.equal true
$ isEven (-20)
test "-19 is odd" do
Assert.equal false
$ isEven (-19)
suite "Exercise - countEven" do
test "[] has none" do
Assert.equal 0
$ countEven []
test "[0] has 1" do
Assert.equal 1
$ countEven [ 0 ]
test "[1] has 0" do
Assert.equal 0
$ countEven [ 1 ]
test "[0, 1, 19, 20] has 2" do
Assert.equal 2
$ countEven [ 0, 1, 19, 20 ]
suite "Exercise Group - Maps, Infix Operators, and Filtering" do
suite "Exercise - squared" do
test "Do nothing with empty array" do
Assert.equal []
$ squared []
test "Calculate squares" do
Assert.equal [ 0.0, 1.0, 4.0, 9.0, 10000.0 ]
$ squared [ 0.0, 1.0, 2.0, 3.0, 100.0 ]
suite "Exercise - keepNonNegative" do
test "Do nothing with empty array" do
Assert.equal []
$ keepNonNegative []
test "Filter negative numbers" do
Assert.equal [ 0.0, 2.0, 3.0 ]
$ keepNonNegative [ -1.5, -1.0, 0.0, -0.1, 2.0, 3.0, -4.0 ]
suite "Exercise - <$?> infix operator for filter" do
test "Define <$?> operator for filter" do
Assert.equal [ 1, 1 ]
$ (_ == 1)
<$?> [ 1, 2, 3, 1, 2, 3 ]
test "keepNonNegativeRewrite " do
Assert.equal [ 0.0, 2.0, 3.0 ]
$ keepNonNegativeRewrite [ -1.5, -1.0, 0.0, -0.1, 2.0, 3.0, -4.0 ]
suite "Exercise Group - Flattening, Comprehensions, Do Notation, and Guards" do
test "Exercise - isPrime" do
assertFalse "0 is not prime"
$ isPrime 0
assertFalse "1 is not prime"
$ isPrime 1
assert "2 is prime"
$ isPrime 2
assertFalse "4 is not prime"
$ isPrime 4
assert "997 is prime"
$ isPrime 997
suite "Exercise - cartesianProduct" do
let
-- Don't worry if this this testing helper function signature looks confusing.
-- It will make more sense after chapter 6
testcp :: forall a. Eq a => Show a => Ord a => String -> Array (Array a) -> Array a -> Array a -> TestSuite
testcp label expected arr1 arr2 =
test label do
-- Sorting to allow any ordering
Assert.equal (sort expected)
$ sort
$ cartesianProduct arr1 arr2
testcp "Left array is empty" [] [] [ "five" ]
testcp "Right array is empty" [] [ "5" ] []
testcp "Two singleton arrays"
[ [ "5", "five" ] ]
[ "5" ]
[ "five" ]
testcp "Arrays larger than singletons"
[ [ "5", "five" ], [ "5", "six" ], [ "6", "five" ], [ "6", "six" ] ]
[ "5", "6" ]
[ "five", "six" ]
suite "Exercise - triples" do
-- Sorting to allow for any ordering
test "single element array result" do
Assert.equal (sort [ [ 3, 4, 5 ] ])
$ sort
$ triples 5
test "multiple element array result" do
Assert.equal (sort [ [ 3, 4, 5 ], [ 5, 12, 13 ], [ 6, 8, 10 ] ])
$ sort
$ triples 13
suite "Exercise - primeFactors" do
let
primeFactorsTest :: Int -> Array Int -> _
primeFactorsTest n xs =
test (show n) do
Assert.equal (sort xs)
$ sort
$ primeFactors n
primeFactorsTest 1 []
primeFactorsTest 2 [2]
primeFactorsTest 3 [3]
primeFactorsTest 4 [2, 2]
primeFactorsTest 6 [3, 2]
primeFactorsTest 18 [3, 3, 2]
primeFactorsTest 210 [ 7, 5, 3, 2 ]
suite "Exercise Group - Folds and Tail Recursion" do
test "Exercise - allTrue" do
assert "all elements true"
$ allTrue [ true, true, true ]
assertFalse "some elements false"
$ allTrue [ true, false, true ]
suite "Exercise - fibTailRec" do
test "Verify 0" do
Assert.equal 0
$ fibTailRec 0
test "Verify 9" do
Assert.equal 34
$ fibTailRec 9
test "Verify 44" do
Assert.equal 701408733
$ fibTailRec 44
suite "Exercise - reverse" do
test "Empty Array" do
Assert.equal ([] :: Array Int)
$ reverse []
test "Singleton Array" do
Assert.equal [ 1 ]
$ reverse [ 1 ]
test "More than 1 element" do
Assert.equal [ 3, 2, 1 ]
$ reverse [ 1, 2, 3 ]
suite "Exercise Group - Filesystem" do
test "Exercise - onlyFiles" do
Assert.equal
[ "/bin/cp"
, "/bin/ls"
, "/bin/mv"
, "/etc/hosts"
, "/home/user/todo.txt"
, "/home/user/code/js/test.js"
, "/home/user/code/haskell/test.hs"
]
$ map filename
$ onlyFiles root
suite "Exercise - whereIs" do
test "locates a file"
$ Assert.equal (Just ("/bin/"))
$ map filename
$ whereIs root "ls"
test "doesn't locate a file"
$ Assert.equal (Nothing)
$ map filename
$ whereIs root "cat"
suite "Exercise - largestSmallest" do
let
testls :: String -> Array String -> Path -> TestSuite
testls label expected path =
test label do
Assert.equal expected
-- Sorting to allow any ordering
$ sort
$ map filename
$ largestSmallest path
oneFileDir = Directory "/etc/" [ File "/etc/hosts" 300 ]
emptyDir = Directory "/etc/" []
testls "works for root" ["/etc/hosts", "/home/user/code/js/test.js"] root
testls "works for a directory with one file" ["/etc/hosts"] oneFileDir
testls "works for an empty directory" [] emptyDir
{- This line should have been automatically deleted by resetSolutions.sh. See Chapter 2 for instructions.
-}
runChapterExamples :: TestSuite
runChapterExamples =
suite "Chapter Examples" do
test "factorial" do
Assert.equal 120
$ factorial 5
test "fib" do
Assert.equal 34
$ fib 9
test "length" do
Assert.equal 3
$ length [ 0, 0, 0 ]
sequence_ do
name /\ f <-
[ "factors" /\ factors
, "factorsV2" /\ factorsV2
, "factorsV3" /\ factorsV3
]
n /\ xs <-
[ 1 /\ [[1,1]]
, 2 /\ [[1,2]]
, 3 /\ [[1,3]]
, 4 /\ [[1,4],[2,2]]
, 10 /\ [[1,10],[2,5]]
, 100 /\ [[1,100],[2,50],[4,25],[5,20],[10,10]]
]
pure $ test (name <> " " <> show n) do
Assert.equal (sort $ map sort xs)
$ sort $ map sort f n
test "factorialTailRec" do
Assert.equal 120
$ factorialTailRec 5 1
test "lengthTailRec" do
Assert.equal 3
$ lengthTailRec [ 0, 0, 0 ]
test "allFiles" do
Assert.equal allFileAndDirectoryNames
$ filename
<$> allFiles root
test "allFiles'" do
Assert.equal allFileAndDirectoryNames
$ filename
<$> allFiles' root
allFileAndDirectoryNames :: Array (String)
allFileAndDirectoryNames =
[ "/"
, "/bin/"
, "/bin/cp"
, "/bin/ls"
, "/bin/mv"
, "/etc/"
, "/etc/hosts"
, "/home/"
, "/home/user/"
, "/home/user/todo.txt"
, "/home/user/code/"
, "/home/user/code/js/"
, "/home/user/code/js/test.js"
, "/home/user/code/haskell/"
, "/home/user/code/haskell/test.hs"
]