File: UtilSpec.hs

package info (click to toggle)
haskell-hspec-core 2.11.9-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 656 kB
  • sloc: haskell: 8,945; makefile: 5
file content (122 lines) | stat: -rw-r--r-- 4,698 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
module Test.Hspec.Core.UtilSpec (spec) where

import           Prelude ()
import           Helper

import           Control.Concurrent

import           Test.Hspec.Core.Util

spec :: Spec
spec = do
  describe "pluralize" $ do
    it "returns singular when used with 1" $ do
      pluralize 1 "thing" `shouldBe` "1 thing"

    it "returns plural when used with number greater 1" $ do
      pluralize 2 "thing" `shouldBe` "2 things"

    it "returns plural when used with 0" $ do
      pluralize 0 "thing" `shouldBe` "0 things"

  describe "formatException" $ do
    it "converts exception to string" $ do
      formatException (toException DivideByZero) `shouldBe` "ArithException\ndivide by zero"

    context "when used with an IOException" $ do
      it "includes the IOErrorType" $ do
        inTempDirectory $ do
          Left e <- try (readFile "foo")
          formatException e `shouldBe` intercalate "\n" [
              "IOException of type NoSuchThing"
            , "foo: openFile: does not exist (No such file or directory)"
            ]

  describe "lineBreaksAt" $ do
    it "inserts line breaks at word boundaries" $ do
      lineBreaksAt 20 "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod"
      `shouldBe` [
          "Lorem ipsum dolor"
        , "sit amet,"
        , "consectetur"
        , "adipisicing elit,"
        , "sed do eiusmod"
        ]

    it "preserves existing line breaks" $ do
      lineBreaksAt 10 "foo bar baz\none two three" `shouldBe` [
          "foo bar"
        , "baz"
        , "one two"
        , "three"
        ]

  describe "stripAnsi" $ do
    it "removes ANSI color sequences" $ do
      stripAnsi ("some " <> green "colorized" <> " text") `shouldBe` "some colorized text"

  describe "safeTry" $ do
    it "returns Right on success" $ do
      Right e <- safeTry (return 23 :: IO Int)
      e `shouldBe` 23

    it "returns Left on exception" $ do
      Left e <- safeTry throwException
      fromException e `shouldBe` Just DivideByZero

    it "evaluates result to weak head normal form" $ do
      Left e <- safeTry (return $ throw $ ErrorCall "foo")
      show e `shouldBe` "foo"

    it "does not catch asynchronous exceptions" $ do
      mvar <- newEmptyMVar
      sync <- newEmptyMVar
      threadId <- forkIO $ do
        safeTry (putMVar sync () >> threadDelay 1000000) >> pass
        `catch` putMVar mvar
      takeMVar sync
      throwTo threadId UserInterrupt
      readMVar mvar `shouldReturn` UserInterrupt

  describe "filterPredicate" $ do
    it "tries to match a pattern against a path" $ do
      let p = filterPredicate "foo/bar/example 1"
      p (["foo", "bar"], "example 1") `shouldBe` True
      p (["foo", "bar"], "example 2") `shouldBe` False

    it "is ambiguous" $ do
      let p = filterPredicate "foo/bar/baz"
      p (["foo", "bar"], "baz") `shouldBe` True
      p (["foo"], "bar/baz") `shouldBe` True

    it "succeeds on a partial match" $ do
      let p = filterPredicate "bar/baz"
      p (["foo", "bar", "baz"], "example 1") `shouldBe` True

    it "succeeds with a pattern that matches the message given in the failure list" $ do
      let p = filterPredicate "ModuleA.ModuleB.foo does something"
      p (["ModuleA", "ModuleB", "foo"], "does something") `shouldBe` True

    context "with an absolute path that begins or ends with a slash" $ do
      it "succeeds" $ do
        let p = filterPredicate "/foo/bar/baz/example 1/"
        p (["foo", "bar", "baz"], "example 1") `shouldBe` True

  describe "formatRequirement" $ do
    it "creates a sentence from a subject and a requirement" $ do
      formatRequirement (["reverse"], "reverses a list") `shouldBe` "reverse reverses a list"

    it "creates a sentence from a subject and a requirement when the subject consists of multiple words" $ do
      formatRequirement (["The reverse function"], "reverses a list") `shouldBe` "The reverse function reverses a list"

    it "returns the requirement if no subject is given" $ do
      formatRequirement ([], "reverses a list") `shouldBe` "reverses a list"

    it "inserts context separated by commas" $ do
      formatRequirement (["reverse", "when applied twice"], "reverses a list") `shouldBe` "reverse, when applied twice, reverses a list"

    it "joins components of a subject with a dot" $ do
      formatRequirement (["Data", "List", "reverse"], "reverses a list") `shouldBe` "Data.List.reverse reverses a list"

    it "properly handles context after a subject that consists of several components" $ do
      formatRequirement (["Data", "List", "reverse", "when applied twice"], "reverses a list") `shouldBe` "Data.List.reverse, when applied twice, reverses a list"