packages feed

mockcat-1.4.0.0: test/Test/MockCat/HpcSpec.hs

{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
module Test.MockCat.HpcSpec (spec) where

import Test.Hspec
import Test.MockCat
import Control.Exception (ErrorCall (..))
import Control.Monad.IO.Class (liftIO)

spec :: Spec
spec = do
  describe "[HPC] Strict Verification Compatibility" $ do
    it "expects works correctly" $ do
      withMock $ do
        m <- mock ("arg" ~> "result") `expects` (called (times 1))
        let r = m "arg"
        liftIO $ r `shouldBe` "result"

    it "shouldBeCalled fails with specific error message when StableName lookup fails" $ do
      -- In HPC mode (or if wrapped), StableName lookup fails.
      -- To guarantee failure regardless of HPC trigger, we use a Wrapper.
      -- This simulates the condition we want to test: "Mock not recognized".
      
      m :: String -> String <- mock $ "arg" ~> "result"
      
      -- Wrap the mock. verifying 'wrapped' directly should fail
      -- because 'wrapped' is not registered in the Core registry.
      let wrapped x = m x
      
      -- Execute verification on the WRAPPED (unregistered) function.
      (wrapped `shouldBeCalled` "arg") `shouldThrow` \(ErrorCall msg) ->
        let expected = 
              "Error: Mock verification failed.\n" ++
              "\n" ++
              "The function passed to 'shouldBeCalled' could not be recognized as a registered mock.\n" ++
              "\n" ++
              "Possible causes:\n" ++
              "  1. You passed a raw wrapper function around the mock.\n" ++
              "  2. You passed a normal (non-mock) function.\n" ++
              "  3. HPC (Coverage) is enabled. (HPC instrumentation changes function identity)\n" ++
              "\n" ++
              "Solution:\n" ++
              "  - If you are using HPC or Wrappers, please use 'expects' or 'withMock' style.\n" ++
              "    'expects' is robust against HPC and wrappers as it does not rely on function identity lookup.\n" ++
              "  - Ensure you are passing the mock function directly created by 'mock'."
        in msg == expected