on master help sign in
Add tests and benchmarks for takeBetween
656bfc6Anurag Hooda
benchmark/Streamly/Benchmark/Data/Parser.hs+6−1
@@ -60,6 +60,10 @@ benchIOSink value name f =
60-- Parsers
60-- Parsers
61-------------------------------------------------------------------------------
61-------------------------------------------------------------------------------
62
62
63+{-# INLINE takeBetween #-}
64+takeBetween :: MonadCatch m => Int -> SerialT m a -> m ()
65+takeBetween value = IP.parse (PR.takeBetween 0 value FL.drain)
66+
63{-# INLINE takeEQ #-}
67{-# INLINE takeEQ #-}
64takeEQ :: MonadCatch m => Int -> SerialT m a -> m ()
68takeEQ :: MonadCatch m => Int -> SerialT m a -> m ()
65takeEQ value = IP.parse (PR.takeEQ value FL.drain)
69takeEQ value = IP.parse (PR.takeEQ value FL.drain)
@@ -267,7 +271,8 @@ moduleName = "Data.Parser"
267
271
268o_1_space_serial :: Int -> [Benchmark]
272o_1_space_serial :: Int -> [Benchmark]
269o_1_space_serial value =
273o_1_space_serial value =
274+ [ benchIOSink value "takeBetween" $ takeBetween value
270− [ benchIOSink value "takeEQ" $ takeEQ value
275+ , benchIOSink value "takeEQ" $ takeEQ value
271 , benchIOSink value "takeWhile" $ takeWhile value
276 , benchIOSink value "takeWhile" $ takeWhile value
272 , benchIOSink value "drainWhile" $ drainWhile value
277 , benchIOSink value "drainWhile" $ drainWhile value
273 , benchIOSink value "groupBy" $ groupBy
278 , benchIOSink value "groupBy" $ groupBy
benchmark/streamly-benchmarks.cabal+2−1
@@ -173,7 +173,7 @@ benchmark Prelude.Serial
173 , Serial.Nested
173 , Serial.Nested
174 , Serial.Exceptions
174 , Serial.Exceptions
175 , Serial.Split
175 , Serial.Split
176− ghc-options: +RTS -M750M -RTS
176+ ghc-options: +RTS -M1000M -RTS
177 if impl(ghcjs)
177 if impl(ghcjs)
178 buildable: False
178 buildable: False
179 else
179 else
@@ -314,6 +314,7 @@ benchmark Data.Parser
314 import: bench-options
314 import: bench-options
315 type: exitcode-stdio-1.0
315 type: exitcode-stdio-1.0
316 hs-source-dirs: Streamly/Benchmark/Data
316 hs-source-dirs: Streamly/Benchmark/Data
317+ ghc-options: +RTS -M750M -RTS
317 main-is: Parser.hs
318 main-is: Parser.hs
318 if impl(ghcjs)
319 if impl(ghcjs)
319 buildable: False
320 buildable: False
src/Streamly/Internal/Data/Parser.hs+2−2
@@ -337,8 +337,8 @@ either = K.toParserK . D.either
337-- | @takeBetween m n@ takes a minimum of @m@ and a maximum of @n@ input
337-- | @takeBetween m n@ takes a minimum of @m@ and a maximum of @n@ input
338-- elements and folds them using the supplied fold.
338-- elements and folds them using the supplied fold.
339--
339--
340−-- Stops after @m@ elements.
340+-- Stops after @n@ elements.
341−-- Fails if the stream ends before @n@ elements could be taken.
341+-- Fails if the stream ends before @m@ elements could be taken.
342--
342--
343-- Examples: -
343-- Examples: -
344--
344--
test/Streamly/Test/Data/Parser.hs+53
@@ -155,6 +155,54 @@ satisfy =
155 predicate = (>= mid_value)
155 predicate = (>= mid_value)
156
156
157-- Sequence Parsers Tests
157-- Sequence Parsers Tests
158+takeBetweenPass :: Property
159+takeBetweenPass =
160+ forAll (chooseInt (min_value, max_value)) $ \m ->
161+ forAll (chooseInt (m, max_value)) $ \n ->
162+ forAll (chooseInt (m, max_value)) $ \list_length ->
163+ forAll (vectorOf list_length (chooseInt (min_value, max_value))) $ \ls ->
164+ case S.parse (P.takeBetween m n FL.toList) (S.fromList ls) of
165+ Right parsed_list ->
166+ let lpl = Prelude.length parsed_list
167+ in checkListEqual parsed_list (Prelude.take lpl ls)
168+ Left _ -> property False
169+
170+takeBetween :: Property
171+takeBetween =
172+ forAll (chooseInt (min_value, max_value)) $ \m ->
173+ forAll (chooseInt (min_value, max_value)) $ \n ->
174+ forAll (listOf(chooseInt (min_value, max_value))) $ \ls ->
175+ let
176+ list_length = Prelude.length ls
177+ in
178+ case S.parse (P.takeBetween m n FL.toList) (S.fromList ls) of
179+ Right parsed_list ->
180+ if m <= list_length && n >= list_length
181+ then
182+ let lpl = Prelude.length parsed_list
183+ in checkListEqual parsed_list (Prelude.take
184+ lpl ls)
185+ else property False
186+ Left _ -> property (m > n || list_length < m)
187+
188+
189+-- takeBetween :: Property
190+-- takeBetween =
191+-- forAll (chooseInt (min_value, max_value)) $ \m ->
192+-- forAll (chooseInt (min_value, max_value)) $ \n ->
193+-- forAll (listOf (chooseInt (min_value, max_value))) $ \ls ->
194+-- let
195+-- list_length = Prelude.length ls
196+-- in
197+-- case S.parseD (P.takeBetween m n FL.toList) (S.fromList ls) of
198+-- Right parsed_list ->
199+-- if m <= list_length && n >= list_length
200+-- then
201+-- let lpl = Prelude.length parsed_list
202+-- in checkListEqual parsed_list (Prelude.take
203+-- lpl ls)
204+-- else property False
205+-- Left _ -> property (m > n || list_length < m)
158
206
159takeEQPass :: Property
207takeEQPass :: Property
160takeEQPass =
208takeEQPass =
@@ -634,6 +682,11 @@ main =
634 prop "check first element exists and satisfies predicate" satisfy
682 prop "check first element exists and satisfies predicate" satisfy
635
683
636 describe "test for sequence parser" $ do
684 describe "test for sequence parser" $ do
685+ prop "P.takeBetween = Prelude.take when len >= m and len <= n"
686+ takeBetweenPass
687+ prop ("P.takeBetween = Prelude.take when len >= m and len <= n and fail"
688+ ++ "otherwise fail") Main.takeBetween
689+
637 prop "P.takeEQ = Prelude.take when len >= n" takeEQPass
690 prop "P.takeEQ = Prelude.take when len >= n" takeEQPass
638 prop "P.takeEQ = Prelude.take when len >= n and fail otherwise" Main.takeEQ
691 prop "P.takeEQ = Prelude.take when len >= n and fail otherwise" Main.takeEQ
639 prop "P.takeGE n ls = ls when len >= n" takeGEPass
692 prop "P.takeGE n ls = ls when len >= n" takeGEPass
test/Streamly/Test/Data/Parser/ParserD.hs+34
@@ -147,6 +147,36 @@ satisfy =
147 predicate = (>= mid_value)
147 predicate = (>= mid_value)
148
148
149-- Sequence Parsers Tests
149-- Sequence Parsers Tests
150+takeBetweenPass :: Property
151+takeBetweenPass =
152+ forAll (chooseInt (min_value, max_value)) $ \m ->
153+ forAll (chooseInt (m, max_value)) $ \n ->
154+ forAll (chooseInt (m, max_value)) $ \list_length ->
155+ forAll (vectorOf list_length (chooseInt (min_value, max_value))) $ \ls ->
156+ case S.parseD (P.takeBetween m n FL.toList) (S.fromList ls) of
157+ Right parsed_list ->
158+ let lpl = Prelude.length parsed_list
159+ in checkListEqual parsed_list (Prelude.take lpl ls)
160+ Left _ -> property False
161+
162+
163+takeBetween :: Property
164+takeBetween =
165+ forAll (chooseInt (min_value, max_value)) $ \m ->
166+ forAll (chooseInt (min_value, max_value)) $ \n ->
167+ forAll (listOf (chooseInt (min_value, max_value))) $ \ls ->
168+ let
169+ list_length = Prelude.length ls
170+ in
171+ case S.parseD (P.takeBetween m n FL.toList) (S.fromList ls) of
172+ Right parsed_list ->
173+ if m <= list_length && n >= list_length
174+ then
175+ let lpl = Prelude.length parsed_list
176+ in checkListEqual parsed_list (Prelude.take
177+ lpl ls)
178+ else property False
179+ Left _ -> property (m > n || list_length < m)
150
180
151take :: Property
181take :: Property
152take =
182take =
@@ -662,6 +692,10 @@ main =
662 prop "check first element exists and satisfies predicate" satisfy
692 prop "check first element exists and satisfies predicate" satisfy
663
693
664 describe "test for sequence parser" $ do
694 describe "test for sequence parser" $ do
695+ prop "P.takeBetween m n = Prelude.take when len >= m and len <= n"
696+ takeBetweenPass
697+ prop "P.takeBetween m n = Prelude.take when len >= m and len <= n and\
698+ \fail otherwise" takeBetween
665 prop "P.take = Prelude.take" Main.take
699 prop "P.take = Prelude.take" Main.take
666 prop "P.takeEQ = Prelude.take when len >= n" takeEQPass
700 prop "P.takeEQ = Prelude.take when len >= n" takeEQPass
667 prop "P.takeEQ = Prelude.take when len >= n and fail otherwise" Main.takeEQ
701 prop "P.takeEQ = Prelude.take when len >= n and fail otherwise" Main.takeEQ