2

I am trying to write property based test with Tasty library and SmallCheck. But I need IO in the property check function and also I need I/O resource. So, I turned existing test into:

myTests :: IO Cfg -> TestTree
myTests getResource = testGroup "My Group"
[
    testProperty "MyProperty" $
    -- HOW TO CALL getResource here, but not in
    -- function, so to avoid multiple acquisition
    -- Some{..} <- getResource
    \(x::X) -> monadic $ do -- HERE I WILL DO I/O...
]

So, question is: how to call getResource once? So, not in the \(x::X) -> ... body but before it. Is it possible?

RandomB
  • 3,367
  • 19
  • 30

1 Answers1

2

You can use withResource. According to the documentation, it will convert your IO Cfg into an IO Cfg that will yield a resource which "will be acquired only once and shared across all the tests in the tree."

It also gives you a Cfg -> IO () function where you can free the Cfg value if needed. I've left that function as a no-op here for now (\cfg -> pure ()), since I don't know the nature of your resource.

myTests :: IO Cfg -> TestTree
myTests getResource =
  withResource getResource (\cfg -> pure ()) $ \getResource' ->
    testGroup "My Group"
    [
        testProperty "MyProperty" $ \(x::X) -> monadic $ do
            Some{..} <- getResource'
            -- DO I/O...
    ]
4castle
  • 32,613
  • 11
  • 69
  • 106
  • yes, but question is different: imagine that you have multiple `testProperty`, so `getResource'` will be called in each of them, but my goal is to call it **once** for all of them – RandomB Jun 19 '19 at 07:19
  • @Paul-AG In that case you can put the `withResource` call around the entire `testGroup` call. See my edit – 4castle Jun 19 '19 at 13:18