File: LocationSpec.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 (142 lines) | stat: -rw-r--r-- 4,881 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
131
132
133
134
135
136
137
138
139
140
141
142
{-# LANGUAGE CPP #-}
{-# OPTIONS_GHC -fno-warn-incomplete-patterns #-}
{-# OPTIONS_GHC -fno-warn-missing-fields #-}
{-# OPTIONS_GHC -fno-warn-overlapping-patterns #-}
{-# OPTIONS_GHC -fno-warn-missing-methods #-}
{-# OPTIONS_GHC -fno-warn-incomplete-uni-patterns #-}
{-# OPTIONS_GHC -O0 #-}
module Test.Hspec.Core.Example.LocationSpec (spec) where

import           Prelude ()
import           Helper

import           Test.Hspec.Core.Example
import           Test.Hspec.Core.Example.Location

class SomeClass a where
  someMethod :: a -> IO ()

instance SomeClass () where

data Person = Person {
  name :: String
, age :: Int
} deriving (Eq, Show)

spec :: Spec
spec = do
  describe "parseAssertionFailed" $ do
    context "with pre-GHC-8.* error message" $ do
      it "extracts source location" $ do
        parseAssertionFailed "Foo.hs:4:7-12: Assertion failed\n" `shouldBe` Just (Location "Foo.hs" 4 7)

  describe "extractLocation" $ do
    context "with pattern match failure in do expression" $ do
      context "in IO" $ do
        it "extracts Location" $ do
          let location = Just $ Location file (__LINE__ + 2) 13
          Left e <- try $ do
            Just n <- return Nothing
            return (n :: Int)
          extractLocation e `shouldBe` location

#if !MIN_VERSION_base(4,12,0)
      context "in Either" $ do
        it "extracts Location" $ do
          let location = Just $ Location file (__LINE__ + 4) 15
          let
            foo :: Either () ()
            foo = do
              23 <- Right (42 :: Int)
              pass
          Left e <- try (evaluate foo)
          extractLocation e `shouldBe` location
#endif

    context "with ErrorCall" $ do
      it "extracts Location" $ do
        let
          location =
            Just $ Location file (succ __LINE__) 34
        Left e <- try (evaluate (undefined :: ()))
        extractLocation e `shouldBe` location

    context "with PatternMatchFail" $ do
      context "with single-line source span" $ do
        it "extracts Location" $ do
          let
            location = Just $ Location file (__LINE__ + 1) 40
          Left e <- try (evaluate (let Just n = Nothing in (n :: Int)))
          extractLocation e `shouldBe` location

      context "with multi-line source span" $ do
        it "extracts Location" $ do
          let location = Just $ Location file (__LINE__ + 1) 36
          Left e <- try (evaluate (case Nothing of
            Just n -> n :: Int
            ))
          extractLocation e `shouldBe` location

    context "with RecConError" $ do
      it "extracts Location" $ do
        let
          location = Just $ Location file (__LINE__ + 1) 39
        Left e <- try $ evaluate (age Person {name = "foo"})
        extractLocation e `shouldBe` location

    context "with NoMethodError" $ do
      it "extracts Location" $ do
        Left e <- try $ someMethod ()
        extractLocation e `shouldBe` Just (Location file 19 10)

    context "with AssertionFailed" $ do
      it "extracts Location" $ do
        let
          location = Just $ Location file (__LINE__ + 1) 36
        Left e <- try . evaluate $ assert False ()
        extractLocation e `shouldBe` location

  describe "parseBacktraces" $ do
    it "parses Location from Backtraces" $ do
      let
        input :: String
        input = unlines [
            "Cost-centre stack backtrace:"
          , "  ..."
          , "IPE backtrace:"
          , "  ..."
          , "HasCallStack backtrace:"
          , "  foo, called at Foo.hs:23:7 in main:Foo"
          , "  bar, called at Foo.hs:42:7 in main:Foo"
          , "  baz, called at Foo.hs:65:9 in main:Foo"
          , "..."
          , "  ..."
          ]
      parseBacktraces input `shouldBe` Just Location {
        locationFile = "Foo.hs"
      , locationLine = 65
      , locationColumn = 9
      }

  describe "parseCallStack" $ do
    it "parses Location from call stack" $ do
      let input = [
              "CallStack (from HasCallStack):"
            , "  error, called at libraries/base/GHC/Err.hs:79:14 in base:GHC.Err"
            , "  undefined, called at test/Test/Hspec.hs:13:32 in main:Test.Hspec"
            ]
      parseCallStack input `shouldBe` Just (Location ("test" </> "Test" </> "Hspec.hs") 13 32)

  describe "parseLocation" $ do
    it "parses Location" $ do
      parseLocation "test/Test/Hspec.hs:13:32" `shouldBe` Just (Location ("test" </> "Test" </> "Hspec.hs") 13 32)

  describe "parseSourceSpan" $ do
    it "parses single-line source span" $ do
      parseSourceSpan "test/Test/Hspec.hs:25:36-51:" `shouldBe` Just (Location ("test" </> "Test" </> "Hspec.hs") 25 36)

    it "parses multi-line source span" $ do
      parseSourceSpan "test/Test/Hspec.hs:(15,7)-(17,26):" `shouldBe` Just (Location ("test" </> "Test" </> "Hspec.hs") 15 7)

file :: FilePath
file = workaroundForIssue19236 __FILE__