Search code examples
haskellyesodhspecyesod-test

How to use Hspec/Yesod.Test with Sqlite?


I have a basic Yesod server that uses an Sqlite db, and I'm trying to add tests to it. I'm very new to Haskell, so I'm even struggling to find the right terminology, so bare with me.

I have this code to run the server:

runShortblitoWebServer :: Settings -> IO ()
runShortblitoWebServer Settings {..} =
  runStderrLoggingT $
    withSqlitePool "urls.db" 1 $ \pool -> do
      let app =
            App
              { appLogLevel = settingLogLevel,
                appStatic = shortblitoWebServerStatic,
                appConnectionPool = pool,
                appGoogleAnalyticsTracking = settingGoogleAnalyticsTracking,
                appGoogleSearchConsoleVerification = settingGoogleSearchConsoleVerification
              }
      flip runSqlPool pool $ do
        runMigration migrateTables
      liftIO $ Yesod.warp settingPort app

And now I'm trying to use yesodSpecWithSiteGenerator or yesodSpecWithSiteGeneratorAndArgument to create my Spec. Something like this:

shortblitoWebServerSpec :: ShortblitoWebServerSpec -> SpecWith a
shortblitoWebServerSpec =
  yesodSpecWithSiteGeneratorAndArgument $
    withSqlitePool ":memory:" 1 $ \pool -> do
      let app =
            App
              { appLogLevel = LevelWarn,
                appStatic = shortblitoWebServerStatic,
                appConnectionPool = pool,
                appGoogleAnalyticsTracking = Nothing,
                appGoogleSearchConsoleVerification = Nothing
              }
      flip runSqlPool pool $ do
        runMigration migrateTables
      app

I'm getting the error:

    • Couldn't match expected type ‘a -> IO App’ with actual type ‘App’
    • In a stmt of a 'do' block: app
      In the expression:
        do let app = ...
           flip runSqlPool pool $ do runMigration migrateTables
           app
      In the second argument of ‘($)’, namely
        ‘\ pool
           -> do let ...
                 flip runSqlPool pool $ do ...
                 ....’
    • Relevant bindings include
        shortblitoWebServerSpec :: ShortblitoWebServerSpec -> SpecWith a
          (bound at test/Shortblito/Web/Server/TestUtils.hs:49:1)
   |
62 |       app
   |       ^^^

And I'm not sure what to do. I've been trying different things, but at this point I'm just shooting in the dark really.

Anyone know how to do this? Is there extra information you need?

Thanks!


Solution

  • I think I figured it out!

    This works:

    shortblitoWebServerSpec :: ShortblitoWebServerSpec -> Spec
    shortblitoWebServerSpec =
      yesodSpecWithSiteGenerator $
        runNoLoggingT $
          withSqlitePool ":memory:" 1 $ \pool -> do
            let app =
                  App
                    { appLogLevel = LevelWarn,
                      appStatic = shortblitoWebServerStatic,
                      appConnectionPool = pool,
                      appGoogleAnalyticsTracking = Nothing,
                      appGoogleSearchConsoleVerification = Nothing
                    }
            flip runSqlPool pool $
              do
                runMigration migrateTables
            return app
    

    I added runNoLoggingT and I'm using yesodSpecWithSiteGenerator for now. Might use yesodSpecWithSiteGeneratorAndArgument if needed later.