module Test.Cursor ( cursorTests ) where import qualified Data.List as List import qualified Data.List.NonEmpty as NEL import qualified Data.Ord as Ord import Hedgehog ((===)) import qualified Hedgehog as HH import qualified Hedgehog.Gen as Gen import qualified Hedgehog.Range as Range import qualified Orville.PostgreSQL as Orville import qualified Orville.PostgreSQL.Execution as Exec import qualified Test.Entities.Foo as Foo import qualified Test.Property as Property cursorTests :: Orville.ConnectionPool -> Property.Group cursorTests pool = Property.group "Cursor" $ [ prop_withCursorFetch pool , prop_withCursorMove pool ] prop_withCursorFetch :: Property.NamedDBProperty prop_withCursorFetch = Property.namedDBProperty "withCursor - fetch" $ \pool -> do foos <- HH.forAll (Foo.generateNonEmpty (Range.linear 1 20)) -- A fetch count of 0 has the special meaning of "current row" in -- PostgreSQL so we avoid generating 0 for the fetch count in this test numToFetch <- HH.forAll (Gen.integral (Range.linear 1 (length foos))) let expectedRows = take numToFetch . List.sortBy (Ord.comparing Foo.fooId) . NEL.toList $ foos actualRows <- Foo.withTable pool $ do Orville.withTransaction $ do _ <- Orville.insertEntities Foo.table foos Exec.withCursor Nothing Nothing selectAllFoosOrderedById $ \cursor -> Exec.fetch (Just $ Exec.forwardCount numToFetch) cursor expectedRows === actualRows prop_withCursorMove :: Property.NamedDBProperty prop_withCursorMove = Property.namedDBProperty "withCursor - move" $ \pool -> do foos <- HH.forAll (Foo.generateNonEmpty (Range.linear 1 20)) -- A fetch count of 0 has the special meaning of "current row" in -- PostgreSQL so we avoid generating any scenario that would give us a -- fetch count of 0 in this test numToSkip <- HH.forAll (Gen.integral (Range.linear 0 (length foos - 1))) numToFetch <- HH.forAll (Gen.integral (Range.linear 1 (length foos - numToSkip))) let expectedRows = take numToFetch . drop numToSkip . List.sortBy (Ord.comparing Foo.fooId) . NEL.toList $ foos actualRows <- Foo.withTable pool $ do Orville.withTransaction $ do _ <- Orville.insertEntities Foo.table foos Exec.withCursor Nothing Nothing selectAllFoosOrderedById $ \cursor -> do Exec.move (Just $ Exec.forwardCount numToSkip) cursor Exec.fetch (Just $ Exec.forwardCount numToFetch) cursor expectedRows === actualRows selectAllFoosOrderedById :: Exec.Select Foo.Foo selectAllFoosOrderedById = Exec.selectTable Foo.table (Orville.orderBy $ Orville.orderByField Foo.fooIdField Orville.ascendingOrder)