{-# LANGUAGE RankNTypes #-}
{- |
Module : Main
Description : Tests for sorting
Copyright : (c) Ivan Lazar Miljenovic
License : MIT
Maintainer : Ivan.Miljenovic@gmail.com
-}
module Main (main) where
import Streaming.Sort (chunkSize, defaultConfig, setConfig, sort, withFileSort)
import Streaming.Prelude (Of, Stream)
import qualified Streaming.Prelude as S
import Streaming.With (withSystemTempDirectory)
import Control.Applicative (liftA2)
import Control.Monad.Catch (catchAll, throwM)
import Control.Monad.Trans.Class (lift)
import Data.Binary (Binary)
import Data.Functor.Identity (runIdentity)
import System.Directory (getDirectoryContents)
import qualified Data.List as L
import Test.Hspec (Expectation, describe, hspec, it, shouldReturn)
import Test.Hspec.QuickCheck (prop)
import Test.QuickCheck (Gen, Positive(Positive), arbitrary, forAllShrink,
ioProperty, shrink)
--------------------------------------------------------------------------------
main :: IO ()
main = hspec $ do
describe "in-memory" $
prop "same as list-based" $
forAllShrink (arbitrary :: Gen [Int]) shrink $
liftA2 (==) L.sort (runIdentity . S.toList_ . sort . S.each)
describe "file-based" $ do
prop "same as list-based" $
forAllShrink (arbitrary :: Gen [Int]) shrink $ \as (Positive cs) ->
ioProperty $ withFileSort (setConfig chunkSize cs defaultConfig)
(S.each as)
(fmap (== L.sort as) . S.toList_)
describe "cleans up temporary files" $ do
it "on success" $
fileSortCleanup (S.each [1::Int .. 10])
it "on exception" $
fileSortCleanup (S.each [1::Int .. 10] >> lift (throwM (userError "Tainted Producer")))
fileSortCleanup :: (Binary a, Ord a) => Stream (Of a) IO r -> Expectation
fileSortCleanup str = withSystemTempDirectory "test-streaming-sort-cleanup" $ \tmpDir -> do
cnts0 <- getDirectoryContents tmpDir -- Should be [".", ".."]
catchAll (withFileSort defaultConfig str S.effects) (const (return ()))
(L.sort <$> getDirectoryContents tmpDir) `shouldReturn` L.sort cnts0