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