{-# LANGUAGE OverloadedStrings #-} module Spec.JSONConversion (spec) where import Data.Aeson (Value(..), toJSON) import Data.Text (Text) import qualified Data.Text as T import MCP.Server import Test.Hspec import Test.QuickCheck import Text.Read (readMaybe) -- Arbitrary instance for Text (needed for QuickCheck) instance Arbitrary Text where arbitrary = T.pack <$> arbitrary spec :: Spec spec = describe "JSON Type Conversion" $ do describe "Property-based tests" $ do it "round-trips integers correctly" $ property prop_intRoundTrip it "round-trips booleans correctly" $ property prop_boolRoundTrip it "round-trips text correctly" $ property prop_textRoundTrip describe "Manual conversion tests" $ do it "converts integers manually" testIntConversion it "converts booleans manually" testBoolConversion -- Fixed property-based tests (no more 'error' usage) prop_intRoundTrip :: Int -> Bool prop_intRoundTrip i = let jsonVal = toJSON i textVal = jsonValueToText jsonVal parsed = readMaybe (T.unpack textVal) in parsed == Just i prop_boolRoundTrip :: Bool -> Bool prop_boolRoundTrip b = let jsonVal = toJSON b textVal = jsonValueToText jsonVal parsed = case T.toLower textVal of "true" -> Just True "false" -> Just False _ -> Nothing in parsed == Just b prop_textRoundTrip :: Text -> Bool prop_textRoundTrip t = let jsonVal = toJSON t textVal = jsonValueToText jsonVal in textVal == t -- Manual test functions converted to Hspec style testIntConversion :: IO () testIntConversion = do let testCases = [0, 42, -17, 999999] :: [Int] results <- mapM testSingleInt testCases all id results `shouldBe` True where testSingleInt i = do let jsonVal = toJSON i textVal = jsonValueToText jsonVal case readMaybe (T.unpack textVal) of Just parsed -> return (parsed == i) Nothing -> do expectationFailure $ "Failed to parse Int from: " <> T.unpack textVal return False testBoolConversion :: IO () testBoolConversion = do let testCases = [True, False] results <- mapM testSingleBool testCases all id results `shouldBe` True where testSingleBool b = do let jsonVal = toJSON b textVal = jsonValueToText jsonVal expected = if b then "true" else "false" case T.toLower textVal of result | result == expected -> return True result -> do expectationFailure $ "Expected " <> T.unpack expected <> " but got " <> T.unpack result return False