Skip to content

Commit 1fb43e4

Browse files
Ch 4: Add unit tests (#106)
* Added unit tests * apply purty formatting * Add initial passing test so project builds Temporarily unused imports are also fine. Commented-out imports make maintenance difficult. * More filtering tests and misc text edits Co-authored-by: Miles Frain <miles.frain@colorado.edu>
1 parent bc8be7a commit 1fb43e4

File tree

5 files changed

+219
-41
lines changed

5 files changed

+219
-41
lines changed

exercises/chapter4/spago.dhall

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,17 @@
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-
[ "arrays"
9-
, "console"
10-
, "effect"
11-
, "foldable-traversable"
12-
, "maybe"
13-
, "psci-support"
14-
, "strings"
15-
]
16-
, packages =
17-
./packages.dhall
18-
, sources =
19-
[ "src/**/*.purs", "test/**/*.purs" ]
7+
[ "arrays"
8+
, "console"
9+
, "effect"
10+
, "foldable-traversable"
11+
, "maybe"
12+
, "psci-support"
13+
, "strings"
14+
, "test-unit"
15+
]
16+
, packages = ./packages.dhall
17+
, sources = [ "src/**/*.purs", "test/**/*.purs" ]
2018
}

exercises/chapter4/src/FileOperations.purs

Lines changed: 0 additions & 14 deletions
This file was deleted.

exercises/chapter4/test/Main.purs

Lines changed: 180 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,186 @@
11
module Test.Main where
22

33
import Prelude
4-
5-
import Data.Foldable (for_)
6-
import Data.Path (root)
4+
import Data.Maybe (Maybe(..))
5+
import Data.Path (filename, root)
6+
import Data.Tuple (fst)
77
import Effect (Effect)
8-
import Effect.Console (logShow)
9-
import FileOperations (allFiles)
8+
import Test.Unit (suite, test)
9+
import Test.Unit.Assert as Assert
10+
import Test.Unit.Main (runTest)
1011

