git.iko.soy/typeable/hjsonpointer
on 1.3.0 help sign in
85 lines 2.6 kB history raw
2module Main where
4import Data.Aeson
5import Data.Bifunctor (first)
6import Data.Foldable
7import Data.Monoid
8import Data.Text (Text)
9import qualified Data.Text as T
10import Data.Text.Encoding (decodeUtf8, encodeUtf8)
11import qualified Data.Vector as V
12import qualified JSONPointer as JP
13import Network.HTTP.Types.URI (urlDecode)
15import Test.Hspec
16import Test.QuickCheck (property)
18import qualified Example
20main :: IO ()
21main = hspec $ do
22 describe "example" $ do
23 it "compiles and runs without errors" Example.main
24 describe "pointers" $ do
25 it "can be stored as JSON without changing its value" (property roundtrip)
26 it "can be represented in a JSON string value" jsonString
27 it "can be represented in a URI fragment identifier" uriFragment
29roundtrip :: JP.Pointer -> Bool
30roundtrip a = Just a == decode (encode a)
32jsonString :: Expectation
33jsonString = traverse_ resolvesTo
34 [ ("" , specExample)
35 , ("/foo" , Array $ V.fromList ["bar", "baz"])
36 , ("/foo/0", String "bar")
37 , ("/" , Number 0)
38 , ("/a~1b" , Number 1)
39 , ("/c%d" , Number 2)
40 , ("/e^f" , Number 3)
41 , ("/g|h" , Number 4)
42 , ("/i\\j" , Number 5)
43 , ("/k\"l" , Number 6)
44 , ("/ " , Number 7)
45 , ("/m~0n" , Number 8)
46 ]
48uriFragment :: Expectation
49uriFragment = traverse_ resolvesTo . fmap (first decodeFragment) $
50 [ ("#" , specExample)
51 , ("#/foo" , Array $ V.fromList ["bar", "baz"])
52 , ("#/foo/0", String "bar")
53 , ("#/" , Number 0)
54 , ("#/a~1b" , Number 1)
55 , ("#/c%25d", Number 2)
56 , ("#/e%5Ef", Number 3)
57 , ("#/g%7Ch", Number 4)
58 , ("#/i%5Cj", Number 5)
59 , ("#/k%22l", Number 6)
60 , ("#/%20" , Number 7)
61 , ("#/m~0n" , Number 8)
62 ]
63 where
64 decodeFragment :: Text -> Text
65 decodeFragment = T.drop 1 . decodeUtf8 . urlDecode True . encodeUtf8
67resolvesTo :: (Text, Value) -> Expectation
68resolvesTo (t, expected) =
69 case JP.unescape t of
70 Left e -> expectationFailure (show e <> " error for pointer: " <> show t)
71 Right p -> JP.resolve p specExample `shouldBe` Right expected
73specExample :: Value
74specExample = object
75 [ "foo" .= (["bar", "baz"] :: [Text])
76 , "" .= (0 :: Int)
77 , "a/b" .= (1 :: Int)
78 , "c%d" .= (2 :: Int)
79 , "e^f" .= (3 :: Int)
80 , "g|h" .= (4 :: Int)
81 , "i\\j" .= (5 :: Int)
82 , "k\"l" .= (6 :: Int)
83 , " " .= (7 :: Int)
84 , "m~n" .= (8 :: Int)
85 ]