tree-diff 0.3.3 → 0.4.1
raw patch · 7 files changed
Files
- ChangeLog.md +15/−0
- src/Data/TreeDiff/Golden.hs +13/−9
- src/Data/TreeDiff/OMap.hs +11/−1
- src/Data/TreeDiff/Pretty.hs +46/−28
- src/Data/TreeDiff/QuickCheck.hs +8/−1
- tests/Tests.hs +7/−7
- tree-diff.cabal +40/−34
ChangeLog.md view
@@ -1,3 +1,18 @@+## 0.4.1++- Fix build with semialign-1.3++## 0.4++- Drop `ansi-wl-pprint` dependency, use `prettyprinter` directly.+ The naming of functions still uses `ansiWl*` naming scheme, to avoid breaking+ too many things. Technically, these functions are still compatible with+ `ansi-wl-pprint` versions which use `prettyprinter` underneath.++## 0.3.4++- Remove 'Eq a' requirement from 'ediffGolden'. The constraint wasn't used, as we only compare 'Expr' representations.+ ## 0.3.3 - Change 'ediffGolden' so that parse errors in expected file don't cause the hard failure.
src/Data/TreeDiff/Golden.hs view
@@ -10,10 +10,12 @@ import Text.Parsec (eof, parse) import Text.Parsec.Text () -import qualified Data.ByteString as BS-import qualified Data.Text as T-import qualified Data.Text.Encoding as TE-import qualified Text.PrettyPrint.ANSI.Leijen as WL+import qualified Data.ByteString as BS+import qualified Data.Text as T+import qualified Data.Text.Encoding as TE+import qualified Data.Text.Lazy as TL+import qualified Prettyprinter as PP+import qualified Prettyprinter.Render.Terminal as PP.A -- | Make a golden tests. --@@ -37,7 +39,7 @@ -- for a proper example. -- ediffGolden- :: (Eq a, ToExpr a)+ :: ToExpr a => (testName -> IO Expr -> IO Expr -> (Expr -> Expr -> IO (Maybe String)) -> (Expr -> IO ()) -> testTree) -- ^ 'goldenTest' -> testName -- ^ test name -> FilePath -- ^ path to "golden file"@@ -51,7 +53,7 @@ -- @since 0.3.2 -- ediffGolden1- :: forall a arg testName testTree. (Eq a, ToExpr a)+ :: forall a arg testName testTree. ToExpr a => (testName -> IO Expr -> (arg -> IO Expr) -> (Expr -> Expr -> IO (Maybe String)) -> (Expr -> IO ()) -> testTree) -- ^ 'goldenTest' -> testName -- ^ test name -> FilePath -- ^ path to "golden file"@@ -74,7 +76,9 @@ | a == b = return Nothing | otherwise = return $ Just $ setSGRCode [Reset] ++ showWL (ansiWlEditExprCompact $ ediff a b)- wrt expr = BS.writeFile fp $ TE.encodeUtf8 $ T.pack $ showWL (WL.plain (ansiWlExpr expr)) ++ "\n"+ wrt expr = BS.writeFile fp $ TE.encodeUtf8 $ T.pack $ showWL (PP.unAnnotate (ansiWlExpr expr)) ++ "\n" -showWL :: WL.Doc -> String-showWL doc = WL.displayS (WL.renderSmart 0.4 80 doc) ""+showWL :: PP.Doc PP.A.AnsiStyle -> String+showWL doc+ = TL.unpack $ PP.A.renderLazy+ $ PP.layoutSmart PP.LayoutOptions { PP.layoutPageWidth = PP.AvailablePerLine 80 0.4 } doc
src/Data/TreeDiff/OMap.hs view
@@ -14,10 +14,12 @@ elems, ) where +import Prelude hiding (zipWith)+ import Control.DeepSeq (NFData (..)) import Data.List (sortBy) import Data.Ord (comparing)-import Data.Semialign (Semialign (..))+import Data.Semialign (Semialign(..), Unzip (..), Zip (..), unzipDefault) import Data.These (These (..)) import qualified Data.Map.Strict as Map@@ -148,3 +150,11 @@ g (This (Val i x)) = Val i (f (This x)) g (That (Val j y)) = Val j (f (That y)) g (These (Val i x) (Val j y)) = Val (min i j) (f (These x y))++instance Ord k => Zip (OMap k) where+ zipWith f (OMap xs) (OMap ys) = OMap (zipWith g xs ys) where+ g (Val i x) (Val j y) = Val (min i j) (f x y)++-- Ord k is required for semialign <1.4+instance Ord k => Unzip (OMap k) where+ unzip = unzipDefault
src/Data/TreeDiff/Pretty.hs view
@@ -10,7 +10,7 @@ prettyExpr, prettyEditExpr, prettyEditExprCompact,- -- * ansi-wl-pprint+ -- * prettyprinter ansiWlPretty, ansiWlExpr, ansiWlEditExpr,@@ -30,9 +30,10 @@ import Numeric (showHex) import Text.Read (readMaybe) -import qualified Data.TreeDiff.OMap as OMap-import qualified Text.PrettyPrint as HJ-import qualified Text.PrettyPrint.ANSI.Leijen as WL+import qualified Data.TreeDiff.OMap as OMap+import qualified Prettyprinter as PP+import qualified Prettyprinter.Render.Terminal as PP.A+import qualified Text.PrettyPrint as HJ -- $setup -- >>> import qualified Data.TreeDiff.OMap as OMap@@ -215,56 +216,73 @@ -- ansi-wl-pprint ------------------------------------------------------------------------------- --- | 'Pretty' via @ansi-wl-pprint@ library (with colors).-ansiWlPretty :: Pretty WL.Doc+-- | 'Pretty' via @prettyprinter@ library (with colors).+ansiWlPretty :: Pretty (PP.Doc PP.A.AnsiStyle) ansiWlPretty = Pretty- { ppCon = WL.text- , ppRec = \c xs -> ansiGroup (c WL.<+> WL.lbrace) WL.rbrace- $ map (\(fn, d) -> WL.text fn WL.<+> WL.equals WL.</> d) xs- , ppLst = ansiGroup WL.lbracket WL.rbracket- , ppCpy = WL.dullwhite- , ppIns = \d -> WL.green $ WL.plain $ WL.char '+' WL.<> d- , ppDel = \d -> WL.red $ WL.plain $ WL.char '-' WL.<> d- , ppApp = \f xs -> WL.group $ WL.nest 2 $ f WL.<$> WL.vsep xs- , ppEdits = WL.sep- , ppEllip = WL.text "..."- , ppParens = WL.parens+ { ppCon = ppText+ , ppRec = \c xs -> ansiGroup (c PP.<+> PP.lbrace) PP.rbrace+ $ map (\(fn, d) -> ppText fn PP.<+> (PP.equals PP.<> PP.softline PP.<> d)) xs+ , ppLst = ansiGroup PP.lbracket PP.rbracket+ , ppCpy = ppDullWhite+ , ppIns = \d -> ppGreen $ PP.unAnnotate $ ppChar '+' PP.<> d+ , ppDel = \d -> ppRed $ PP.unAnnotate $ ppChar '-' PP.<> d+ , ppApp = \f xs -> PP.group $ PP.nest 2 $ f PP.<> PP.line PP.<> PP.vsep xs+ , ppEdits = PP.sep+ , ppEllip = ppText "..."+ , ppParens = PP.parens } -ansiGroup :: WL.Doc -> WL.Doc -> [WL.Doc] -> WL.Doc-ansiGroup l r xs = WL.group $ WL.nest 2 (l WL.<$$> WL.vsep (WL.punctuate WL.comma xs) WL.<> r)+ansiGroup :: PP.Doc PP.A.AnsiStyle -> PP.Doc PP.A.AnsiStyle -> [PP.Doc PP.A.AnsiStyle] -> PP.Doc PP.A.AnsiStyle+ansiGroup l r xs = PP.group $ PP.nest 2 (l PP.<> ppLinebreak PP.<> PP.vsep (PP.punctuate PP.comma xs) PP.<> r) -- | Pretty print 'Expr' using @ansi-wl-pprint@.-ansiWlExpr :: Expr -> WL.Doc+ansiWlExpr :: Expr -> PP.Doc PP.A.AnsiStyle ansiWlExpr = ppExpr ansiWlPretty -- | Pretty print @'Edit' 'EditExpr'@ using @ansi-wl-pprint@.-ansiWlEditExpr :: Edit EditExpr -> WL.Doc+ansiWlEditExpr :: Edit EditExpr -> PP.Doc PP.A.AnsiStyle ansiWlEditExpr = ppEditExpr ansiWlPretty -- | Compact 'ansiWlEditExpr'-ansiWlEditExprCompact :: Edit EditExpr -> WL.Doc+ansiWlEditExprCompact :: Edit EditExpr -> PP.Doc PP.A.AnsiStyle ansiWlEditExprCompact = ppEditExprCompact ansiWlPretty +ppChar :: Char -> PP.Doc PP.A.AnsiStyle+ppChar = PP.pretty++ppText :: String -> PP.Doc PP.A.AnsiStyle+ppText = PP.pretty++ppLinebreak :: PP.Doc a+ppLinebreak = PP.flatAlt PP.line mempty++ppWhite, ppDullWhite, ppRed, ppGreen, ppOnDullRed, ppOnDullGreen :: PP.Doc PP.A.AnsiStyle -> PP.Doc PP.A.AnsiStyle+ppWhite = PP.annotate (PP.A.color PP.A.White)+ppDullWhite = PP.annotate (PP.A.colorDull PP.A.White)+ppRed = PP.annotate (PP.A.color PP.A.Red)+ppGreen = PP.annotate (PP.A.color PP.A.Green)+ppOnDullRed = PP.annotate (PP.A.bgColorDull PP.A.Red)+ppOnDullGreen = PP.annotate (PP.A.bgColorDull PP.A.Green)+ ------------------------------------------------------------------------------- -- Background ------------------------------------------------------------------------------- -- | Like 'ansiWlPretty' but color the background.-ansiWlBgPretty :: Pretty WL.Doc+ansiWlBgPretty :: Pretty (PP.Doc PP.A.AnsiStyle) ansiWlBgPretty = ansiWlPretty- { ppIns = \d -> WL.ondullgreen $ WL.white $ WL.plain $ WL.char '+' WL.<> d- , ppDel = \d -> WL.ondullred $ WL.white $ WL.plain $ WL.char '-' WL.<> d+ { ppIns = \d -> ppOnDullGreen $ ppWhite $ PP.unAnnotate $ ppChar '+' PP.<> d+ , ppDel = \d -> ppOnDullRed $ ppWhite $ PP.unAnnotate $ ppChar '-' PP.<> d } -- | Pretty print 'Expr' using @ansi-wl-pprint@.-ansiWlBgExpr :: Expr -> WL.Doc+ansiWlBgExpr :: Expr -> PP.Doc PP.A.AnsiStyle ansiWlBgExpr = ppExpr ansiWlBgPretty -- | Pretty print @'Edit' 'EditExpr'@ using @ansi-wl-pprint@.-ansiWlBgEditExpr :: Edit EditExpr -> WL.Doc+ansiWlBgEditExpr :: Edit EditExpr -> PP.Doc PP.A.AnsiStyle ansiWlBgEditExpr = ppEditExpr ansiWlBgPretty -- | Compact 'ansiWlBgEditExpr'.-ansiWlBgEditExprCompact :: Edit EditExpr -> WL.Doc+ansiWlBgEditExprCompact :: Edit EditExpr -> PP.Doc PP.A.AnsiStyle ansiWlBgEditExprCompact = ppEditExprCompact ansiWlBgPretty
src/Data/TreeDiff/QuickCheck.hs view
@@ -7,8 +7,15 @@ import System.Console.ANSI (SGR (Reset), setSGRCode) import Test.QuickCheck (Property, counterexample) +import qualified Data.Text.Lazy as TL+import qualified Prettyprinter as PP+import qualified Prettyprinter.Render.Terminal as PP.A+ -- | A variant of '===', which outputs a diff when values are inequal. ediffEq :: (Eq a, ToExpr a) => a -> a -> Property ediffEq x y = counterexample- (setSGRCode [Reset] ++ show (ansiWlEditExpr $ ediff x y))+ (setSGRCode [Reset] ++ render (ansiWlEditExpr $ ediff x y)) (x == y)++render :: PP.Doc PP.A.AnsiStyle -> String+render = TL.unpack . PP.A.renderLazy . PP.layoutPretty PP.defaultLayoutOptions
tests/Tests.hs view
@@ -10,12 +10,12 @@ import Test.Tasty.Golden.Advanced (goldenTest) import Test.Tasty.QuickCheck (testProperty) -import qualified Data.HashSet as HS-import qualified Data.Primitive as Prim-import qualified Text.Parsec as P-import qualified Text.PrettyPrint.ANSI.Leijen as WL-import qualified Text.Trifecta as T (eof, parseString)-import qualified Text.Trifecta.Result as T (ErrInfo (..), Result (..))+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@@ -73,7 +73,7 @@ roundtripParsecAnsiWl :: Expr -> Property roundtripParsecAnsiWl e = counterexample info $ ediffEq (Just e) res' where- doc = show (WL.plain (ansiWlExpr e))+ doc = show (PP.unAnnotate (ansiWlExpr e)) res = P.parse (exprParser <* P.eof) "<memory>" doc info = case res of
tree-diff.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: tree-diff-version: 0.3.3+version: 0.4.1 synopsis: Diffing of (expression) trees. category: Data, Testing description:@@ -50,9 +50,11 @@ || ==9.0.2 || ==9.2.8 || ==9.4.8- || ==9.6.5- || ==9.8.2- || ==9.10.1+ || ==9.6.7+ || ==9.8.4+ || ==9.10.3+ || ==9.12.2+ || ==9.14.1 extra-source-files: fixtures/exfoo.expr@@ -65,6 +67,11 @@ type: git location: https://github.com/phadej/tree-diff.git +flag base-ge-4-17+ description: @base >=4.17@ (GHC-9.4)+ default: True+ manual: False+ library exposed-modules: Data.TreeDiff@@ -80,34 +87,32 @@ -- GHC boot libraries build-depends:- , base >=4.12.0.0 && <4.21+ , base >=4.12.0.0 && <4.23 , bytestring ^>=0.10.8.2 || ^>=0.11.0.0 || ^>=0.12.0.2- , containers ^>=0.6.0.1 || ^>=0.7+ , containers ^>=0.6.0.1 || ^>=0.7 || ^>=0.8 , deepseq ^>=1.4.4.0 || ^>=1.5.0.0 , parsec ^>=3.1.13.0 , pretty ^>=1.1.1.0 , text ^>=1.2.3.0 || ^>=2.0 || ^>=2.1- , time ^>=1.8.0.2 || ^>=1.9.3 || ^>=1.10 || ^>=1.11 || ^>=1.12+ , time ^>=1.8.0.2 || ^>=1.9.3 || ^>=1.10 || ^>=1.11 || ^>=1.12 || ^>=1.14 || ^>=1.15 build-depends:- , aeson ^>=2.2.0.0- , ansi-terminal ^>=1.1- , ansi-wl-pprint ^>=1.0.2- , hashable ^>=1.4.4.0 || ^>=1.5.0.0- , parsers ^>=0.12.11- , primitive ^>=0.9.0.0- , QuickCheck ^>=2.14.2 || ^>=2.15- , scientific ^>=0.3.8.0- , semialign ^>=1.3.1- , strict ^>=0.5- , tagged ^>=0.8.8- , these ^>=1.2.1- , unordered-containers ^>=0.2.20- , uuid-types ^>=1.0.6- , vector ^>=0.13.1.0-- if (impl(ghc >=8) && !impl(ghc >=9.4))- build-depends: data-array-byte ^>=0.1.0.1+ , aeson ^>=2.2.0.0+ , ansi-terminal ^>=1.1+ , hashable ^>=1.4.4.0 || ^>=1.5.0.0+ , parsers ^>=0.12.11+ , prettyprinter ^>=1.7.2+ , prettyprinter-ansi-terminal ^>=1.1.4+ , primitive ^>=0.9.0.0+ , QuickCheck ^>=2.14.2 || ^>=2.15 || ^>=2.16.0.0 || ^>=2.18.0.0+ , scientific ^>=0.3.8.0+ , semialign ^>=1.3.1 || ^>=1.4+ , strict ^>=0.5+ , tagged ^>=0.8.8+ , these ^>=1.2.1+ , unordered-containers ^>=0.2.20+ , uuid-types ^>=1.0.6+ , vector ^>=0.13.1.0 other-extensions: CPP@@ -132,21 +137,16 @@ -- dependencies from library build-depends:- , ansi-terminal- , ansi-wl-pprint , base , parsec+ , prettyprinter , primitive , QuickCheck- , tagged , tree-diff , unordered-containers - if (impl(ghc >=8) && !impl(ghc >=9.4))- build-depends: data-array-byte-- if impl(ghc <7.5)- build-depends: ghc-prim+ if !flag(base-ge-4-17)+ build-depends: data-array-byte >=0.1.0.1 && <0.2 -- extra dependencies build-depends:@@ -155,6 +155,12 @@ , tasty-quickcheck ^>=0.10.3 || ^>=0.11 , trifecta ^>=2.1.4 + if flag(base-ge-4-17)+ build-depends: base >=4.17++ else+ build-depends: base <4.17+ benchmark tree-diff-bench default-language: Haskell2010 type: exitcode-stdio-1.0@@ -171,4 +177,4 @@ -- extra dependencies build-depends: , criterion ^>=1.6.3.0- , Diff ^>=0.5+ , Diff ^>=1.0