{-# LANGUAGE ScopedTypeVariables #-} module Test.Hspec.Core.Formatters.DiffSpec (spec) where import Prelude () import Helper hiding (First) import Data.Char import Test.Hspec.Core.Formatters.Diff as Diff dropQuotes :: String -> String dropQuotes = init . drop 1 spec :: Spec spec = do describe "lineDiff" $ do let enumerate name n = map ((name ++) . show) [1 .. n :: Int] diff_ expected actual = lineDiff (Just 2) (unlines expected) (unlines actual) it "suppresses excessive diff output" $ do let expected = enumerate "foo" 99 actual = replace "foo50" "bar50" expected diff_ expected actual `shouldBe` [ LinesOmitted 47 , LinesBoth [ "foo48" , "foo49" ] , SingleLineDiff [First "foo50", Second "bar50"] , LinesBoth [ "foo51" , "foo52" ] , LinesOmitted 47 , LinesBoth [""] ] it "ensures that omitted sections are at least three lines in size" $ do forAll (elements [1..20]) $ \ size -> do let expected = enumerate "" size forAll (elements expected) $ \ i -> do let actual = replace i "bar" expected [n | LinesOmitted n <- diff_ expected actual] `shouldSatisfy` all (>= 3) context "with modifications within a line" $ do it "suppresses excessive diff output" $ do let expected = enumerate "foo " 99 actual = replace "foo 42" "foo 23" expected diff_ expected actual `shouldBe` [ LinesOmitted 39 , LinesBoth [ "foo 40" , "foo 41" ] , SingleLineDiff [Both "foo ", First "42", Second "23"] , LinesBoth [ "foo 43" , "foo 44" ] , LinesOmitted 55 , LinesBoth [""] ] context "with modifications at start / end" $ do it "suppresses excessive diff output" $ do let expected = enumerate "foo" 9 actual = replace "foo9" "bar9" $ replace "foo1" "bar1" expected diff_ expected actual `shouldBe` [ SingleLineDiff [First "foo1", Second "bar1"] , LinesBoth [ "foo2" , "foo3" ] , LinesOmitted 3 , LinesBoth [ "foo7" , "foo8" ] , SingleLineDiff [First "foo9", Second "bar9"] , LinesBoth [""] ] describe "splitLines" $ do it "splits on newline characters" $ do splitLines "foo\nbar\nbaz" `shouldBe` ["foo", "bar", "baz"] describe "with a newline characters at the start" $ do it "splits on newline characters" $ do splitLines "\nfoo\nbar\nbaz" `shouldBe` ["", "foo", "bar", "baz"] describe "with a newline characters at the end" $ do it "splits on newline characters" $ do splitLines "foo\nbar\nbaz\n" `shouldBe` ["foo", "bar", "baz", ""] describe "partition" $ do context "with a single shown Char" $ do it "never partitions a character escape" $ do property $ \ (c :: Char) -> partition (show c) `shouldBe` ["'", dropQuotes (show c), "'"] context "with a shown String" $ do it "puts backslash-escaped characters into separate chunks" $ do partition (show "foo\nbar") `shouldBe` ["\"", "foo", "\\n", "bar", "\""] it "puts *arbitrary* backslash-escaped characters into separate chunks" $ do property $ \ xs c ys -> let char = dropQuotes (show [c]) isEscaped = length char > 1 escape = drop 1 char sep = case ys of x : _ | all isDigit escape && isDigit x || escape == "SO" && x == 'H' -> ["\\&"] _ -> [] actual = partition (show (xs ++ c : ys)) expected = partition (init $ show xs) ++ [char] ++ sep ++ partition (drop 1 $ show ys) in isEscaped ==> actual `shouldBe` expected describe "breakList" $ do context "with a list where the predicate matches at the beginning and the end" $ do it "breaks the list into pieces" $ do breakList isAlphaNum "foo bar baz" `shouldBe` ["foo", " ", "bar", " ", " ", "baz"] context "with a list where the predicate does not match at the beginning and the end" $ do it "breaks the list into pieces" $ do breakList isAlphaNum " foo bar baz " `shouldBe` [" ", " ", "foo", " ", "bar", " ", " ", "baz", " ", " "]