1
1
import Prelude
2
2
3
3
import qualified Data.ByteString.Lazy as BS
4
+ import Data.Maybe (fromMaybe )
5
+ import Data.Text (Text )
4
6
import qualified Data.Text as Text
5
7
import qualified Data.Text.Encoding as Text
6
8
import qualified Data.Text.IO as Text
7
9
import Test.Tasty (defaultMain , TestTree , testGroup )
8
10
import Test.Tasty.Golden (goldenVsString , findByExtension )
11
+ import Test.Tasty.QuickCheck
12
+ import Text.Read (readMaybe )
9
13
import Language.PureScript.CST.Errors as CST
10
14
import Language.PureScript.CST.Lexer as CST
11
15
import Language.PureScript.CST.Print as CST
16
+ import Language.PureScript.CST.Types
12
17
import System.FilePath (takeBaseName , replaceExtension )
13
18
14
19
main :: IO ()
15
- main = defaultMain =<< layoutTests
20
+ main = do
21
+ lytTests <- layoutTests
22
+ defaultMain $ testGroup " CST"
23
+ [ lytTests
24
+ , litTests
25
+ ]
16
26
17
27
layoutTests :: IO TestTree
18
28
layoutTests = do
@@ -23,7 +33,6 @@ layoutTests = do
23
33
(takeBaseName file)
24
34
(replaceExtension file " .out" )
25
35
(BS. fromStrict . Text. encodeUtf8 <$> runLexer file)
26
-
27
36
where
28
37
runLexer file = do
29
38
src <- Text. readFile file
@@ -32,3 +41,91 @@ layoutTests = do
32
41
pure $ Text. pack $ unlines $ CST. prettyPrintError <$> errs
33
42
Right toks -> do
34
43
pure $ CST. printTokens toks
44
+
45
+ litTests :: TestTree
46
+ litTests = testGroup " Literals"
47
+ [ testProperty " Integer" $
48
+ checkTok checkReadNum (\ case TokInt a b -> Just (a, b); _ -> Nothing ) . unInt
49
+ , testProperty " Hex" $
50
+ checkTok checkReadNum (\ case TokInt a b -> Just (a, b); _ -> Nothing ) . unHex
51
+ , testProperty " Number" $
52
+ checkTok checkReadNum (\ case TokNumber a b -> Just (a, b); _ -> Nothing ) . unFloat
53
+ , testProperty " Exponent" $
54
+ checkTok checkReadNum (\ case TokNumber a b -> Just (a, b); _ -> Nothing ) . unExponent
55
+ ]
56
+
57
+ checkTok
58
+ :: (Text -> a -> Gen Bool )
59
+ -> (Token -> Maybe (Text , a ))
60
+ -> Text
61
+ -> Gen Bool
62
+ checkTok p f t = case CST. lex t of
63
+ Right (SourceToken _ tok : _)
64
+ | Just (a, b) <- f tok ->
65
+ if a == t
66
+ then p t b
67
+ else fail $ " Mismatched raw text: " <> show a
68
+ Right toks ->
69
+ fail $ " Failed to lex correctly: " <> show toks
70
+ Left errs ->
71
+ fail $ " Failed to parse: " <> unlines (CST. prettyPrintError <$> errs)
72
+
73
+ checkReadNum :: (Eq a , Read a ) => Text -> a -> Gen Bool
74
+ checkReadNum t a = do
75
+ let
76
+ chs = case Text. unpack $ Text. replace " .e" " .0e" $ Text. replace " _" " " t of
77
+ chs' | last chs' == ' .' -> chs' <> " 0"
78
+ chs' -> chs'
79
+ case (== a) <$> readMaybe chs of
80
+ Just a' -> pure a'
81
+ Nothing -> fail " Failed to `read`"
82
+
83
+ newtype PSSourceInt = PSSourceInt { unInt :: Text }
84
+ deriving (Show , Eq )
85
+
86
+ instance Arbitrary PSSourceInt where
87
+ arbitrary = resize 16 genInt
88
+
89
+ newtype PSSourceFloat = PSSourceFloat { unFloat :: Text }
90
+ deriving (Show , Eq )
91
+
92
+ instance Arbitrary PSSourceFloat where
93
+ arbitrary = resize 16 genFloat
94
+
95
+ newtype PSSourceExponent = PSSourceExponent { unExponent :: Text }
96
+ deriving (Show , Eq )
97
+
98
+ instance Arbitrary PSSourceExponent where
99
+ arbitrary = PSSourceExponent <$> do
100
+ floatPart <- unFloat <$> resize 5 genFloat
101
+ signPart <- fromMaybe " " <$> elements [ Just " +" , Just " -" , Nothing ]
102
+ expPart <- unInt <$> resize 1 genInt
103
+ pure $ floatPart <> " e" <> signPart <> expPart
104
+
105
+ newtype PSSourceHex = PSSourceHex { unHex :: Text }
106
+ deriving (Show , Eq )
107
+
108
+ instance Arbitrary PSSourceHex where
109
+ arbitrary = resize 16 genHex
110
+
111
+ genInt :: Gen PSSourceInt
112
+ genInt = PSSourceInt . Text. pack <$> do
113
+ (:) <$> nonZeroChar
114
+ <*> listOf numChar
115
+
116
+ genFloat :: Gen PSSourceFloat
117
+ genFloat = PSSourceFloat <$> do
118
+ intPart <- unInt <$> genInt
119
+ floatPart <- Text. pack <$> listOf1 numChar
120
+ pure $ intPart <> " ." <> floatPart
121
+
122
+ genHex :: Gen PSSourceHex
123
+ genHex = PSSourceHex <$> do
124
+ nums <- listOf1 $ elements $ [' a' .. ' f' ] <> [' A' .. ' F' ] <> [' 0' .. ' 9' ]
125
+ pure $ " 0x" <> Text. pack nums
126
+
127
+ numChar :: Gen Char
128
+ numChar = elements " 0123456789_"
129
+
130
+ nonZeroChar :: Gen Char
131
+ nonZeroChar = elements " 123456789"
0 commit comments