packages feed

avers-0.0.7: test/Test.hs

{-# LANGUAGE OverloadedStrings #-}

module Main where

import           Test.Hspec
import           Control.Exception (evaluate)

import           Data.Aeson          as A
import           Data.Aeson.Types
import qualified Data.Vector         as V
import qualified Data.HashMap.Strict as HMS

import           Avers
import           Avers.Types (PatchM)
import           Avers.Patching

isFailure :: PatchM a -> Bool
isFailure (Left  _) = True
isFailure (Right _) = False

isSuccess :: PatchM a -> Bool
isSuccess (Left  _) = False
isSuccess (Right _) = True

main :: IO ()
main = hspec spec

objA :: A.Value
objA = A.Object $ HMS.fromList [("id", A.String "foo"),("bar", A.String "baz")]

spec :: Spec
spec = parallel $ do

    describe "resolvePathIn" $ do
        it "should return the value if the path is empty" $ do
            resolvePathIn "" Null `shouldBe` Just Null

        it "should return Nothing if the value is not a container" $ do
            resolvePathIn "x" Null        `shouldBe` Nothing
            resolvePathIn "x" (String "") `shouldBe` Nothing
            resolvePathIn "x" (Number 1)  `shouldBe` Nothing
            resolvePathIn "x" (Bool True) `shouldBe` Nothing

        it "should return Nothing if the path can't be resolved" $ do
            resolvePathIn "foo" emptyObject `shouldBe` Nothing

        it "should return object field if the path points into an object" $ do
            resolvePathIn "bar" objA `shouldBe` Just (A.String "baz")

        it "should pick the item from an array which has the given id" $ do
            resolvePathIn "foo.bar" (Array $ V.fromList []) `shouldBe` Nothing
            resolvePathIn "foo.bar" (Array $ V.fromList [emptyObject]) `shouldBe` Nothing
            resolvePathIn "foo.bar" (Array $ V.fromList [objA]) `shouldBe` Just (A.String "baz")


    describe "applyOperation" $ do
        it "should fail if it can't descend to the target value" $ do
            applyOperation emptyObject (Set "foo.bar.baz" Nothing) `shouldSatisfy` isFailure
            applyOperation emptyArray  (Set "foo.bar.baz" Nothing) `shouldSatisfy` isFailure

            applyOperation emptyObject (Splice "foo.bar.baz" 0 0 []) `shouldSatisfy` isFailure
            applyOperation emptyArray  (Splice "foo.bar.baz" 0 0 []) `shouldSatisfy` isFailure

        describe "Splice" $ do
            it "should handle primitive arrays" $ do
                let Right obj = applyOperation emptyObject (Set "array" (Just emptyArray))
                applyOperation obj (Splice "array" 0 0 ["elem"]) `shouldSatisfy` isSuccess

            it "should fail if the array doesn't match structure" $ do
                let Right obj = applyOperation emptyObject (Set "array" (Just $ Array $ V.singleton emptyObject))
                applyOperation obj (Splice "array" 0 0 ["elem"]) `shouldSatisfy` isFailure

            it "should fail if the array indices are out of range" $ do
                let Right obj = applyOperation emptyObject (Set "array" (Just emptyArray))
                applyOperation obj (Splice "array" 0 1 ["elem"]) `shouldSatisfy` isFailure

        describe "Set" $ do
            it "should create a new key if the key doesn't exist yet" $ do
                let (Right a) = applyOperation emptyObject $ Set "foo" (Just Null)
                resolvePathIn "foo" a `shouldBe` Just Null