packages feed

hjsonpointer-0.2.0.0: tests/Unit.hs

module Main where

import           Control.Applicative
import           Control.Arrow
import           Control.Monad
import           Data.Aeson
import qualified Data.HashMap.Strict            as H
import           Data.JsonPointer
import           Data.Monoid
import           Data.Text                      (Text)
import qualified Data.Text                      as T
import           Data.Text.Encoding
import qualified Data.Vector                    as V
import           Network.HTTP.Types.URI
import           Test.Framework                 (defaultMain, testGroup)
import           Test.Framework.Providers.HUnit (testCase)
import           Test.HUnit                     hiding (Test)


main :: IO ()
main = defaultMain
  [ testGroup "unit"
    [ testCase "Can be represented in a JSON string value" jsonString
    , testCase "Can be represented in a URI fragment identifier" uriFragment
    ]
  ]

specExample :: Value
specExample =
  Object $ H.fromList
    [ ("foo" , Array $ V.fromList ["bar", "baz"])
    , (""    , Number 0)
    , ("a/b" , Number 1)
    , ("c%d" , Number 2)
    , ("e^f" , Number 3)
    , ("g|h" , Number 4)
    , ("i\\j", Number 5)
    , ("k\"l", Number 6)
    , (" "   , Number 7)
    , ("m~n" , Number 8)
    ]

resolvesTo :: (Text, Value) -> Assertion
resolvesTo (t, expected) =
  case jsonPointer t of
    Left e  -> assertFailure (show e <> " error for pointer: " <> show t)
    Right p ->
      assertEqual ("Resolved value for pointer: " <> show t)
        (Right expected)
        $ resolvePointer p specExample

jsonString :: Assertion
jsonString =
  void $ mapM resolvesTo
    [ (""      , specExample)
    , ("/foo"  , Array $ V.fromList ["bar", "baz"])
    , ("/foo/0", String "bar")
    , ("/"     , Number 0)
    , ("/a~1b" , Number 1)
    , ("/c%d"  , Number 2)
    , ("/e^f"  , Number 3)
    , ("/g|h"  , Number 4)
    , ("/i\\j" , Number 5)
    , ("/k\"l" , Number 6)
    , ("/ "    , Number 7)
    , ("/m~0n" , Number 8)
    ]

uriFragment :: Assertion
uriFragment =
  void $ mapM resolvesTo $ first decodeFragment <$>
    [ ("#"      , specExample)
    , ("#/foo"  , Array $ V.fromList ["bar", "baz"])
    , ("#/foo/0", String "bar")
    , ("#/"     , Number 0)
    , ("#/a~1b" , Number 1)
    , ("#/c%25d", Number 2)
    , ("#/e%5Ef", Number 3)
    , ("#/g%7Ch", Number 4)
    , ("#/i%5Cj", Number 5)
    , ("#/k%22l", Number 6)
    , ("#/%20"  , Number 7)
    , ("#/m~0n" , Number 8)
    ]
  where
    decodeFragment :: Text -> Text
    decodeFragment = T.drop 1 . decodeUtf8 . urlDecode True . encodeUtf8