pretty-diff 0.4.0.2 → 0.4.0.3
raw patch · 4 files changed
+146/−117 lines, 4 files
Files
- CHANGELOG.md +5/−0
- pretty-diff.cabal +2/−2
- src/Pretty/Diff.hs +58/−71
- test/Main.hs +81/−44
CHANGELOG.md view
@@ -1,7 +1,12 @@+# 0.4.0.3+- more small fix+ # 0.4.0.2 - small fix for different line number count+ # 0.4.0.1 - small fix for smaller diff context+ # 0.4.0.0 - `pretty/above/below` take `Text` instead of `Show a` allowing the user to decide how to turn stuff into a string. - `pretty` render multiline input nicely
pretty-diff.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 4f793bc4b441a763102c87017e021f3fab936f2ee528c21b41c3a8444c5922b9+-- hash: 48e2d88ee9f4ca9a7d52484e613038b8827a08f5444274557a47c0e68f2e10ef name: pretty-diff-version: 0.4.0.2+version: 0.4.0.3 synopsis: Pretty printing a diff of two values. description: Please see the README at <https://github.com/stoeffel/pretty-diff>. category: Diffing
src/Pretty/Diff.hs view
@@ -106,111 +106,93 @@ -- | Printing a full diff of both values separated by some pipes. pretty :: Config -> Text -> Text -> Text pretty Config {separatorText, wrapping, multilineContext} x y =- let xs = Text.lines x- ys = Text.lines y- in [ zipWithSameLength (above' wrapping) xs ys & extractContext multilineContext (False, [], []) & mconcat,- separator separatorText,- zipWithSameLength (below' wrapping) xs ys & extractContext multilineContext (False, [], []) & mconcat- ]- & mconcat--zipWithSameLength :: (Maybe a -> Maybe a -> b) -> [a] -> [a] -> [b]-zipWithSameLength f [] ys = map (\y -> f Nothing (Just y)) ys-zipWithSameLength f xs [] = map (\x -> f (Just x) Nothing) xs-zipWithSameLength f (x : xs) (y : ys) = f (Just x) (Just y) : zipWithSameLength f xs ys+ mconcat+ [ above wrapping multilineContext x y,+ separator separatorText,+ below wrapping multilineContext x y+ ] -- | Printing The first value and the diff indicator above. -- -- @--- Diff.above Diff.NoWrap Diff.FullContext "1234" "_23"+-- Diff.above Diff.NoWrap Diff.FullContext Diff.FullContext "1234" "_23" -- @ -- -- @ -- ▼ ▼ -- "1234" -- @-above :: Wrapping -> Text -> Text -> Text-above wrapping x y =- let (_, res) = above' wrapping (Just x) (Just y)- in res+above :: Wrapping -> MultilineContext -> Text -> Text -> Text+above wrapping multilineContext x y =+ let xs = Text.lines x+ ys = Text.lines y+ in sameLength xs ys+ & map ((\(x, y) -> (x, wrap wrapping y)) . above')+ & extractContext multilineContext (False, [], [])+ & Text.unlines+ & Text.dropAround (== '\n') -above' :: Wrapping -> Maybe Text -> Maybe Text -> (Bool, Text)-above' wrapping Nothing (Just y) =- ( True,- withDiffLine First down (map Diff.Second $ Text.unpack y)- & wrap wrapping- & filterEmptyLines- & Text.unlines- )-above' wrapping (Just x) Nothing =- ( True,- withDiffLine First down (map Diff.First $ Text.unpack x)- & wrap wrapping- & filterEmptyLines- & Text.unlines- )-above' wrapping (Just x) (Just y) =+above' :: (Maybe Text, Maybe Text) -> (Bool, [Text])+above' (Nothing, Just y) =+ (True, withDiffLine First down (if y == "" then [Diff.Second ' '] else map Diff.Second $ Text.unpack y))+above' (Just x, Nothing) =+ (True, withDiffLine First down (if x == "" then [Diff.First ' '] else map Diff.First $ Text.unpack x))+above' (Just x, Just y) = let diffs = Diff.getDiff (Text.unpack x) (Text.unpack y) in ( any hasDiff diffs, withDiffLine First down diffs- & wrap wrapping- & filterEmptyLines- & Text.unlines ) -- | Printing The second value and the diff indicator below. -- -- @--- Diff.below Diff.NoWrap "1234" "_23"+-- Diff.below Diff.NoWrap Diff.FullContext "1234" "_23" -- @ -- -- @ -- "_23" -- ▲ -- @-below :: Wrapping -> Text -> Text -> Text-below wrapping x y =- let (_, res) = below' wrapping (Just x) (Just y)- in res+below :: Wrapping -> MultilineContext -> Text -> Text -> Text+below wrapping multilineContext x y =+ let xs = Text.lines x+ ys = Text.lines y+ in sameLength xs ys+ & map ((\(x, y) -> (x, wrap wrapping y)) . below')+ & extractContext multilineContext (False, [], [])+ & Text.unlines+ & Text.dropAround (== '\n') -below' :: Wrapping -> Maybe Text -> Maybe Text -> (Bool, Text)-below' wrapping Nothing (Just y) =- ( True,- withDiffLine Second up (map Diff.Second $ Text.unpack y)- & wrap wrapping- & filterEmptyLines- & Text.unlines- )-below' wrapping (Just x) Nothing =- ( True,- withDiffLine Second up (map Diff.First $ Text.unpack x)- & wrap wrapping- & filterEmptyLines- & Text.unlines- )-below' wrapping (Just x) (Just y) =+below' :: (Maybe Text, Maybe Text) -> (Bool, [Text])+below' (Nothing, Just y) =+ (True, withDiffLine Second up (if y == "" then [Diff.Second ' '] else map Diff.Second $ Text.unpack y))+below' (Just x, Nothing) =+ (True, withDiffLine Second up (if x == "" then [Diff.First ' '] else map Diff.First $ Text.unpack x))+below' (Just x, Just y) = let diffs = Diff.getDiff (Text.unpack x) (Text.unpack y) in ( any hasDiff diffs, withDiffLine Second up diffs- & wrap wrapping- & filterEmptyLines- & Text.unlines ) -wrap :: Wrapping -> [Text] -> [Text]+wrap :: Wrapping -> [Text] -> Text wrap wrapping text =- case wrapping of+ Text.stripEnd $ case wrapping of Wrap n -> text & fmap (Text.chunksOf n) & interleaveLists- NoWrap -> text+ & filter+ ( \x ->+ not (Text.null (Text.dropAround (== ' ') x) && Text.length x >= n)+ )+ & Text.unlines+ NoWrap -> Text.unlines text down :: Char down = '▼'@@ -227,8 +209,8 @@ & mapMaybe (toDiffLine pos differ) & unzip in case pos of- First -> [Text.pack indicators & Text.stripEnd, Text.pack content & Text.stripEnd]- Second -> [Text.pack content & Text.stripEnd, Text.pack indicators & Text.stripEnd]+ First -> filterEmptyLines [Text.pack indicators & Text.stripEnd, Text.pack content & Text.stripEnd]+ Second -> filterEmptyLines [Text.pack content & Text.stripEnd, Text.pack indicators & Text.stripEnd] toDiffLine :: Position -> Char -> Diff.Diff Char -> Maybe (Char, Char) toDiffLine pos c d =@@ -248,7 +230,7 @@ [] -> if length before <= c then acc ++ before- else acc ++ take c before ++ [sep, "\n"]+ else acc ++ take c before ++ [sep] (True, x) : rest -> extractContext context@@ -272,11 +254,11 @@ then if length xs <= n * 2 then xs- else take n xs ++ [sep, "\n"] ++ takeRight n xs+ else take n xs ++ [sep] ++ takeRight n xs else if length xs <= n then xs- else [sep, "\n"] ++ takeRight n xs+ else [sep] ++ takeRight n xs takeRight :: Int -> [a] -> [a] takeRight i xs = reverse (take i (reverse xs))@@ -290,14 +272,19 @@ separator :: Maybe Text -> Text separator maybeComparison =- [ "╷",+ [ "\n╷\n", "│" <> (fromMaybe "" $ ((<>) " ") <$> maybeComparison),- "╵"+ "\n╵\n" ]- & Text.unlines+ & mconcat interleaveLists :: [[a]] -> [a] interleaveLists = mconcat . transpose filterEmptyLines :: [Text] -> [Text] filterEmptyLines = filter (not . Text.null . Text.strip)++sameLength :: [a] -> [b] -> [(Maybe a, Maybe b)]+sameLength [] ys = map (\y -> (Nothing, Just y)) ys+sameLength xs [] = map (\x -> (Just x, Nothing)) xs+sameLength (x : xs) (y : ys) = (Just x, Just y) : sameLength xs ys
test/Main.hs view
@@ -308,53 +308,90 @@ " ▲", "e" ],- testCase "few lines (no diff)" $- expectDiffToEqual- ( Diff.pretty- def {Diff.wrapping = Diff.NoWrap, Diff.multilineContext = Diff.Surrounding 1 "..."}- "a\n"- "a\n"- )- [ "a",- "╷",- "│",- "╵",- "a"- ],- testCase "first is longer" $- expectDiffToEqual- ( Diff.pretty- def- "a\nB"- "a\n"- )- [ "a",- "▼",- "B",- "╷",- "│",- "╵",- "a"- ],- testCase "second is longer" $- expectDiffToEqual- ( Diff.pretty- def- "a\n"- "a\nB"- )- [ "a",- "╷",- "│",- "╵",- "a",- "B",- "▲"- ]+ testGroup+ "pretty (newlines)"+ [ testCase "few lines (no diff)" $+ expectDiffToEqual+ ( Diff.pretty+ def {Diff.wrapping = Diff.NoWrap, Diff.multilineContext = Diff.Surrounding 1 "..."}+ "a\n"+ "a\n"+ )+ [ "a",+ "╷",+ "│",+ "╵",+ "a"+ ],+ testCase "first is longer" $+ expectDiffToEqual+ ( Diff.pretty+ def+ "a\nB"+ "a\n"+ )+ [ "a",+ "▼",+ "B",+ "╷",+ "│",+ "╵",+ "a"+ ],+ testCase "second is longer" $+ expectDiffToEqual+ ( Diff.pretty+ def+ "a\n"+ "a\nB"+ )+ [ "a",+ "╷",+ "│",+ "╵",+ "a",+ "B",+ "▲"+ ],+ testCase "extra newline" $+ expectDiffToEqual+ ( Diff.pretty+ def+ "a\nb"+ "a\n\nb"+ )+ [ "a",+ "▼",+ "b",+ "╷",+ "│",+ "╵",+ "a",+ "",+ "b",+ "▲"+ ],+ testCase "extra newline at the end" $+ expectDiffToEqual+ ( Diff.pretty+ def+ "a\nb\n\n"+ "a\nb"+ )+ [ "a",+ "b",+ "▼",+ "╷",+ "│",+ "╵",+ "a",+ "b"+ ]+ ] ] expectDiffToEqual actual expected_ = do- let expected = Text.unlines expected_+ let expected = Text.stripEnd (Text.unlines expected_) (actual @?= expected) `catch` ( \(e :: HUnitFailure) -> do Text.IO.putStrLn "Actual was:"