on master help sign in
jrec/test/JRecSpec.hs
122 lines 5.1 kB history raw
1module JRecSpec (spec) where
3import Control.Lens ((&), (.~), (^.))
4import Data.Aeson
5import GHC.Stack
6import JRec
7import Test.Hspec
9data Pair a = Pair !a !a
10 deriving (Eq, Show)
12spec :: HasCallStack => Spec
13spec = do
14 it "is not crazy" $ do
15 Pair (Rec (#a := 1)) (Rec (#a := 2))
16 `shouldNotBe` Pair (Rec (#a := 1)) (Rec (#a := 1))
17 Pair (Rec (#a := 1)) (Rec (#a := 2))
18 `shouldNotBe` Pair (Rec (#a := 2)) (Rec (#a := 2))
19 it "polymorphic" $ do
20 (Rec (#u := True, #a := 5, #b := 6, #a := 2) & #u .~ 5)
21 `shouldBe` Rec (#u := 5, #a := 5, #b := 6, #a := 2)
22 describe "eq" $ do
23 -- eq can compare only the first matching field, discarding the rest.
24 it "fails if first matching field doesn't compare" $ do
25 Rec (#a := 1, #a := 2) `shouldNotBe` Rec (#a := 0, #a := 2)
26 it "succeeds if first matching field compares" $ do
27 Rec (#a := 1, #a := 2) `shouldBe` Rec (#a := 1, #a := 0)
28 it "ord" $ do
29 -- Same as eq when there is duplicated keys.
30 -- Only the first occurence of that key is considered.
31 compare (Rec (#a := 1, #a := 2)) (Rec (#a := 1, #a := 2)) `shouldBe` EQ
32 compare (Rec (#a := 1, #a := 2)) (Rec (#a := 1, #a := 3)) `shouldBe` EQ
33 compare (Rec (#a := 1, #a := 2)) (Rec (#a := 2, #a := 1)) `shouldBe` LT
34 compare (Rec (#a := 1, #a := 2)) (Rec (#a := 0, #a := 3)) `shouldBe` GT
35 compare (Rec (#a := 1, #b := 2)) (Rec (#a := 1, #b := 2)) `shouldBe` EQ
36 compare (Rec (#a := 1, #b := 2)) (Rec (#a := 1, #b := 3)) `shouldBe` LT
37 compare (Rec (#a := 1, #b := 2)) (Rec (#a := 2, #b := 1)) `shouldBe` LT
38 compare (Rec (#a := 1, #b := 2)) (Rec (#a := 0, #b := 3)) `shouldBe` GT
39 compare (Rec (#a := 1, #a := 2, #b := 3)) (Rec (#a := 1, #a := 3, #b := 2)) `shouldBe` GT
40 it "show" $ do
41 show (Rec ()) `shouldBe` "{}"
42 show (Rec (#foo := True)) `shouldBe` "{foo = True}"
43 show (Rec (#foo := True, #bar := 0)) `shouldBe` "{foo = True, bar = 0}"
44 it "get" $ do
45 let getA1 :: Rec ("a" := Int ': rest) -> Int
46 getA1 = (^. #a)
47 let getA2 :: Rec ("u" := Bool ': "a" := Int ': rest) -> Int
48 getA2 = (^. #a)
49 getA1 (Rec (#a := 5)) `shouldBe` 5
50 getA1 (Rec (#a := 5, #b := 6)) `shouldBe` 5
51 getA2 (Rec (#u := True, #a := 5)) `shouldBe` 5
52 getA2 (Rec (#u := True, #a := 5, #b := 6)) `shouldBe` 5
53 it "set" $ do
54 let setA1 ::
55 Rec ("a" := Int ': rest) ->
56 Rec ("a" := Int ': rest)
57 setA1 = (#a .~ 8)
58 let setA2 ::
59 Rec ("u" := Bool ': "a" := Int ': rest) ->
60 Rec ("u" := Bool ': "a" := Int ': rest)
61 setA2 = (#a .~ 8)
62 setA1 (Rec (#a := 5))
63 `shouldBe` (Rec (#a := 8))
64 setA1 (Rec (#a := 5, #b := 6))
65 `shouldBe` (Rec (#a := 8, #b := 6))
66 setA2 (Rec (#u := True, #a := 5))
67 `shouldBe` (Rec (#u := True, #a := 8))
68 setA2 (Rec (#u := True, #a := 5, #b := 6))
69 `shouldBe` (Rec (#u := True, #a := 8, #b := 6))
70 describe "append" $ do
71 it "simple append" $ do
72 Rec (#a := 1) `append` Rec (#b := 2)
73 `shouldBe` Rec (#a := 1, #b := 2)
74 Rec () `append` Rec (#b := 2)
75 `shouldBe` Rec (#b := 2)
76 Rec (#a := 1) `append` Rec ()
77 `shouldBe` Rec (#a := 1)
78 Rec (#a := 1, #b := 2) `append` Rec (#c := 3)
79 `shouldBe` Rec (#a := 1, #b := 2, #c := 3)
80 Rec (#a := 1) `append` Rec (#b := 2, #c := 3)
81 `shouldBe` Rec (#a := 1, #b := 2, #c := 3)
82 Rec (#a := 1, #b := 2) `append` Rec (#c := 3, #d := 4)
83 `shouldBe` Rec (#a := 1, #b := 2, #c := 3, #d := 4)
84 it "append with duplicates" $ do
85 let r1 = Rec (#b := 5, #a := 6)
86 r2 = Rec (#c := 7, #a := 8)
87 r1 `append` r2
88 `shouldBe` Rec (#b := 5, #a := 6, #c := 7, #a := 8)
89 describe "union" $ do
90 it "simple union" $ do
91 Rec (#a := 1) `union` Rec (#b := 2)
92 `shouldBe` Rec (#a := 1, #b := 2)
93 it "union with duplicates (left-biased)" $ do
94 let r1 = Rec (#b := 5, #a := 6)
95 r2 = Rec (#c := 7, #a := 8)
96 r1 `union` r2
97 `shouldBe` Rec (#b := 5, #a := 6, #c := 7)
98 describe "insert" $ do
99 it "simple insert" $ do
100 (#a := 1) `insert` Rec (#b := 2, #c := 3)
101 `shouldBe` Rec (#a := 1, #b := 2, #c := 3)
102 describe "insertOrSet" $ do
103 it "distinct" $ do
104 insertOrSet (#a := 1) (Rec (#b := 2, #c := 3))
105 `shouldBe` Rec (#a := 1, #b := 2, #c := 3)
106 it "overwrite" $ do
107 insertOrSet (#c := 1) (Rec (#b := 2, #c := 3))
108 `shouldBe` Rec (#b := 2, #c := 1)
109 describe "optional fields" $ do
110 it "encode" $ do
111 encode (Rec (#a := (1 :: Int), #b := (Nothing :: Maybe Int)))
112 `shouldBe` "{\"a\":1}"
113 it "encode" $ do
114 encode (Rec (#a := (1 :: Int), #b := (Just 2 :: Maybe Int)))
115 `shouldBe` "{\"a\":1,\"b\":2}"
116 it "decode" $ do
117 decode "{\"a\": 1}"
118 `shouldBe` Just (Rec (#a := (1 :: Int), #b := (Nothing :: Maybe Int)))
119 decode "{\"a\": 1, \"b\": null}"
120 `shouldBe` Just (Rec (#a := (1 :: Int), #b := (Nothing :: Maybe Int)))
121 decode "{\"a\": 1, \"b\": 2}"
122 `shouldBe` Just (Rec (#a := (1 :: Int), #b := (Just 2 :: Maybe Int)))