diff --git a/CHANGELOG.md b/CHANGELOG.md index 997c127..64cddf9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.0.2 + + - Output correct format when an input file is empty, e.g. `@@ --0,0 +1,3 @@`. + # 1.0.1.1 - Require `base >= 4.11` (GHC 8.4). diff --git a/Diff.cabal b/Diff.cabal index cddc85c..8974d91 100644 --- a/Diff.cabal +++ b/Diff.cabal @@ -1,6 +1,6 @@ Cabal-Version: 1.18 name: Diff -version: 1.0.1.1 +version: 1.0.2 synopsis: Diff algorithm in pure Haskell description: Implementation of the standard diff algorithm in Haskell. . diff --git a/src/Data/Algorithm/DiffContext.hs b/src/Data/Algorithm/DiffContext.hs index f1800f6..ac6761c 100644 --- a/src/Data/Algorithm/DiffContext.hs +++ b/src/Data/Algorithm/DiffContext.hs @@ -150,7 +150,7 @@ prettyContextDiff old new prettyElem hunks = formatHunk hunk = "-" <> formatRun (firsts hunk) <> " +" <> formatRun (seconds hunk) formatRun :: [Int] -> String - formatRun [] = error "empty hunk!" + formatRun [] = "-0,0" formatRun [n] = show n formatRun ns@(n : _) = show n <> "," <> show (length ns) @@ -164,6 +164,7 @@ prettyContextDiff old new prettyElem hunks = seconds (Second ns : more) = fmap (\(Numbered n _) -> n) ns <> seconds more seconds [] = [] +-- | Pretty print without line numbers. prettyContextDiffOld :: Doc -- ^ Document 1 name -> Doc -- ^ Document 2 name diff --git a/test/Test.hs b/test/Test.hs index 169648f..af38ab6 100644 --- a/test/Test.hs +++ b/test/Test.hs @@ -50,11 +50,29 @@ main = defaultMain [ testGroup "sub props" [ { diLeft = ["1","2","3","4","","5","6","7"] , diRight = ["1","2","3","q","b","u","l","","XXX6",""] }), - testProperty "test parse" prop_parse, - testProperty "test context" prop_context_diff + testProperty "test parse" prop_parse + ], + testGroup "context props" [ + testProperty "test context" $ prop_ppContextDiffUnitTest + (DiffInput + { diLeft = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"] + , diRight = ["a", "b", "d", "e", "f", "g", "h", "i", "j"] + }) + "--- a\n+++ b\n@@ -1,5 +1,4 @@\n a\n b\n-c\n d\n e\n@@ -9,3 +8,2 @@\n i\n j\n-k\n", + testProperty "compare with empty" $ prop_ppContextDiffUnitTest + (DiffInput + { diLeft = [] + , diRight = ["1","2","3"] + }) + "--- a\n+++ b\n@@ --0,0 +1,3 @@\n+1\n+2\n+3\n", + testProperty "compare with empty" $ prop_ppContextDiffUnitTest + (DiffInput + { diLeft = ["1","2","3"] + , diRight = [] + }) + "--- a\n+++ b\n@@ -1,3 +-0,0 @@\n-1\n-2\n-3\n" ] ] - slTest s t = testProperty s $ forAll shortLists (t :: [Bool] -> Bool) slTest2 s t = testProperty s $ forAll2 shortLists (t :: [Bool] -> [Bool] -> Bool) @@ -173,6 +191,13 @@ prop_ppDiffR (DiffInput le ri) = hClose h return fp +prop_ppContextDiffUnitTest :: DiffInput -> String -> Property +prop_ppContextDiffUnitTest (DiffInput le ri) expected = + show diff === expected + where + hunks = getContextDiff (Just 2) le ri + diff = prettyContextDiff (text "a") (text "b") (text . unnumber) hunks + -- | Check pretty printed DiffOperations can be parsed again prop_parse :: DiffInput -> Bool prop_parse (DiffInput le ri) = @@ -205,21 +230,6 @@ instance Arbitrary DiffInput where , (2, return prefix) , (2, return [str])] --- | FIXME - make a real quickcheck property -prop_context_diff :: Bool -prop_context_diff = - expected == actual - where - -- Note that the line numbers don't affect equality - expected = [[Both [Numbered 1 "a",Numbered 2 "b"] [Numbered 1 "a",Numbered 2 "b"], - First [Numbered 3 "c"], - Both [Numbered 4 "d",Numbered 5 "e"] [Numbered 3 "d",Numbered 4 "e"]], - [Both [Numbered 9 "i",Numbered 10 "j"] [Numbered 8 "i",Numbered 9 "j"], - First [Numbered 11 "k"]]] - actual = getContextDiff (Just 2) (lines textA) (lines textB) - textA = "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\n" - textB = "a\nb\nd\ne\nf\ng\nh\ni\nj\n" - -- | Reference implementation, very slow. naiveGetDiffBy :: forall a b. (a -> b -> Bool) -> [a] -> [b] -> [PolyDiff a b] naiveGetDiffBy eq as bs = reverse $ (\(Arg _ ds) -> ds) $ tbl A.! (length us, length vs)