packages feed

langchain-hs-0.0.3.0: test/Test/Langchain/OutputParser/Core.hs

{-# LANGUAGE OverloadedStrings #-}

module Test.Langchain.OutputParser.Core (tests) where

import Test.Tasty
import Test.Tasty.HUnit

import Data.Aeson
import Data.Text (Text)
import Langchain.Error (LangchainError)
import Langchain.OutputParser.Core

data Person = Person
  { name :: Text
  , age :: Int
  }
  deriving (Show, Eq)

instance FromJSON Person where
  parseJSON = withObject "Person" $ \v ->
    Person
      <$> v .: "name"
      <*> v .: "age"

tests :: TestTree
tests =
  testGroup
    "OutputParser Tests"
    [ testCase "Bool parser should parse 'true'" $
        (parse "true" :: Either LangchainError Bool) @?= Right True
    , testCase "Bool parser should parse 'True'" $
        (parse "True" :: Either LangchainError Bool) @?= Right True
    , testCase "Bool parser should parse 'TRUE'" $
        (parse "TRUE" :: Either LangchainError Bool) @?= Right True
    , testCase "Bool parser should parse 'true' with whitespace" $
        (parse "  true  " :: Either LangchainError Bool) @?= Right True
    , testCase "Bool parser should parse 'false'" $
        (parse "false" :: Either LangchainError Bool) @?= Right False
    , testCase "Bool parser should parse 'False'" $
        (parse "False" :: Either LangchainError Bool) @?= Right False
    , testCase "Bool parser should parse 'FALSE'" $
        (parse "FALSE" :: Either LangchainError Bool) @?= Right False
    , testCase "Bool parser should parse 'false' with whitespace" $
        (parse "  false  " :: Either LangchainError Bool) @?= Right False
    , testCase "Bool parser should fail on invalid input" $
        case parse "not a boolean" :: Either LangchainError Bool of
          Left _ -> assertBool "Should be Left" True
          Right _ -> assertFailure "Should have failed parsing"
    , testCase "CommaSeparatedList parser should parse empty string" $
        parse "" @?= Right (CommaSeparatedList [""])
    , testCase "CommaSeparatedList parser should parse single item" $
        parse "item" @?= Right (CommaSeparatedList ["item"])
    , testCase "CommaSeparatedList parser should parse multiple items" $
        parse "item1,item2,item3" @?= Right (CommaSeparatedList ["item1", "item2", "item3"])
    , testCase "CommaSeparatedList parser should trim whitespace" $
        parse " item1 , item2 , item3 " @?= Right (CommaSeparatedList ["item1", "item2", "item3"])
    , testCase "JSONOutputStructure parser should parse valid JSON" $
        parse "{\"name\":\"John\",\"age\":30}"
          @?= Right (JSONOutputStructure (Person "John" 30))
    , testCase "JSONOutputStructure parser should fail on invalid JSON" $
        case parse "{not valid json}" :: Either LangchainError (JSONOutputStructure Person) of
          Left _ -> assertBool "Should be Left" True
          Right _ -> assertFailure "Should have failed parsing"
    , testCase "NumberSeparatedList parser should parse numbered list" $
        parse "1. First item\n2. Second item\n3. Third item"
          @?= Right (NumberSeparatedList ["First item", "Second item", "Third item"])
    , testCase "NumberSeparatedList parser should handle whitespace" $
        parse "1.   First item  \n  2.  Second item\n3. Third item"
          @?= Right (NumberSeparatedList ["First item", "Second item", "Third item"])
    , testCase "NumberSeparatedList parser should handle multi-digit numbers" $
        parse "10. First item\n11. Second item\n12. Third item"
          @?= Right (NumberSeparatedList ["First item", "Second item", "Third item"])
    , testCase "NumberSeparatedList parser should handle text before numbered list" $
        parse "Here is a list:\n1. First item\n2. Second item"
          @?= Right (NumberSeparatedList ["First item", "Second item"])
    , testCase "NumberSeparatedList parser should handle whitespace between number and dot" $
        parse "1 . First item\n2 . Second item"
          @?= Right (NumberSeparatedList ["First item", "Second item"])
    , testCase "NumberSeparatedList parser should fail if no numbers are found" $
        case parse "No numbers here, just text" :: Either LangchainError NumberSeparatedList of
          Left _ -> assertBool "Should be Left" True
          Right _ -> assertFailure "Should have failed parsing"
    ]