@@ -6,7 +6,7 @@ where
66
77import Control.Monad.Identity (Identity(runIdentity))
88import Debug.Trace (trace)
9−import Streamly.Internal.Data.Parser (ParseError (..))
9+import Streamly.Internal.Data.Parser (ParseError (..), Parser)
1010import Streamly.Test.Common (chooseDouble)
1111import Test.Hspec.QuickCheck (prop)
1212import Test.QuickCheck
@@ -89,103 +89,150 @@ double s d = monadicIO $ do
8989 case x of
9090 Right val -> if val == d
9191 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))
9393 Left (ParseError _) -> assert False
9494
95−doubleErr :: String -> String -> Property
96−doubleErr s msg = monadicIO $ do
97− x <- run $ doubleParser s
95+numberP :: Monad m => Parser Char m Double
96+numberP = uncurry Parser.mkDouble <$> Parser.number
97+
98+numberParser :: String -> IO (Either ParseError Double)
99+numberParser = Stream.parse numberP . Stream.fromList
100+
101+number :: String -> Double -> Property
102+number s d = monadicIO $ do
103+ x <- run $ numberParser s
104+ case x of
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
109+
110+doubleErr :: (String -> IO (Either ParseError Double)) -> String -> String -> Property
111+doubleErr f s msg = monadicIO $ do
112+ x <- run $ f s
98113 case x of
99114 Right _ -> assert False
100115 Left (ParseError err) -> if err == msg
101116 then assert (err == msg)
102117 else trace err (assert (err == msg))
103118
104−remainingStream :: String -> [String]
105−remainingStream x =
119+remainingStreamDouble :: String -> [String]
120+remainingStreamDouble x =
106121 let f = Stream.parseBreak Unicode.double . Stream.fromList
107122 in concatMap (Stream.toList . snd) (f x)
108123
109−afterParse :: String -> String -> Property
110−afterParse si so = monadicIO $ do
111− let x = remainingStream si
112− in assert (x == [so])
113−
114−moduleName :: String
115−moduleName = "Unicode.Parser"
124+remainingStreamNumber :: String -> [String]
125+remainingStreamNumber x =
126+ let f = Stream.parseBreak numberP . Stream.fromList
127+ in concatMap (Stream.toList . snd) (f x)
116128
117−main :: IO ()
118−main = do
119− H.hspec
120− $ H.describe moduleName $ do
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
129+afterParse :: (String -> [String]) -> String -> String -> Property
130+afterParse f si so = monadicIO $ do
131+ let x = f si
132+ in assert (x == [so])
149133
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
137+ -- same test.
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
171+ -- maxBound :: Int
172+ prop "double \"9223372036854775807\"" $ f "9223372036854775807" 9.223372036854776e18
173+ prop "double \"9223372036854775808\"" $ f "9223372036854775808" 9.223372036854776e18
174+
175+testParseErr :: String -> (String -> IO (Either ParseError Double)) -> H.SpecWith ()
176+testParseErr desc f = do
177+ H.describe ("Unicode Parser Error " ++ desc) $ do
150178 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"
152180 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'"
154182 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 '.'"
156184 prop "double \".\" Error"
157− $ doubleErr "." "number: expecting sign or decimal digit, got '.'"
185+ $ doubleErr f "." "number: expecting sign or decimal digit, got '.'"
158186 prop "double \"..\" Error"
159− $ doubleErr ".." "number: expecting sign or decimal digit, got '.'"
187+ $ doubleErr f ".." "number: expecting sign or decimal digit, got '.'"
160188 prop "double \"-\" Error"
161− $ doubleErr "-" "number: expecting decimal digit, got end of input"
189+ $ doubleErr f "-" "number: expecting decimal digit, got end of input"
162190 prop "double \"+\" Error"
163− $ doubleErr "+" "number: expecting decimal digit, got end of input"
191+ $ doubleErr f "+" "number: expecting decimal digit, got end of input"
164192 prop "double \"++\" Error"
165− $ doubleErr "++" "number: expecting decimal digit, got '+'"
166−
167− prop "afterParse \"4.\" \".\"" $ afterParse "4." "."
168− prop "afterParse \"4..\" \"..\"" $ afterParse "4.." ".."
169− prop "afterParse \"4-\" \"-\"" $ afterParse "4-" "-"
170− prop "afterParse \"4--\" \"--\"" $ afterParse "4--" "--"
171− prop "afterParse \"4.9abc\" \"abc\"" $ afterParse "4.9abc" "abc"
172− prop "afterParse \"4.9\" \"\"" $ afterParse "4.9" ""
173− prop "afterParse \"+4.9\" \"\"" $ afterParse "+4.9" ""
174− prop "afterParse \"-4.9\" \"\"" $ afterParse "-4.9" ""
175− prop "afterParse \"4.9.\" \".\"" $ afterParse "4.9." "."
176− prop "afterParse \"4.9..\" \"..\"" $ afterParse "4.9.." ".."
177− prop "afterParse \"4.9...\" \"...\"" $ afterParse "4.9..." "..."
178− prop "afterParse \"4.9+\" \"+\"" $ afterParse "4.9+" "+"
179− prop "afterParse \"4.9++\" \"++\"" $ afterParse "4.9++" "++"
180− prop "afterParse \"4.9+++\" \"+++\"" $ afterParse "4.9+++" "+++"
181− prop "afterParse \"4.9-\" \"-\"" $ afterParse "4.9-" "-"
182− prop "afterParse \"4.9--\" \"--\"" $ afterParse "4.9--" "--"
183− prop "afterParse \"4.9---\" \"---\"" $ afterParse "4.9---" "---"
184− prop "afterParse \"\" \"\"" $ afterParse "" ""
185− prop "afterParse \".\" \".\"" $ afterParse "." "."
186− prop "afterParse \"..\" \"..\"" $ afterParse ".." ".."
187− prop "afterParse \"+\" \"+\"" $ afterParse "+" "+"
188− prop "afterParse \"++\" \"++\"" $ afterParse "++" "++"
193+ $ doubleErr f "++" "number: expecting decimal digit, got '+'"
194+
195+testLeftOver :: String -> (String -> [String]) -> H.SpecWith ()
196+testLeftOver desc f = do
197+ H.describe ("Unicode Parser leftover " ++ desc) $ do
198+ prop "afterParse \"4.\" \".\"" $ afterParse f "4." "."
199+ prop "afterParse \"4..\" \"..\"" $ afterParse f "4.." ".."
200+ prop "afterParse \"4-\" \"-\"" $ afterParse f "4-" "-"
201+ prop "afterParse \"4--\" \"--\"" $ afterParse f "4--" "--"
202+ prop "afterParse \"4.9abc\" \"abc\"" $ afterParse f "4.9abc" "abc"
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" ""
206+ prop "afterParse \"+4.9\" \"\"" $ afterParse f "+4.9" ""
207+ prop "afterParse \"-4.9\" \"\"" $ afterParse f "-4.9" ""
208+ prop "afterParse \"4.9.\" \".\"" $ afterParse f "4.9." "."
209+ prop "afterParse \"4.9..\" \"..\"" $ afterParse f "4.9.." ".."
210+ prop "afterParse \"4.9...\" \"...\"" $ afterParse f "4.9..." "..."
211+ prop "afterParse \"4.9+\" \"+\"" $ afterParse f "4.9+" "+"
212+ prop "afterParse \"4.9++\" \"++\"" $ afterParse f "4.9++" "++"
213+ prop "afterParse \"4.9+++\" \"+++\"" $ afterParse f "4.9+++" "+++"
214+ prop "afterParse \"4.9-\" \"-\"" $ afterParse f "4.9-" "-"
215+ prop "afterParse \"4.9--\" \"--\"" $ afterParse f "4.9--" "--"
216+ prop "afterParse \"4.9---\" \"---\"" $ afterParse f "4.9---" "---"
217+ prop "afterParse \"\" \"\"" $ afterParse f "" ""
218+ prop "afterParse \".\" \".\"" $ afterParse f "." "."
219+ prop "afterParse \"..\" \"..\"" $ afterParse f ".." ".."
220+ prop "afterParse \"+\" \"+\"" $ afterParse f "+" "+"
221+ prop "afterParse \"++\" \"++\"" $ afterParse f "++" "++"
222+
223+moduleName :: String
224+moduleName = "Unicode.Parser"
225+
226+main :: IO ()
227+main = do
228+ H.hspec
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
189236 H.describe "Scientific parser property test" $ do
190237 prop "Exponent format" scientificExpFP
191238 prop "Decimal format" scientificFixFP