packages feed

hask-redis-mux-0.1.0.0: test/FromRespSpec.hs

{-# LANGUAGE OverloadedStrings #-}

module Main where

import           Data.ByteString         (ByteString)
import           Data.Either             (isLeft)
import           Data.Text               (Text)
import           Database.Redis.Command  (RedisError (..))
import           Database.Redis.FromResp (FromResp (..))
import           Database.Redis.Resp     (RespData (..))
import           Test.Hspec

main :: IO ()
main = hspec $ do
  describe "FromResp RespData (identity)" $ do
    it "always succeeds for any RespData" $ do
      fromResp (RespSimpleString "OK") `shouldBe` Right (RespSimpleString "OK")
      fromResp (RespInteger 42) `shouldBe` Right (RespInteger 42)
      fromResp RespNullBulkString `shouldBe` Right RespNullBulkString
      fromResp (RespBulkString "hello") `shouldBe` Right (RespBulkString "hello")
      fromResp (RespArray []) `shouldBe` Right (RespArray [])

  describe "FromResp ByteString" $ do
    it "extracts RespBulkString payload" $ do
      fromResp (RespBulkString "hello") `shouldBe` (Right "hello" :: Either RedisError ByteString)

    it "extracts RespSimpleString payload" $ do
      fromResp (RespSimpleString "OK") `shouldBe` (Right "OK" :: Either RedisError ByteString)

    it "returns Left UnexpectedResp for wrong constructor" $ do
      let result = fromResp (RespInteger 42) :: Either RedisError ByteString
      result `shouldSatisfy` isLeft
      result `shouldBe` Left (UnexpectedResp (RespInteger 42))

    it "returns Left UnexpectedResp for RespNullBulkString" $ do
      let result = fromResp RespNullBulkString :: Either RedisError ByteString
      result `shouldBe` Left (UnexpectedResp RespNullBulkString)

  describe "FromResp (Maybe ByteString)" $ do
    it "returns Nothing for RespNullBulkString" $ do
      fromResp RespNullBulkString `shouldBe` (Right Nothing :: Either RedisError (Maybe ByteString))

    it "returns Just payload for RespBulkString" $ do
      fromResp (RespBulkString "val") `shouldBe` (Right (Just "val") :: Either RedisError (Maybe ByteString))

    it "returns Just payload for RespSimpleString" $ do
      fromResp (RespSimpleString "OK") `shouldBe` (Right (Just "OK") :: Either RedisError (Maybe ByteString))

    it "returns Left UnexpectedResp for wrong constructor" $ do
      let result = fromResp (RespInteger 1) :: Either RedisError (Maybe ByteString)
      result `shouldSatisfy` isLeft

  describe "FromResp Integer" $ do
    it "extracts RespInteger payload" $ do
      fromResp (RespInteger 42) `shouldBe` (Right 42 :: Either RedisError Integer)

    it "extracts negative integers" $ do
      fromResp (RespInteger (-1)) `shouldBe` (Right (-1) :: Either RedisError Integer)

    it "extracts zero" $ do
      fromResp (RespInteger 0) `shouldBe` (Right 0 :: Either RedisError Integer)

    it "returns Left UnexpectedResp for wrong constructor" $ do
      let result = fromResp (RespBulkString "42") :: Either RedisError Integer
      result `shouldBe` Left (UnexpectedResp (RespBulkString "42"))

  describe "FromResp Bool" $ do
    it "interprets RespSimpleString OK as True" $ do
      fromResp (RespSimpleString "OK") `shouldBe` (Right True :: Either RedisError Bool)

    it "interprets RespInteger 1 as True" $ do
      fromResp (RespInteger 1) `shouldBe` (Right True :: Either RedisError Bool)

    it "interprets RespInteger 0 as False" $ do
      fromResp (RespInteger 0) `shouldBe` (Right False :: Either RedisError Bool)

    it "returns Left UnexpectedResp for other values" $ do
      let result = fromResp (RespBulkString "true") :: Either RedisError Bool
      result `shouldBe` Left (UnexpectedResp (RespBulkString "true"))

    it "returns Left UnexpectedResp for non-OK simple string" $ do
      let result = fromResp (RespSimpleString "QUEUED") :: Either RedisError Bool
      result `shouldBe` Left (UnexpectedResp (RespSimpleString "QUEUED"))

  describe "FromResp [ByteString]" $ do
    it "extracts array of bulk strings" $ do
      let input = RespArray [RespBulkString "a", RespBulkString "b"]
      fromResp input `shouldBe` (Right ["a", "b"] :: Either RedisError [ByteString])

    it "handles empty array" $ do
      fromResp (RespArray []) `shouldBe` (Right [] :: Either RedisError [ByteString])

    it "extracts array of simple strings" $ do
      let input = RespArray [RespSimpleString "x", RespSimpleString "y"]
      fromResp input `shouldBe` (Right ["x", "y"] :: Either RedisError [ByteString])

    it "returns Left UnexpectedResp for non-array" $ do
      let result = fromResp (RespBulkString "notarray") :: Either RedisError [ByteString]
      result `shouldSatisfy` isLeft

    it "returns Left when element is wrong type" $ do
      let input = RespArray [RespBulkString "a", RespInteger 1]
      let result = fromResp input :: Either RedisError [ByteString]
      result `shouldSatisfy` isLeft

  describe "FromResp [RespData]" $ do
    it "extracts array elements as RespData" $ do
      let input = RespArray [RespInteger 1, RespBulkString "two"]
      fromResp input `shouldBe` Right [RespInteger 1, RespBulkString "two"]

    it "handles empty array" $ do
      fromResp (RespArray []) `shouldBe` (Right [] :: Either RedisError [RespData])

    it "returns Left UnexpectedResp for non-array" $ do
      let result = fromResp (RespInteger 1) :: Either RedisError [RespData]
      result `shouldBe` Left (UnexpectedResp (RespInteger 1))

  describe "FromResp ()" $ do
    it "always succeeds, discarding the response" $ do
      fromResp (RespSimpleString "OK") `shouldBe` (Right () :: Either RedisError ())
      fromResp (RespInteger 42) `shouldBe` (Right () :: Either RedisError ())
      fromResp RespNullBulkString `shouldBe` (Right () :: Either RedisError ())
      fromResp (RespError "ERR") `shouldBe` (Right () :: Either RedisError ())
      fromResp (RespArray []) `shouldBe` (Right () :: Either RedisError ())

  describe "FromResp Text" $ do
    it "decodes UTF-8 bulk string to Text" $ do
      fromResp (RespBulkString "hello") `shouldBe` (Right "hello" :: Either RedisError Text)

    it "decodes UTF-8 simple string to Text" $ do
      fromResp (RespSimpleString "OK") `shouldBe` (Right "OK" :: Either RedisError Text)

    it "returns Left UnexpectedResp for invalid UTF-8" $ do
      let result = fromResp (RespBulkString "\xff\xfe") :: Either RedisError Text
      result `shouldSatisfy` isLeft

    it "returns Left UnexpectedResp for wrong constructor" $ do
      let result = fromResp (RespInteger 42) :: Either RedisError Text
      result `shouldBe` Left (UnexpectedResp (RespInteger 42))

  describe "FromResp (Maybe Text)" $ do
    it "returns Nothing for RespNullBulkString" $ do
      fromResp RespNullBulkString `shouldBe` (Right Nothing :: Either RedisError (Maybe Text))

    it "returns Just text for valid UTF-8 bulk string" $ do
      fromResp (RespBulkString "hello") `shouldBe` (Right (Just "hello") :: Either RedisError (Maybe Text))

    it "returns Left UnexpectedResp for wrong constructor" $ do
      let result = fromResp (RespInteger 1) :: Either RedisError (Maybe Text)
      result `shouldSatisfy` isLeft