LimitedInput.hs 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. {-# LANGUAGE OverloadedStrings #-}
  2. module LimitedInput where
  3. import Distribution.TestSuite
  4. import Base (simpleTest)
  5. import System.IO.Uniform.ByteString
  6. import qualified System.IO.Uniform.Streamline as S
  7. import Data.ByteString (ByteString)
  8. import qualified Data.ByteString as BS
  9. import qualified Data.Attoparsec.ByteString as A
  10. import Control.Monad
  11. tests :: IO [Test]
  12. tests = return [
  13. simpleTest "recieveLine" $ recvTest False "A test\n" 3 S.recieveLine,
  14. simpleTest "recieveN" $ recvTest False "A test\n" 3 $ S.recieveN 30,
  15. simpleTest "runAttoparsec" $ recvTest False "abcedefghijklmnopqrstuvwxyz" 3 $ runParser parseAlphabet,
  16. simpleTest "recieveLine" $ recvTest True "A test\n" 3 S.recieveLine,
  17. simpleTest "recieveN" $ recvTest True "A test\n" 3 $ S.recieveN 30,
  18. simpleTest "runAttoparsec" $ recvTest True "abcedefghijklmnopqrstuvwxyz" 3 $ runParser parseAlphabet,
  19. simpleTest "Attoparsec failure gets pushed back" attoparsecPushBack
  20. ]
  21. recvTest :: Bool -> ByteString -> Int -> S.Streamline IO ByteString -> IO Progress
  22. recvTest readFirst input limit f = fstIO $ withByteStringIO input $ \t -> S.withTarget t $ do
  23. when readFirst $ S.recieveN 1 >> return ()
  24. S.limitInput limit
  25. r <- f
  26. let extra = if readFirst then 1 else 0
  27. if BS.length r <= limit + extra
  28. then return . Finished $ Pass
  29. else return . Finished . Fail $ "Got too much text: " ++ show r
  30. fstIO :: IO (a, b) -> IO a
  31. fstIO f = fst <$> f
  32. alphabet :: ByteString
  33. alphabet = "abcedefghijklmnopqrstuvwxyz"
  34. parseAlphabet :: A.Parser ByteString
  35. parseAlphabet = A.string alphabet
  36. parseNotAlphabet :: A.Parser ByteString
  37. parseNotAlphabet = A.string . BS.reverse $ alphabet
  38. runParser :: A.Parser ByteString -> S.Streamline IO ByteString
  39. runParser p = fst <$> S.runAttoparsecAndReturn p
  40. attoparsecPushBack :: IO Progress
  41. attoparsecPushBack = fstIO $ withByteStringIO alphabet $ \t -> S.withTarget t $ do
  42. S.runAttoparsec parseNotAlphabet
  43. abc <- S.recieveN 3
  44. if abc == "abc"
  45. then return . Finished $ Pass
  46. else return . Finished . Fail $ "Read wrong data: " ++ show abc