1
exercism fetch haskell complex-numbers

test/Tests.hs

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
{-# LANGUAGE RecordWildCards #-}

import Prelude hiding    (abs, div)
import Data.Foldable     (for_)
import Test.Hspec        (Spec, describe, it, shouldBe)
import Test.Hspec.Runner (configFastFail, defaultConfig, hspecWith)

import ComplexNumbers

main :: IO ()
main = hspecWith defaultConfig {configFastFail = True} specs

specs :: Spec
specs = do
          describe "real"      $ for_ realCases      $ testC real
          describe "imaginary" $ for_ imaginaryCases $ testC imaginary
          describe "conjugate" $ for_ conjugateCases $ testB conjugate
          describe "abs"       $ for_ absCases       $ testC abs
          describe "mul"       $ for_ mulCases       $ testA mul
          describe "div"       $ for_ divCases       $ testA div
          describe "add"       $ for_ addCases       $ testA add
          describe "sub"       $ for_ subCases       $ testA sub
 where
  testA f CaseA{..} = it descriptionA $ f (complex number1A) (complex number2A)
                                        `shouldBe` complex expectedA
  testB f CaseB{..} = it descriptionB $ f (complex number1B)
                                        `shouldBe` complex expectedB
  testC f CaseC{..} = it descriptionC $ f (complex number1C)
                                        `shouldBe` expectedC


data CaseA = CaseA { descriptionA :: String
                   , number1A     :: (Float, Float)
                   , number2A     :: (Float, Float)
                   , expectedA    :: (Float, Float)
                   }

data CaseB = CaseB { descriptionB :: String
                   , number1B     :: (Float, Float)
                   , expectedB    :: (Float, Float)
                   }

data CaseC = CaseC { descriptionC :: String
                   , number1C     :: (Float, Float)
                   , expectedC    :: Float
                   }

realCases :: [CaseC]
realCases =
    [ CaseC { descriptionC = "Real part of a purely real number"
            , number1C     = (1, 0)
            , expectedC    = 1
            }
    , CaseC { descriptionC = "Real part of a purely imaginary number"
            , number1C     = (0, 1)
            , expectedC    = 0
            }
    , CaseC { descriptionC = "Real part of a number with real and imaginary part"
            , number1C     = (1, 2)
            , expectedC    = 1
            }
    ]

imaginaryCases :: [CaseC]
imaginaryCases =
    [ CaseC { descriptionC = "Imaginary part of a purely real number"
            , number1C     = (1, 0)
            , expectedC    = 0
            }
    , CaseC { descriptionC = "Imaginary part of a purely imaginary number"
            , number1C     = (0, 1)
            , expectedC    = 1
            }
    , CaseC { descriptionC = "Imaginary part of a number with real and imaginary part"
            , number1C     = (1, 2)
            , expectedC    = 2
            }
    ]

conjugateCases :: [CaseB]
conjugateCases =
    [ CaseB { descriptionB = "Conjugate a purely real number"
            , number1B     = (5, 0)
            , expectedB    = (5, 0)
            }
    , CaseB { descriptionB = "Conjugate a purely imaginary number"
            , number1B     = (0, 5)
            , expectedB    = (0, -5)
            }
    , CaseB { descriptionB = "Conjugate a number with real and imaginary part"
            , number1B     = (1, 1)
            , expectedB    = (1, -1)
            }
    ]

absCases :: [CaseC]
absCases =
    [ CaseC { descriptionC = "Absolute value of a positive purely real number"
            , number1C     = (5, 0)
            , expectedC    = 5
            }
    , CaseC { descriptionC = "Absolute value of a negative purely real number"
            , number1C     = (-5, 0)
            , expectedC    = 5
            }
    , CaseC { descriptionC = "Absolute value of a purely imaginary number with positive imaginary part"
            , number1C     = (0, 5)
            , expectedC    = 5
            }
    , CaseC { descriptionC = "Absolute value of a purely imaginary number with negative imaginary part"
            , number1C     = (0, -5)
            , expectedC    = 5
            }
    , CaseC { descriptionC = "Absolute value of a number with real and imaginary part"
            , number1C     = (3, 4)
            , expectedC    = 5
            }
    ]

mulCases :: [CaseA]
mulCases =
    [ CaseA { descriptionA = "Multiply purely real numbers"
            , number1A     = (1, 0)
            , number2A     = (2, 0)
            , expectedA    = (2, 0)
            }
    , CaseA { descriptionA = "Multiply purely imaginary numbers"
            , number1A     = (0, 1)
            , number2A     = (0, 2)
            , expectedA    = (-2, 0)
            }
    , CaseA { descriptionA = "Multiply numbers with real and imaginary part"
            , number1A     = (1, 2)
            , number2A     = (3, 4)
            , expectedA    = (-5, 10)
            }
    ]

divCases :: [CaseA]
divCases =
    [ CaseA { descriptionA = "Divide purely real numbers"
            , number1A     = (1, 0)
            , number2A     = (2, 0)
            , expectedA    = (0.5, 0)
            }
    , CaseA { descriptionA = "Divide purely imaginary numbers"
            , number1A     = (0, 1)
            , number2A     = (0, 2)
            , expectedA    = (0.5, 0)
            }
    , CaseA { descriptionA = "Divide numbers with real and imaginary part"
            , number1A     = (1, 2)
            , number2A     = (3, 4)
            , expectedA    = (0.44, 0.08)
            }
    ]

addCases :: [CaseA]
addCases =
    [ CaseA { descriptionA = "Add purely real numbers"
            , number1A     = (1, 0)
            , number2A     = (2, 0)
            , expectedA    = (3, 0)
            }
    , CaseA { descriptionA = "Add purely imaginary numbers"
            , number1A     = (0, 1)
            , number2A     = (0, 2)
            , expectedA    = (0, 3)
            }
    , CaseA { descriptionA = "Add numbers with real and imaginary part"
            , number1A     = (1, 2)
            , number2A     = (3, 4)
            , expectedA    = (4, 6)
            }
    ]

subCases :: [CaseA]
subCases =
    [ CaseA { descriptionA = "Subtract purely real numbers"
            , number1A     = (1, 0)
            , number2A     = (2, 0)
            , expectedA    = (-1, 0)
            }
    , CaseA { descriptionA = "Subtract purely imaginary numbers"
            , number1A     = (0, 1)
            , number2A     = (0, 2)
            , expectedA    = (0, -1)
            }
    , CaseA { descriptionA = "Subtract numbers with real and imaginary part"
            , number1A     = (1, 2)
            , number2A     = (3, 4)
            , expectedA    = (-2, -2)
            }
    ]