@@ -6,7 +6,7 @@ where
7import Control.Monad.Identity (Identity(runIdentity))
7import Control.Monad.Identity (Identity(runIdentity))
8import Debug.Trace (trace)
8import Debug.Trace (trace)
9−import Streamly.Internal.Data.Parser (ParseError (..))
9+import Streamly.Internal.Data.Parser (ParseError (..), Parser)
10import Streamly.Test.Common (chooseDouble)
10import Streamly.Test.Common (chooseDouble)
11import Test.Hspec.QuickCheck (prop)
11import Test.Hspec.QuickCheck (prop)
12import Test.QuickCheck
12import Test.QuickCheck
@@ -89,103 +89,150 @@ double s d = monadicIO $ do
90 Right val -> if val == d
90 Right val -> if val == d
91 then assert (val == d)
91 then assert (val == d)
92− else trace ("Expectedc = " ++ show d ++ " Got = "++ show val) (assert (val == d))
92+ else trace ("Expected = " ++ show d ++ " Got = "++ show val) (assert (val == d))
93 Left (ParseError _) -> assert False
93 Left (ParseError _) -> assert False
95+numberP :: Monad m => Parser Char m Double
96+numberP = uncurry Parser.mkDouble <$> Parser.number
98+numberParser :: String -> IO (Either ParseError Double)
99+numberParser = Stream.parse numberP . Stream.fromList
101+number :: String -> Double -> Property
102+number s d = monadicIO $ do
103+ x <- run $ numberParser s
105+ Right val -> if val == d
106+ then assert (val == d)
107+ else trace ("Expected = " ++ show d ++ " Got = "++ show val) (assert (val == d))
108+ Left (ParseError _) -> assert False
95−doubleErr :: String -> String -> Property
110+doubleErr :: (String -> IO (Either ParseError Double)) -> String -> String -> Property
96−doubleErr s msg = monadicIO $ do
111+doubleErr f s msg = monadicIO $ do
97− x <- run $ doubleParser s
112+ x <- run $ f s
98 case x of
113 case x of
99 Right _ -> assert False
114 Right _ -> assert False
100 Left (ParseError err) -> if err == msg
115 Left (ParseError err) -> if err == msg
101 then assert (err == msg)
116 then assert (err == msg)
102 else trace err (assert (err == msg))
117 else trace err (assert (err == msg))
104−remainingStream :: String -> [String]
119+remainingStreamDouble :: String -> [String]
105−remainingStream x =
120+remainingStreamDouble x =
106 let f = Stream.parseBreak Unicode.double . Stream.fromList
121 let f = Stream.parseBreak Unicode.double . Stream.fromList
107 in concatMap (Stream.toList . snd) (f x)
122 in concatMap (Stream.toList . snd) (f x)
109−afterParse :: String -> String -> Property
124+remainingStreamNumber :: String -> [String]
110−afterParse si so = monadicIO $ do
125+remainingStreamNumber x =
111− let x = remainingStream si
126+ let f = Stream.parseBreak numberP . Stream.fromList
112− in assert (x == [so])
127+ in concatMap (Stream.toList . snd) (f x)
115−moduleName = "Unicode.Parser"
117−main :: IO ()
129+afterParse :: (String -> [String]) -> String -> String -> Property
118−main = do
130+afterParse f si so = monadicIO $ do
119− H.hspec
131+ let x = f si
120− $ H.describe moduleName $ do
132+ in assert (x == [so])
121− H.describe "Unicode Parser" $ do
122− prop "double \"4\" 4.0" $ double "4" 4.0
123− prop "double \"00.3\" 0.3" $ double "00.3" 0.3
124− prop "double \"0.003\" 3.0e-3" $ double "0.003" 3.0e-3
125− prop "double \"44.56.67\" 44.56" $ double "44.56.67" 44.56
126− prop "double \"0.0.00\" 0.0" $ double "0.0.00" 0.0
127− prop "double \"44.56-78\" 44.56" $ double "44.56-78" 44.56
128− prop "double \"44-\" 44.0" $ double "44-" 44.0
129− prop "double \"44-56\" 44.0" $ double "44-56" 44.0
130− prop "double \"44+\" 44.0" $ double "44+" 44.0
131− prop "double \"44+56\" 44.0" $ double "44+56" 44.0
132− prop "double \"44u\" 44.0" $ double "44u" 44.0
133− prop "double \"+123.345\" 123.345" $ double "+123.345" 123.345
134− prop "double \"-123.345\" (-123.345)" $ double "-123.345" (-123.345)
135− prop "double \"1e\"" $ double "1e" 1.0
136− prop "double \"1e+\"" $ double "1e+" 1.0
137− prop "double \"1e+0\"" $ double "1e+0" 1.0
138− prop "double \"1e-0\"" $ double "1e-0" 1.0
139− prop "double \"1.0e-1\"" $ double "1.0e-1" 0.1
140− prop "double \"1.0e+1\"" $ double "1.0e+1" 10.0
141− prop "double \"1.0e1\"" $ double "1.0e1" 10.0
142− prop "double \"1.0e+309\"" $ double "1.0e+309" 1.0e309
143− prop "double \"1.0e-309\"" $ double "1.0e-309" 1.0e-309
144− prop "double \"1.0e1.\"" $ double "1.0e1." 10.0
145− prop "double \"1.0e1+\"" $ double "1.0e1+" 10.0
146− prop "double \"1.0e1-\"" $ double "1.0e1-" 10.0
147− prop "double \"1.0e1e\"" $ double "1.0e1e" 10.0
148− prop "double \"1.0E+1\"" $ double "1.0E+1" 10.0
134+testParser :: String -> (String -> Double -> Property) -> H.SpecWith ()
135+testParser desc f = do
136+ -- XXX We can combine the parser tests and remaining stream tests in the
138+ H.describe ("Unicode Parser " ++ desc) $ do
139+ prop "double \"00.00\"" $ f "00.00" 0.0
140+ prop "double \"00.00e00\"" $ f "00.00e00" 0.0
141+ prop "double \"4\" 4.0" $ f "4" 4.0
142+ prop "double \"00.3\" 0.3" $ f "00.3" 0.3
143+ prop "double \"0.003\" 3.0e-3" $ f "0.003" 3.0e-3
144+ prop "double \"44.56.67\" 44.56" $ f "44.56.67" 44.56
145+ prop "double \"0.0.00\" 0.0" $ f "0.0.00" 0.0
146+ prop "double \"44.56-78\" 44.56" $ f "44.56-78" 44.56
147+ prop "double \"44-\" 44.0" $ f "44-" 44.0
148+ prop "double \"44-56\" 44.0" $ f "44-56" 44.0
149+ prop "double \"44+\" 44.0" $ f "44+" 44.0
150+ prop "double \"44+56\" 44.0" $ f "44+56" 44.0
151+ prop "double \"44u\" 44.0" $ f "44u" 44.0
152+ prop "double \"+123.345\" 123.345" $ f "+123.345" 123.345
153+ prop "double \"-123.345\" (-123.345)" $ f "-123.345" (-123.345)
154+ prop "double \"1e\"" $ f "1e" 1.0
155+ prop "double \"1e+\"" $ f "1e+" 1.0
156+ prop "double \"1ex\"" $ f "1ex" 1.0
157+ prop "double \"1e+x\"" $ f "1e+x" 1.0
158+ prop "double \"1e+0\"" $ f "1e+0" 1.0
159+ prop "double \"1e-0\"" $ f "1e-0" 1.0
160+ prop "double \"1.0e-1\"" $ f "1.0e-1" 0.1
161+ prop "double \"1.0e+1\"" $ f "1.0e+1" 10.0
162+ prop "double \"1.0e1\"" $ f "1.0e1" 10.0
163+ prop "double \"1.0e+309\"" $ f "1.0e+309" 1.0e309
164+ prop "double \"1.0e-309\"" $ f "1.0e-309" 1.0e-309
165+ prop "double \"1.0e1.\"" $ f "1.0e1." 10.0
166+ prop "double \"1.0e1+\"" $ f "1.0e1+" 10.0
167+ prop "double \"1.0e1-\"" $ f "1.0e1-" 10.0
168+ prop "double \"1.0e1e\"" $ f "1.0e1e" 10.0
169+ prop "double \"1.0E+1\"" $ f "1.0E+1" 10.0
170+ prop "double \"9223372036854775806\"" $ f "9223372036854775806" 9.223372036854776e18
172+ prop "double \"9223372036854775807\"" $ f "9223372036854775807" 9.223372036854776e18
173+ prop "double \"9223372036854775808\"" $ f "9223372036854775808" 9.223372036854776e18
175+testParseErr :: String -> (String -> IO (Either ParseError Double)) -> H.SpecWith ()
176+testParseErr desc f = do
177+ H.describe ("Unicode Parser Error " ++ desc) $ do
150 prop "double \"\" Error"
178 prop "double \"\" Error"
151− $ doubleErr "" "number: expecting sign or decimal digit, got end of input"
179+ $ doubleErr f "" "number: expecting sign or decimal digit, got end of input"
152 prop "double \"a\" Error"
180 prop "double \"a\" Error"
153− $ doubleErr "a" "number: expecting sign or decimal digit, got 'a'"
181+ $ doubleErr f "a" "number: expecting sign or decimal digit, got 'a'"
154 prop "double \".4\" Error"
182 prop "double \".4\" Error"
155− $ doubleErr ".4" "number: expecting sign or decimal digit, got '.'"
183+ $ doubleErr f ".4" "number: expecting sign or decimal digit, got '.'"
156 prop "double \".\" Error"
184 prop "double \".\" Error"
157− $ doubleErr "." "number: expecting sign or decimal digit, got '.'"
185+ $ doubleErr f "." "number: expecting sign or decimal digit, got '.'"
158 prop "double \"..\" Error"
186 prop "double \"..\" Error"
159− $ doubleErr ".." "number: expecting sign or decimal digit, got '.'"
187+ $ doubleErr f ".." "number: expecting sign or decimal digit, got '.'"
160 prop "double \"-\" Error"
188 prop "double \"-\" Error"
161− $ doubleErr "-" "number: expecting decimal digit, got end of input"
189+ $ doubleErr f "-" "number: expecting decimal digit, got end of input"
162 prop "double \"+\" Error"
190 prop "double \"+\" Error"
163− $ doubleErr "+" "number: expecting decimal digit, got end of input"
191+ $ doubleErr f "+" "number: expecting decimal digit, got end of input"
164 prop "double \"++\" Error"
192 prop "double \"++\" Error"
165− $ doubleErr "++" "number: expecting decimal digit, got '+'"
193+ $ doubleErr f "++" "number: expecting decimal digit, got '+'"
195+testLeftOver :: String -> (String -> [String]) -> H.SpecWith ()
196+testLeftOver desc f = do
197+ H.describe ("Unicode Parser leftover " ++ desc) $ do
167− prop "afterParse \"4.\" \".\"" $ afterParse "4." "."
198+ prop "afterParse \"4.\" \".\"" $ afterParse f "4." "."
168− prop "afterParse \"4..\" \"..\"" $ afterParse "4.." ".."
199+ prop "afterParse \"4..\" \"..\"" $ afterParse f "4.." ".."
169− prop "afterParse \"4-\" \"-\"" $ afterParse "4-" "-"
200+ prop "afterParse \"4-\" \"-\"" $ afterParse f "4-" "-"
170− prop "afterParse \"4--\" \"--\"" $ afterParse "4--" "--"
201+ prop "afterParse \"4--\" \"--\"" $ afterParse f "4--" "--"
171− prop "afterParse \"4.9abc\" \"abc\"" $ afterParse "4.9abc" "abc"
202+ prop "afterParse \"4.9abc\" \"abc\"" $ afterParse f "4.9abc" "abc"
172− prop "afterParse \"4.9\" \"\"" $ afterParse "4.9" ""
203+ prop "afterParse \"4.9ex\"" $ afterParse f "4.9ex" "ex"
204+ prop "afterParse \"4.9e+x\"" $ afterParse f "4.9e+x" "e+x"
205+ prop "afterParse \"4.9\" \"\"" $ afterParse f "4.9" ""
173− prop "afterParse \"+4.9\" \"\"" $ afterParse "+4.9" ""
206+ prop "afterParse \"+4.9\" \"\"" $ afterParse f "+4.9" ""
174− prop "afterParse \"-4.9\" \"\"" $ afterParse "-4.9" ""
207+ prop "afterParse \"-4.9\" \"\"" $ afterParse f "-4.9" ""
175− prop "afterParse \"4.9.\" \".\"" $ afterParse "4.9." "."
208+ prop "afterParse \"4.9.\" \".\"" $ afterParse f "4.9." "."
176− prop "afterParse \"4.9..\" \"..\"" $ afterParse "4.9.." ".."
209+ prop "afterParse \"4.9..\" \"..\"" $ afterParse f "4.9.." ".."
177− prop "afterParse \"4.9...\" \"...\"" $ afterParse "4.9..." "..."
210+ prop "afterParse \"4.9...\" \"...\"" $ afterParse f "4.9..." "..."
178− prop "afterParse \"4.9+\" \"+\"" $ afterParse "4.9+" "+"
211+ prop "afterParse \"4.9+\" \"+\"" $ afterParse f "4.9+" "+"
179− prop "afterParse \"4.9++\" \"++\"" $ afterParse "4.9++" "++"
212+ prop "afterParse \"4.9++\" \"++\"" $ afterParse f "4.9++" "++"
180− prop "afterParse \"4.9+++\" \"+++\"" $ afterParse "4.9+++" "+++"
213+ prop "afterParse \"4.9+++\" \"+++\"" $ afterParse f "4.9+++" "+++"
181− prop "afterParse \"4.9-\" \"-\"" $ afterParse "4.9-" "-"
214+ prop "afterParse \"4.9-\" \"-\"" $ afterParse f "4.9-" "-"
182− prop "afterParse \"4.9--\" \"--\"" $ afterParse "4.9--" "--"
215+ prop "afterParse \"4.9--\" \"--\"" $ afterParse f "4.9--" "--"
183− prop "afterParse \"4.9---\" \"---\"" $ afterParse "4.9---" "---"
216+ prop "afterParse \"4.9---\" \"---\"" $ afterParse f "4.9---" "---"
184− prop "afterParse \"\" \"\"" $ afterParse "" ""
217+ prop "afterParse \"\" \"\"" $ afterParse f "" ""
185− prop "afterParse \".\" \".\"" $ afterParse "." "."
218+ prop "afterParse \".\" \".\"" $ afterParse f "." "."
186− prop "afterParse \"..\" \"..\"" $ afterParse ".." ".."
219+ prop "afterParse \"..\" \"..\"" $ afterParse f ".." ".."
187− prop "afterParse \"+\" \"+\"" $ afterParse "+" "+"
220+ prop "afterParse \"+\" \"+\"" $ afterParse f "+" "+"
188− prop "afterParse \"++\" \"++\"" $ afterParse "++" "++"
221+ prop "afterParse \"++\" \"++\"" $ afterParse f "++" "++"
224+moduleName = "Unicode.Parser"
229+ $ H.describe moduleName $ do
230+ testParser "double" double
231+ testParser "number" number
232+ testParseErr "double" doubleParser
233+ testParseErr "number" numberParser
234+ testLeftOver "double" remainingStreamDouble
235+ testLeftOver "number" remainingStreamNumber
189 H.describe "Scientific parser property test" $ do
236 H.describe "Scientific parser property test" $ do
190 prop "Exponent format" scientificExpFP
237 prop "Exponent format" scientificExpFP
191 prop "Decimal format" scientificFixFP
238 prop "Decimal format" scientificFixFP