0

更具体地说,我正在寻找一个类型的函数:

f :: site -> SpecM (TestApp site) b -> IO b

或类似的。

换句话说,我正在寻找的反函数:

liftIO :: IO b -> SpecM (TestApp _site) b

我查看了Yesod.Test 文档源代码并尝试自己构建它,但我似乎在任何地方都找不到它,而且构建起来似乎也不简单。我是否忽略了某些东西,它可能存在于某个地方?还是以我没有考虑过的方式构建起来很简单?

背景

我多次遇到需要这样的功能,但到目前为止,我总是能够解决或不做。但在我最近的情况下,它似乎无法解决:我想编写一个 Monadic QuickCheck 属性,它可以设置一个任意的数据库环境 ( runDB . insert) 并在其上运行一些处理程序来测试我的应用程序的某些不变量。

这是我尝试的最远距离:

propSpec = do
  context "qt" $ do
    it "monadic" $ property $ \a b -> monadicIO $ do
      run $ withServer $ \site -> yesodSpec site $ runDB $ insert $ User{..}
      assert $ a /= b

withServer cont = do
  p <- runLogging $ withSqlitePool "database_test.db3" 10 $ \pool -> do
    runSqlPool (runMigration migrateAll) pool
    return pool

  wipeDB (MyApp p)

  cont (MyApp p, id)

可以理解的是,这会导致以下类型错误:

/path/to/project/spec/Spec.hs:301:35: error:
    • Couldn't match type ‘hspec-core-2.2.4:Test.Hspec.Core.Spec.Monad.SpecM
                             () ()’
                     with ‘IO a0’
      Expected type: IO a0
        Actual type: Spec
    • In the expression:
        yesodSpec site $ runDB $ insert $ User{..}
      In the second argument of ‘($)’, namely
        ‘\ site
           -> yesodSpec site $ runDB $ insert $ User{..}’
      In the second argument of ‘($)’, namely
        ‘withServer
         $ \ site
             -> yesodSpec site $ runDB $ insert $ User{..}’

/path/to/project/spec/Spec.hs:301:52: error:
    • Couldn't match type ‘ST.StateT
                             (YesodExampleData MyApp) IO (Key User)’
                     with ‘transformers-0.5.2.0:Control.Monad.Trans.Writer.Lazy.WriterT
                             [YesodSpecTree (MyApp, a1 -> a1)]
                             Data.Functor.Identity.Identity
                             ()’
      Expected type: YesodSpec (MyApp, a1 -> a1)
        Actual type: YesodExample MyApp (Key User)
    • In the second argument of ‘($)’, namely
        ‘runDB $ insert $ User{..}’
      In the expression:
        yesodSpec site $ runDB $ insert $ User{..}
      In the second argument of ‘($)’, namely
        ‘\ site
           -> yesodSpec site $ runDB $ insert $ User{..}’
    • Relevant bindings include
        site :: (MyApp, a1 -> a1)
          (bound at /path/to/project/spec/Spec.hs:301:27)

有任何想法吗?

另外,之前有没有人Test.QuickCheck.Monadic成功使用过Yesod.Test?或者,如果可能没有成功,至少尝试过这样做?

4

0 回答 0