forked from haskellari/tree-diff
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTests.hs
188 lines (156 loc) · 5.44 KB
/
Tests.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveGeneric #-}
module Main (main) where
import Data.Proxy (Proxy (..))
import Data.Word (Word8)
import GHC.Generics (Generic)
import Prelude ()
import Prelude.Compat
import Test.QuickCheck (Property, counterexample, (===))
import Test.Tasty (TestTree, defaultMain, testGroup)
import Test.Tasty.Golden.Advanced (goldenTest)
import Test.Tasty.QuickCheck (testProperty)
#if MIN_VERSION_base(4,9,0)
import Data.Array.Byte (ByteArray (..))
#endif
import qualified Data.HashSet as HS
import qualified Data.Primitive as Prim
import qualified Prettyprinter as PP
import qualified Text.Parsec as P
import qualified Text.Trifecta as T (eof, parseString)
import qualified Text.Trifecta.Result as T (ErrInfo (..), Result (..))
import Data.TreeDiff
import Data.TreeDiff.Golden
import Data.TreeDiff.List
import Data.TreeDiff.QuickCheck
import qualified RefDiffBy
main :: IO ()
main = defaultMain $ testGroup "tests"
[ testProperty "trifecta-pretty roundtrip" roundtripTrifectaPretty
, testProperty "parsec-ansi-wl-pprint roundtrip" roundtripParsecAnsi
, testProperty "diffBy example1" $ diffByModel [7,1,6,0,0] [0,0,6,7,1,0,0]
, testProperty "diffBy model" diffByModel
, goldenTests
]
-------------------------------------------------------------------------------
-- diffBy
-------------------------------------------------------------------------------
diffByModel :: [Word8] -> [Word8] -> Property
diffByModel xs ys =
diffBy (==) xs ys === RefDiffBy.diffBy (==) xs ys
-------------------------------------------------------------------------------
-- Roundtrip
-------------------------------------------------------------------------------
-- | This property tests that we can parse pretty printed 'Expr'.
--
-- We demonstrate the use of 'ediffEq'. We could used '===' there,
-- but now the nice diff will be printed as well
-- (as there is 'ToExpr Expr' instance).
roundtripTrifectaPretty :: Expr -> Property
roundtripTrifectaPretty e = counterexample info $ ediffEq (Just e) res'
where
doc = show (prettyExpr e)
res = T.parseString (exprParser <* T.eof) mempty doc
info = case res of
T.Success e' ->
doc
++ "\n" ++
show e'
T.Failure err ->
doc
++ "\n" ++
show (T._errDoc err)
res' = case res of
T.Success e' -> Just e'
T.Failure _ -> Nothing
roundtripParsecAnsi :: Expr -> Property
roundtripParsecAnsi e = counterexample info $ ediffEq (Just e) res'
where
doc = show (PP.unAnnotate (ansiExpr e))
res = P.parse (exprParser <* P.eof) "<memory>" doc
info = case res of
Right e' ->
doc
++ "\n" ++
show e'
Left err ->
doc
++ "\n" ++
show err
res' = either (const Nothing) Just res
-------------------------------------------------------------------------------
-- Golden
-------------------------------------------------------------------------------
-- | This test case verifies that we don't change 'Foo' or 'exFoo'.
--
-- We demonstrate the use of 'ediffGolden'.
--
-- First we declare a type, make it instance of 'ToExpr' and define
-- an example value 'exFoo'. In real-world you might e.g. read the source
-- file and parse it into the AST type.
--
-- Then we create a golden test that verifies that version we got now,
-- is the same we had previously. @tree-diff@ seralises the 'Expr',
-- not the original value. This is a design trade-off:
-- as we can always deserialise we can better diff the values even the
-- type is changed, e.g. the fields is added.
data Foo = Foo
{ fooInt :: Int
, fooBar :: [Maybe String]
, fooQuu :: (Double, Proxy ())
, fooNew :: Bool
, fooStr :: String
}
deriving (Eq, Show, Generic)
instance ToExpr Foo
exFoo :: Foo
exFoo = Foo
{ fooInt = 42
, fooBar = [Just "pub", Just "night\nclub"]
, fooQuu = (125.375, Proxy)
, fooNew = True
, fooStr = "Some Name"
}
newtype MyInt1 = MyInt1 Int
deriving (Eq, Show, Generic)
newtype MyInt2 = MyInt2 { getMyInt2 :: Int }
deriving (Eq, Show, Generic)
data MyInt3 = MyInt3 { getMyInt3 :: Int}
deriving (Eq, Show, Generic)
data Positional = Positional Int Bool Char
deriving (Eq, Show, Generic)
data Empty
deriving (Generic)
instance Eq Empty where
_ == _ = True
instance Show Empty where
showsPrec _ _ = error "Empty?"
instance ToExpr MyInt1
instance ToExpr MyInt2
instance ToExpr MyInt3
instance ToExpr Positional
instance ToExpr Empty
-- test that we have both instances.
data ByteArrays = ByteArrays
Prim.ByteArray
#if MIN_VERSION_base(4,9,0)
ByteArray
#endif
deriving Generic
instance ToExpr ByteArrays
goldenTests :: TestTree
goldenTests = testGroup "Golden"
[ ediffGolden goldenTest "exFoo" "fixtures/exfoo.expr" $
return exFoo
, ediffGolden goldenTest "MyInt1" "fixtures/MyInt1.expr" $
return $ MyInt1 42
, ediffGolden goldenTest "MyInt2" "fixtures/MyInt2.expr" $
return $ MyInt2 42
, ediffGolden goldenTest "MyInt3" "fixtures/MyInt3.expr" $
return $ MyInt3 42
, ediffGolden goldenTest "Positional" "fixtures/Positional.expr" $
return $ Positional 12 True 'z'
-- issue #67
, ediffGolden goldenTest "HashSet" "fixtures/HashSet.expr" $
return $ HS.fromList [ [x,y] | x <- "abcd", y <- "xyz" ]
]