|
1 |
| -import Test.HUnit (Assertion, (@=?), runTestTT, Test(..), Counts(..)) |
2 |
| -import System.Exit (ExitCode(..), exitWith) |
3 |
| -import Matrix ( Matrix, row, column, rows, cols, shape, transpose |
4 |
| - , reshape, flatten, fromString, fromList) |
5 |
| -import Control.Arrow ((&&&)) |
6 |
| -import qualified Data.Vector as V |
| 1 | +import Control.Arrow ((&&&)) |
| 2 | +import Test.Hspec (Spec, describe, it, shouldBe, shouldSatisfy) |
| 3 | +import Test.Hspec.Runner (configFastFail, defaultConfig, hspecWith) |
7 | 4 |
|
8 |
| --- Implementation of a row-major matrix for any type, using Data.Vector. |
| 5 | +import qualified Data.Vector as Vector (fromList) |
9 | 6 |
|
10 |
| --- fromString should work for any type that implements the Read typeclass. |
11 |
| --- You can assume that "\n" is used to delimit rows without context |
12 |
| --- sensitivity, but treatment of whitespace in a row should be context |
13 |
| --- sensitive! |
| 7 | +import Matrix |
| 8 | + ( Matrix |
| 9 | + , cols |
| 10 | + , column |
| 11 | + , flatten |
| 12 | + , fromList |
| 13 | + , fromString |
| 14 | + , reshape |
| 15 | + , row |
| 16 | + , rows |
| 17 | + , shape |
| 18 | + , transpose |
| 19 | + ) |
14 | 20 |
|
15 |
| --- No validation of input is required. Let it fail if the matrix is not |
16 |
| --- rectangular, invalid chars are encountered, etc. |
| 21 | +main :: IO () |
| 22 | +main = hspecWith defaultConfig {configFastFail = True} specs |
17 | 23 |
|
18 |
| --- shape is (rows, cols) |
| 24 | +specs :: Spec |
| 25 | +specs = describe "matrix" $ do |
19 | 26 |
|
20 |
| -exitProperly :: IO Counts -> IO () |
21 |
| -exitProperly m = do |
22 |
| - counts <- m |
23 |
| - exitWith $ if failures counts /= 0 || errors counts /= 0 then ExitFailure 1 else ExitSuccess |
| 27 | + -- As of 2016-08-08, there was no reference file |
| 28 | + -- for the test cases in `exercism/x-common`. |
24 | 29 |
|
25 |
| -testCase :: String -> Assertion -> Test |
26 |
| -testCase label assertion = TestLabel label (TestCase assertion) |
| 30 | + let intMatrix = fromString :: String -> Matrix Int |
| 31 | + let vector = Vector.fromList |
27 | 32 |
|
28 |
| -main :: IO () |
29 |
| -main = exitProperly $ runTestTT $ TestList |
30 |
| - [ TestList matrixTests ] |
31 |
| - |
32 |
| -v :: [a] -> V.Vector a |
33 |
| -v = V.fromList |
34 |
| - |
35 |
| -msInt :: String -> Matrix Int |
36 |
| -msInt = fromString |
37 |
| - |
38 |
| -msInteger :: String -> Matrix Integer |
39 |
| -msInteger = fromString |
40 |
| - |
41 |
| -msChar :: String -> Matrix Char |
42 |
| -msChar = fromString |
43 |
| - |
44 |
| -msString :: String -> Matrix String |
45 |
| -msString = fromString |
46 |
| - |
47 |
| -matrixTests :: [Test] |
48 |
| -matrixTests = |
49 |
| - [ testCase "extract first row" $ do |
50 |
| - v [1, 2] @=? row 0 (msInt "1 2\n10 20") |
51 |
| - v [9, 7] @=? row 0 (msInteger "9 7\n8 6") |
52 |
| - , testCase "extract second row" $ do |
53 |
| - v [19, 18, 17] @=? row 1 (msInt "9 8 7\n19 18 17") |
54 |
| - v [16, 25, 36] @=? row 1 (msInteger "1 4 9\n16 25 36") |
55 |
| - , testCase "extract first column" $ do |
56 |
| - v [1, 4, 7, 8] @=? column 0 (msInt "1 2 3\n4 5 6\n7 8 9\n 8 7 6") |
57 |
| - v [1903, 3, 4] @=? column 1 (msInteger "89 1903 3\n18 3 1\n9 4 800") |
58 |
| - , testCase "shape" $ do |
59 |
| - (0, 0) @=? shape (msInt "") |
60 |
| - (1, 1) @=? shape (msInt "1") |
61 |
| - (2, 1) @=? shape (msInt "1\n2") |
62 |
| - (1, 2) @=? shape (msInt "1 2") |
63 |
| - (2, 2) @=? shape (msInt "1 2\n3 4") |
64 |
| - , testCase "rows & cols" $ |
65 |
| - (1, 2) @=? (rows &&& cols) (msInt "1 2") |
66 |
| - , testCase "eq" $ |
67 |
| - msInt "1 2" @=? msInt "1 2" |
68 |
| - , testCase "fromList" $ do |
69 |
| - msInt "1 2" @=? fromList [[1, 2]] |
70 |
| - msInt "1\n2" @=? fromList [[1], [2]] |
71 |
| - , testCase "transpose" $ do |
72 |
| - msInt "1 2 3" @=? transpose (msInt "1\n2\n3") |
73 |
| - msInt "1 2 3\n4 5 6" @=? transpose (msInt "1 4\n2 5\n3 6") |
74 |
| - , testCase "reshape" $ do |
75 |
| - msInt "1 2\n3 4" @=? reshape (2, 2) (msInt "1 2 3 4") |
76 |
| - , testCase "flatten" $ do |
77 |
| - v [1, 2, 3, 4] @=? flatten (msInt "1 2\n3 4") |
78 |
| - , testCase "matrix of chars" $ do |
79 |
| - fromList ["foo", "bar"] @=? msChar "'f' 'o' 'o'\n'b' 'a' 'r'" |
80 |
| - , testCase "matrix of strings" $ do |
81 |
| - fromList [["this one"], ["may be tricky!"]] @=? |
82 |
| - msString "\"this one\"\n\"may be tricky!\"" |
83 |
| - , testCase "matrix of strings 2" $ do |
84 |
| - fromList [["this one", "one"], ["may be tricky!", "really tricky"]] @=? |
85 |
| - msString "\"this one\" \"one\" \n\"may be tricky!\" \"really tricky\"" |
86 |
| - |
87 |
| - ] |
| 33 | + it "extract first row" $ do |
| 34 | + row 0 (intMatrix "1 2\n10 20") `shouldBe` vector [1, 2] |
| 35 | + row 0 (intMatrix "9 7\n8 6" ) `shouldBe` vector [9, 7] |
| 36 | + |
| 37 | + it "extract second row" $ do |
| 38 | + row 1 (intMatrix "9 8 7\n19 18 17") `shouldBe` vector [19, 18, 17] |
| 39 | + row 1 (intMatrix "1 4 9\n16 25 36") `shouldBe` vector [16, 25, 36] |
| 40 | + |
| 41 | + it "extract first column" $ do |
| 42 | + column 0 (intMatrix "1 2 3\n4 5 6\n7 8 9\n 8 7 6") |
| 43 | + `shouldBe` vector [1, 4, 7, 8] |
| 44 | + column 1 (intMatrix "89 1903 3\n18 3 1\n9 4 800") |
| 45 | + `shouldBe` vector [1903, 3, 4] |
| 46 | + |
| 47 | + it "shape" $ do |
| 48 | + shape (intMatrix "" ) `shouldBe` (0, 0) |
| 49 | + shape (intMatrix "1" ) `shouldBe` (1, 1) |
| 50 | + shape (intMatrix "1\n2" ) `shouldBe` (2, 1) |
| 51 | + shape (intMatrix "1 2" ) `shouldBe` (1, 2) |
| 52 | + shape (intMatrix "1 2\n3 4") `shouldBe` (2, 2) |
| 53 | + |
| 54 | + it "rows & cols" $ |
| 55 | + (rows &&& cols) (intMatrix "1 2") `shouldBe` (1, 2) |
| 56 | + |
| 57 | + it "eq" $ do |
| 58 | + |
| 59 | + -- `shouldNotBe` is not availabe on lts-2.22. |
| 60 | + let x `shouldNotBe` y = x `shouldSatisfy` (/= y) |
| 61 | + |
| 62 | + intMatrix "1 2" `shouldBe` intMatrix "1 2" |
| 63 | + intMatrix "2 3" `shouldNotBe` intMatrix "1 2 3" |
| 64 | + |
| 65 | + it "fromList" $ do |
| 66 | + fromList [[1 , 2]] `shouldBe` intMatrix "1 2" |
| 67 | + fromList [[1], [2]] `shouldBe` intMatrix "1\n2" |
| 68 | + |
| 69 | + it "transpose" $ do |
| 70 | + transpose (intMatrix "1\n2\n3" ) `shouldBe` intMatrix "1 2 3" |
| 71 | + transpose (intMatrix "1 4\n2 5\n3 6") `shouldBe` intMatrix "1 2 3\n4 5 6" |
| 72 | + |
| 73 | + it "reshape" $ do |
| 74 | + reshape (2, 2) (intMatrix "1 2 3 4") `shouldBe` intMatrix "1 2\n3 4" |
| 75 | + |
| 76 | + it "flatten" $ do |
| 77 | + flatten (intMatrix "1 2\n3 4") `shouldBe` vector [1, 2, 3, 4] |
| 78 | + |
| 79 | + it "matrix of chars" $ do |
| 80 | + fromString "'f' 'o' 'o'\n'b' 'a' 'r'" `shouldBe` fromList ["foo", "bar"] |
| 81 | + |
| 82 | + it "matrix of strings" $ do |
| 83 | + fromString "\"this one\"\n\"may be tricky!\"" |
| 84 | + `shouldBe` fromList [ ["this one" ] |
| 85 | + , ["may be tricky!"] ] |
| 86 | + |
| 87 | + it "matrix of strings 2" $ do |
| 88 | + fromString "\"this one\" \"one\" \n\"may be tricky!\" \"really tricky\"" |
| 89 | + `shouldBe` fromList [ ["this one" , "one" ] |
| 90 | + , ["may be tricky!", "really tricky"] ] |
0 commit comments