1112
main :: Effect Unit
12-
main = for_ (allFiles root) logShow
13+
main =
14+
runTest do
15+
test "Initial passing test"
16+
$ Assert.equal true true
17+
18+
{- Move this block comment starting point to enable more tests
19+
suite "Exercise Group 1" do
20+
suite "Exercise 1 - Test if integer is even" do
21+
test "0 is even"
22+
$ Assert.assert "0"
23+
$ isEven 0
24+
test "1 is odd"
25+
$ Assert.assertFalse "1"
26+
$ isEven 1
27+
test "20 is even"
28+
$ Assert.assert "20"
29+
$ isEven 20
30+
test "19 is odd"
31+
$ Assert.assertFalse "19"
32+
$ isEven 19
33+
suite "Exercise 2 - Count even integers in Array" do
34+
test "[] has none"
35+
$ Assert.equal 0
36+
$ evenCount []
37+
test "[0] has 1"
38+
$ Assert.equal 1
39+
$ evenCount [ 0 ]
40+
test "[1] has 0"
41+
$ Assert.equal 0
42+
$ evenCount [ 1 ]
43+
test "[0, 1, 19, 20] has 2"
44+
$ Assert.equal 2
45+
$ evenCount [ 0, 1, 19, 20 ]
46+
suite "Exercise Group 2" do
47+
suite "Exercise 1 - Square each Number in an Array" do
48+
test "Do nothing with empty array"
49+
$ Assert.equal []
50+
$ squared []
51+
test "Calculate squares"
52+
$ Assert.equal [ 0.0, 1.0, 4.0, 9.0, 10000.0 ]
53+
$ squared [ 0.0, 1.0, 2.0, 3.0, 100.0 ]
54+
suite "Exercise 2 - Remove negative numbers in array" do
55+
test "Do nothing with empty array"
56+
$ Assert.equal []
57+
$ keepNonNegative []
58+
test "Filter negative numbers"
59+
$ Assert.equal [ 0.0, 2.0, 3.0 ]
60+
$ keepNonNegative [ -1.5, -1.0, 0.0, -0.1, 2.0, 3.0, -4.0 ]
61+
suite "Exercise 3 - <$?> operator for filter" do
62+
test "Define <$?> operator for filter"
63+
$ Assert.equal [ 1, 1 ]
64+
$ (_ == 1)
65+
<$?> [ 1, 2, 3, 1, 2, 3 ]
66+
test "Rewrite previous filtering solution using new operator"
67+
$ Assert.equal [ 0.0, 2.0, 3.0 ]
68+
$ keepNonNegativeRewrite [ -1.5, -1.0, 0.0, -0.1, 2.0, 3.0, -4.0 ]
69+
suite "Exercise Group 3" do
70+
suite "Exercise 1 - Identify prime integer" do
71+
test "0 is not prime"
72+
$ Assert.assertFalse "prime numbers start at 1"
73+
$ isPrime 0
74+
test "1 is prime"
75+
$ Assert.assert "1"
76+
$ isPrime 1
77+
test "4 is not prime"
78+
$ Assert.assertFalse "all even numbers above 2 are not prime"
79+
$ isPrime 4
80+
test "Test for large prime number"
81+
$ Assert.assert "failed for largest prime number under 1000"
82+
$ isPrime 997
83+
suite "Exercise 2 - Cartesian product" do
84+
test "Left array is empty"
85+
$ Assert.equal ([] :: Array (Array String))
86+
$ cartesianProduct [] [ "five" ]
87+
test "Right array is empty"
88+
$ Assert.equal ([] :: Array (Array String))
89+
$ cartesianProduct [ "5" ] []
90+
test "Two singleton arrays"
91+
$ Assert.equal [ [ "5", "five" ] ]
92+
$ cartesianProduct [ "5" ] [ "five" ]
93+
test "Arrays larger than singletons"
94+
$ Assert.equal [ [ "5", "five" ], [ "5", "six" ], [ "6", "five" ], [ "6", "six" ] ]
95+
$ cartesianProduct [ "5", "6" ] [ "five", "six" ]
96+
suite "Exercise 3 - Pythagorean Triple" do
97+
test "Pythagorean triple -- single element array result"
98+
$ Assert.equal [ [ 3, 4, 5 ] ]
99+
$ triples 5
100+
test "Pythagorean triple -- multiple element array result"
101+
$ Assert.equal [ [ 3, 4, 5 ], [ 5, 12, 13 ], [ 6, 8, 10 ] ]
102+
$ triples 13
103+
suite "Exercise 4 - factorizations" do
104+
test "Test small non-prime number"
105+
$ Assert.equal [ 3, 2 ]
106+
$ factorizations 6
107+
test "Test number that uses the prime numbers less than 10"
108+
$ Assert.equal [ 7, 5, 3, 2 ]
109+
$ factorizations 210
110+
suite "Exercise Group 4" do
111+
suite "Exercise 1 - foldl for true" do
112+
test "Test when all elements are true"
113+
$ Assert.assert "one of the elements wasn't true"
114+
$ allTrue [ true, true, true ]
115+
test "Test when all the elements are not true"
116+
$ Assert.assertFalse "One or more of the elements were false"
117+
$ allTrue [ true, false, true ]
118+
suite "Exercise 2 - foldl (==) false xs" do
119+
test "returns true when 1st 2 elements are false, true then trailing trues"
120+
$ Assert.assert "Failed when 1st element is false and remaining elements are true"
121+
$ exclusiveOrThenTrue [ false, true, true, true, true, true, true ]
122+
test "returns true when 1st 2 elements are true, false then trailing trues"
123+
$ Assert.assert "Failed when 1st element is true, 2nd one false, and remainder are true"
124+
$ exclusiveOrThenTrue [ true, false, true, true, true, true, true ]
125+
test "returns true when last element is false"
126+
$ Assert.assertFalse "Failed when last element is false"
127+
$ exclusiveOrThenTrue [ true, false, true, true, true, true, true, false ]
128+
suite "Exercise 3 - Rewrite fib in tail recursion" do
129+
test "Verify 0"
130+
$ Assert.equal 1
131+
$ fib 0
132+
test "Verify 1"
133+
$ Assert.equal 1
134+
$ fib 1
135+
test "Verify 2"
136+
$ Assert.equal 2
137+
$ fib 2
138+
test "Verify 5"
139+
$ Assert.equal 8
140+
$ fib 5
141+
test "Verify 7"
142+
$ Assert.equal 21
143+
$ fib 7
144+
test "Verify 9"
145+
$ Assert.equal 55
146+
$ fib 9
147+
test "Verify 44"
148+
$ Assert.equal 1134903170
149+
$ fib 44
150+
suite "Exercise 4: reverse in terms of foldl" do
151+
test "Empty Array"
152+
$ Assert.equal ([] :: Array Int)
153+
$ reverse []
154+
test "Singleton Array"
155+
$ Assert.equal [ 1 ]
156+
$ reverse [ 1 ]
157+
test "More than 1 element"
158+
$ Assert.equal [ 3, 2, 1 ]
159+
$ reverse [ 1, 2, 3 ]
160+
suite "Exercise Group 5" do
161+
suite "Exercise 1: onlyFiles" do
162+
test "all files under root"
163+
$ Assert.equal
164+
[ "/bin/cp"
165+
, "/bin/ls"
166+
, "/bin/mv"
167+
, "/etc/hosts"
168+
, "/home/user/todo.txt"
169+
, "/home/user/code/js/test.js"
170+
, "/home/user/code/haskell/test.hs"
171+
]
172+
$ map filename
173+
$ onlyFiles root
174+
suite "Exercise 2: find largest and smallest files" do
175+
test "largestSmallest for root"
176+
$ Assert.equal [ "/home/user/code/js/test.js", "/etc/hosts" ]
177+
$ map fst
178+
$ largestSmallest root
179+
suite "Exercise 3: whereIs" do
180+
test "locates a file"
181+
$ Assert.equal (Just ("/bin/"))
182+
$ whereIs "ls"
183+
test "doesn't locate a file"
184+
$ Assert.equal (Nothing)
185+
$ whereIs "lss"
186+
-}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
module Test.Solutions where
2+
3+
import Prelude
4+
import Data.Array ((:), (..))
5+
import Data.Path (Path, ls)
6+
import Control.MonadZero (guard)
7+
8+
factors :: Int -> Array (Array Int)
9+
factors n = do
10+
i <- 1 .. n
11+
j <- i .. n
12+
guard $ i * j == n
13+
pure [ i, j ]
14+
15+
-- Section for : A Virtual Filesystem exercise
16+
allFiles :: Path -> Array Path
17+
allFiles file =
18+
file
19+
: do
20+
child <- ls file
21+
allFiles child

