diff --git a/default.nix b/default.nix index 8eccfd4..deaea0b 100644 --- a/default.nix +++ b/default.nix @@ -1,32 +1,23 @@ -{ mkDerivation, aeson, base, base16-bytestring, base64-bytestring -, bytestring, case-insensitive, clock, containers, extra, HsYAML -, http-api-data, http-types, iproute, mtl, network, opaleye -, optparse-applicative, postgresql-simple -, postgresql-simple-migration, product-profunctors, profunctors -, pureMD5, random-bytestring, servant, servant-rawm, servant-server -, stdenv, stm, text, time, wai, wai-logger, wai-middleware-throttle -, warp -}: -mkDerivation { - pname = "mateamt"; - version = "0.0.0.0"; - src = ./.; - isLibrary = true; - isExecutable = true; - libraryHaskellDepends = [ - aeson base base16-bytestring base64-bytestring bytestring - containers extra http-api-data http-types mtl opaleye - postgresql-simple product-profunctors profunctors pureMD5 - random-bytestring servant servant-rawm servant-server stm text time - wai wai-logger warp - ]; - executableHaskellDepends = [ - base base16-bytestring bytestring case-insensitive clock containers - HsYAML iproute mtl network opaleye optparse-applicative - postgresql-simple postgresql-simple-migration servant - servant-server stm text time wai wai-logger wai-middleware-throttle - warp - ]; - description = "A whole new matemat"; - license = stdenv.lib.licenses.agpl3; +{ # Fetch the latest haskell.nix and import its default.nix + haskellNix ? import (builtins.fetchTarball "https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz") {} + +# haskell.nix provides access to the nixpkgs pins which are used by our CI, +# hence you will be more likely to get cache hits when using these. +# But you can also just use your own, e.g. ''. +, nixpkgsSrc ? haskellNix.sources.nixpkgs-2009 + +# haskell.nix provides some arguments to be passed to nixpkgs, including some +# patches and also the haskell.nix functionality itself as an overlay. +, nixpkgsArgs ? haskellNix.nixpkgsArgs + +# import nixpkgs with overlays +, pkgs ? import nixpkgsSrc nixpkgsArgs +}: pkgs.haskell-nix.project { + # 'cleanGit' cleans a source directory based on the files known by git + src = pkgs.haskell-nix.haskellLib.cleanGit { + name = "mateamt"; + src = ./.; + }; + # Specify the GHC version to use. + compiler-nix-name = "ghc8103"; # Not required for `stack.yaml` based projects. } diff --git a/mateamt.cabal b/mateamt.cabal index 8041a7d..42364ff 100644 --- a/mateamt.cabal +++ b/mateamt.cabal @@ -19,7 +19,7 @@ flag develop manual: True executable mateamt - main-is: Main.hs + main-is: AppMain.hs other-modules: AppTypes , AppTypes.Configuration , Janitor @@ -120,3 +120,26 @@ library ghc-options: -Wall if flag(develop) cpp-options: -DDEVELOP + +test-suite spec + type: exitcode-stdio-1.0 + main-is: Main.hs + hs-source-dirs: test + ghc-options: -Wall + build-depends: base + , mateamt + , hspec + , hspec-wai + , hspec-wai-json + , warp + , wai + , pg-transact + , tmp-postgres + , bytestring + , resource-pool + , postgresql-simple + other-modules: TestUtil + , Spec + , MainSpec + default-language: Haskell2010 + build-tool-depends: hspec-discover:hspec-discover diff --git a/test/Main.hs b/test/Main.hs new file mode 100644 index 0000000..6e7666c --- /dev/null +++ b/test/Main.hs @@ -0,0 +1,8 @@ +{-# LANGUAGE PackageImports #-} +module Main where + +import Test.Hspec +import qualified Spec + +main :: IO () +main = hspec Spec.spec diff --git a/test/MainSpec.hs b/test/MainSpec.hs new file mode 100644 index 0000000..2471d78 --- /dev/null +++ b/test/MainSpec.hs @@ -0,0 +1,20 @@ +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE PackageImports #-} +module MainSpec where + +import Database.PostgreSQL.Transact +import Database.PostgreSQL.Simple (Only(..)) + +import Test.Hspec + +import Control.Monad.IO.Class (liftIO) + +-- internal imports + +import qualified "mateamt" Util as LibUtil +import TestUtil + +spec = describeDB (const $ return ()) "Initialize DB" $ + itDB "call initialization script" $ do + conn <- getConnection + liftIO $ shouldReturn (LibUtil.initDB conn) () diff --git a/test/Spec.hs b/test/Spec.hs new file mode 100644 index 0000000..5416ef6 --- /dev/null +++ b/test/Spec.hs @@ -0,0 +1 @@ +{-# OPTIONS_GHC -F -pgmF hspec-discover -optF --module-name=Spec #-} diff --git a/test/TestUtil.hs b/test/TestUtil.hs new file mode 100644 index 0000000..2ee6827 --- /dev/null +++ b/test/TestUtil.hs @@ -0,0 +1,50 @@ +{-# LANGUAGE RecordWildCards #-} +module TestUtil where + +import Control.Exception +import Control.Monad +import qualified Data.ByteString.Char8 as BSC +import Data.Pool +import qualified Database.Postgres.Temp as Temp +import Database.PostgreSQL.Simple +import Database.PostgreSQL.Transact +import Test.Hspec + +describeDB :: (Connection -> IO ()) -> String -> SpecWith TestDB -> Spec +describeDB migrate str = + beforeAll (setupDB migrate) . afterAll teardownDB . describe str + +setupDB :: (Connection -> IO ()) -> IO TestDB +setupDB migrate = do + tempDB <- either throwIO return =<< Temp.start + putStrLn $ BSC.unpack $ Temp.toConnectionString tempDB + pool <- createPool + (connectPostgreSQL (Temp.toConnectionString tempDB)) + close + 1 + 100000000 + 50 + withResource pool migrate + return TestDB {..} + +teardownDB :: TestDB -> IO () +teardownDB TestDB {..} = do + destroyAllResources pool + void $ Temp.stop tempDB + +withPool :: TestDB -> (Connection -> IO a) -> IO a +withPool testDB = withResource (pool testDB) + +itDB :: String -> DB a -> SpecWith TestDB +itDB msg action = it msg $ void . withDB action + +withDB :: DB a -> TestDB -> IO a +withDB action testDB = + withResource (pool testDB) (runDBTSerializable action) + +data TestDB = TestDB + { tempDB :: Temp.DB + -- ^ Handle for temporary @postgres@ process + , pool :: Pool Connection + -- ^ Pool of 50 connections to the temporary @postgres@ + }