content: -- XXX We are using head/tail at one place
  #if __GLASGOW_HASKELL__ >= 908
  {-# OPTIONS_GHC -Wno-x-partial #-}
  #endif
  
  -- |
  -- Module      : Streamly.Test.Data.Stream
  -- Copyright   : (c) 2019 Composewell technologies
  -- License     : BSD-3-Clause
  -- Maintainer  : streamly@composewell.com
  -- Stability   : experimental
  -- Portability : GHC
  
  module Streamly.Test.Data.Stream.Time (main) where
  
  #ifdef DEVBUILD
  import Control.Concurrent ( threadDelay )
  import Control.Monad ( when)
  import Data.Int (Int64)
  import Streamly.Internal.Data.Time.Clock (Clock(Monotonic), getTime)
  import Streamly.Internal.Data.Time.Units
         (AbsTime, NanoSecond64(..), toRelTime64, diffAbsTime64)
  
  import qualified Streamly.Internal.Data.Fold as Fold
  import qualified Streamly.Internal.Data.Stream as Stream
  import qualified Streamly.Internal.Data.Stream.Prelude as Stream
  
  #endif
  
  import Test.Hspec as H
  
  #ifdef DEVBUILD
  tenPow8 :: Int64
  tenPow8 = 10^(8 :: Int)
  
  tenPow7 :: Int64
  tenPow7 = 10^(7 :: Int)
  
  takeDropTime :: NanoSecond64
  takeDropTime = NanoSecond64 $ 5 * tenPow8
  
  checkTakeDropTime :: (Maybe AbsTime, Maybe AbsTime) -> IO Bool
  checkTakeDropTime (mt0, mt1) = do
      let graceTime = NanoSecond64 $ 8 * tenPow7
      case mt0 of
          Nothing -> return True
          Just t0 ->
              case mt1 of
                  Nothing -> return True
                  Just t1 -> do
                      let tMax = toRelTime64 (takeDropTime + graceTime)
                      let tMin = toRelTime64 (takeDropTime - graceTime)
                      let t = diffAbsTime64 t1 t0
                      let r = t >= tMin && t <= tMax
                      when (not r) $ putStrLn $
                          "t = " ++ show t ++
                          " tMin = " ++ show tMin ++
                          " tMax = " ++ show tMax
                      return r
  
  testTakeInterval :: IO Bool
  testTakeInterval = do
      r <-
           Stream.fold (Fold.tee Fold.one Fold.latest)
          $ Stream.takeInterval (fromIntegral takeDropTime * 10**(-9))
          $ Stream.repeatM (threadDelay 1000 >> getTime Monotonic)
      checkTakeDropTime r
  
  testDropInterval :: IO Bool
  testDropInterval = do
      t0 <- getTime Monotonic
      mt1 <-
           Stream.fold Fold.one
          $ Stream.dropInterval (fromIntegral takeDropTime * 10**(-9))
          $ Stream.repeatM (threadDelay 1000 >> getTime Monotonic)
      checkTakeDropTime (Just t0, mt1)
  #endif
  
  moduleName :: String
  moduleName = "Data.Stream.Time"
  
  main :: IO ()
  main = hspec
    $ H.parallel
  #ifdef COVERAGE_BUILD
    $ modifyMaxSuccess (const 10)
  #endif
    $ describe moduleName $ do
  #ifdef DEVBUILD
          describe "Filtering" $ do
              it "takeInterval" (testTakeInterval `shouldReturn` True)
              it "dropInterval" (testDropInterval `shouldReturn` True)
  #endif
          it "dummy" (return () `shouldReturn` ())
  
  