text/chapter4.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,7 @@ The motivating example for this chapter is a library of functions for working wi
1010

1111
## Project Setup
1212

13-
The source code for this chapter is contained in the two files `src/Data/Path.purs` and `src/FileOperations.purs`.
14-
15-
The `Data.Path` module contains a model of a virtual filesystem. You do not need to modify the contents of this module.
16-
17-
The `FileOperations` module contains functions which use the `Data.Path` API. Solutions to the exercises can be completed in this file.
13+
The source code for this chapter is contained in `src/Data/Path.purs` and `test/Solutions.purs`. The `Data.Path` module contains a model of a virtual filesystem. You do not need to modify the contents of this module. Implement your solutions to the exercises in the `Test.Solutions` module.
1814

1915
The project has the following dependencies:
2016

@@ -193,7 +189,10 @@ For example, suppose we wanted to compute an array of all numbers between 1 and
193189

194190
1. (Easy) Use the `map` or `<$>` function to write a function which calculates the squares of an array of numbers.
195191
1. (Easy) Use the `filter` function to write a function which removes the negative numbers from an array of numbers.
196-
1. (Medium) Define an infix synonym `<$?>` for `filter`. Rewrite your answer to the previous question to use your new operator. Experiment with the precedence level and associativity of your operator in PSCi.
192+
1. (Medium)
193+
* Define an infix synonym `<$?>` for `filter`.
194+
* Rewrite your answer to the previous question to use your new operator.
195+
* Experiment with the precedence level and associativity of your operator in PSCi. NOTE: no unit tests for this.
197196

198197
## Flattening Arrays
199198

@@ -650,7 +649,7 @@ Try out the new version in PSCi - you should get the same result. I'll let you d
650649
```text
651650
> whereIs "/bin/ls"
652651
Just (/bin/)
653-
652+
654653
> whereIs "/bin/cat"
655654
Nothing
656655
```

0 commit comments

Comments
 (0)