File: DiffSpec.hs

package info (click to toggle)
haskell-hspec-core 2.11.16-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 700 kB
  • sloc: haskell: 9,452; makefile: 3
file content (130 lines) | stat: -rw-r--r-- 4,569 bytes parent folder | download
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
{-# LANGUAGE ScopedTypeVariables #-}
module Test.Hspec.Core.Formatters.DiffSpec (spec) where

import           Prelude ()
import           Helper
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", " ", " "]