File: ValiditySpec.hs

package info (click to toggle)
haskell-validity 0.12.1.0-1
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 88 kB
  • sloc: haskell: 538; makefile: 5
file content (165 lines) | stat: -rw-r--r-- 8,189 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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE MagicHash #-}

module Data.ValiditySpec
  ( spec,
  )
where

import Data.Maybe
import Data.Validity
import GHC.Exts (Char (..), chr#)
import GHC.Generics (Generic)
import GHC.Int (Int16 (..), Int32 (..), Int8 (..))
import GHC.Real (Ratio (..), infinity, notANumber)
import GHC.Word (Word16 (..), Word32 (..), Word8 (..))
import Test.Hspec

newtype NormalisedRatio a
  = NormalisedRatio (Ratio a)
  deriving (Show, Eq, Generic)

instance (Validity a, Integral a) => Validity (NormalisedRatio a) where
  validate nr@(NormalisedRatio r) =
    mconcat
      [ genericValidate nr,
        validateRatioNotNaN r,
        validateRatioNotInfinite r,
        validateRatioNormalised r
      ]

data Wrong
  = Wrong
  | Fine
  deriving (Show, Eq)

instance Validity Wrong where
  validate w =
    case w of
      Wrong -> invalid "Wrong"
      Fine -> valid

data GeneratedValidity
  = G Rational Rational
  deriving (Show, Eq, Generic)

instance Validity GeneratedValidity

spec :: Spec
spec = do
  describe "Small numbers" $ do
    describe "Validity Int8" $ do
      it "Says that minBound is valid" $ isValid (minBound :: Int8) `shouldBe` True
      it "Says that maxBound is valid" $ isValid (maxBound :: Int8) `shouldBe` True
#if MIN_VERSION_base(4,16,0)
#else
      it "Says that Int# 200 is invalid" $ isValid (I8# 200#) `shouldBe` False
      it "Says that Int# -200 is invalid" $ isValid (I8# (-200#)) `shouldBe` False
#endif
    describe "Validity Int16" $ do
      it "Says that minBound is valid" $ isValid (minBound :: Int16) `shouldBe` True
      it "Says that maxBound is valid" $ isValid (maxBound :: Int16) `shouldBe` True
#if MIN_VERSION_base(4,16,0)
#else
      it "Says that Int# 4000 is invalid" $ isValid (I16# 40000#) `shouldBe` False
      it "Says that Int# -4000 is invalid" $ isValid (I16# (-40000#)) `shouldBe` False
#endif
    describe "Validity Int32" $ do
      it "Says that minBound is valid" $ isValid (minBound :: Int32) `shouldBe` True
      it "Says that maxBound is valid" $ isValid (maxBound :: Int32) `shouldBe` True
#if MIN_VERSION_base(4,16,0)
#else
      it "Says that Int# 2200000000 is invalid" $ isValid (I32# 2200000000#) `shouldBe` False
      it "Says that Int# -2200000000 is invalid" $ isValid (I32# (-2200000000#)) `shouldBe` False
#endif
    describe "Validity Word8" $ do
      it "Says that minBound is valid" $ isValid (minBound :: Word8) `shouldBe` True
      it "Says that maxBound is valid" $ isValid (maxBound :: Word8) `shouldBe` True
#if MIN_VERSION_base(4,16,0)
#else
      it "Says that Word# 300 is invalid" $ isValid (W8# 300##) `shouldBe` False
#endif
    describe "Validity Word16" $ do
      it "Says that minBound is valid" $ isValid (minBound :: Word16) `shouldBe` True
      it "Says that maxBound is valid" $ isValid (maxBound :: Word16) `shouldBe` True
#if MIN_VERSION_base(4,16,0)
#else
      it "Says that Word# 80000 is invalid" $ isValid (W16# 80000##) `shouldBe` False
#endif
    describe "Validity Word32" $ do
      it "Says that minBound is valid" $ isValid (minBound :: Word32) `shouldBe` True
      it "Says that maxBound is valid" $ isValid (maxBound :: Word32) `shouldBe` True
#if MIN_VERSION_base(4,16,0)
#else
      it "Says that Word# 4800000000 is invalid" $ isValid (W32# 4800000000##) `shouldBe` False
#endif
  describe "Chars" $ do
    describe "Small" $ do
      describe "Validity Char" $ do
        it "Says that minBound is valid" $ isValid (minBound :: Char) `shouldBe` True
        it "Says that maxBound is valid" $ isValid (maxBound :: Char) `shouldBe` True
        it "Says that 2147483647 is invalid" $ isValid (C# (chr# 2147483647#)) `shouldBe` False
        it "Says that a negative char is invalid" $ isValid (C# (chr# -1#)) `shouldBe` False
        it "Says that a very positive char is invalid" $ isValid (C# (chr# 9223372036854775807#)) `shouldBe` False
        it "Says that a very negative char is invalid" $ isValid (C# (chr# -9223372036854775808#)) `shouldBe` False
    describe "Weird" $ do
      describe "isUtf16SurrogateCodePoint" $ do
        it "Says that a is a valid char" $ isUtf16SurrogateCodePoint 'a' `shouldBe` False
        it "Says that \\55810 is an invalid char" $ isUtf16SurrogateCodePoint '\55810' `shouldBe` True
      describe "validateCharNotUtf16SurrogateCodePoint" $ do
        it "Says that a is a valid char" $
          prettyValidation (validateCharNotUtf16SurrogateCodePoint 'a') `shouldSatisfy` isNothing
        it "Says that \\55810 is an invalid char" $
          prettyValidation (validateCharNotUtf16SurrogateCodePoint '\55810') `shouldSatisfy` isJust
    describe "Lines" $ do
      describe "isLineSeparator" $ do
        it "Says that a is not a line separator" $ isLineSeparator 'a' `shouldBe` False
        it "Says that '\\n' is a line separator " $ isLineSeparator '\n' `shouldBe` True
        it "Says that '\\r' is a line separator " $ isLineSeparator '\r' `shouldBe` True
      describe "validateCharNotLineSeparator" $ do
        it "Says that a is not a line separator" $
          prettyValidation (validateCharNotLineSeparator 'a') `shouldSatisfy` isNothing
        it "Says that '\\n' is a line separator" $
          prettyValidation (validateCharNotLineSeparator '\n') `shouldSatisfy` isJust
        it "Says that '\\r' is a line separator" $
          prettyValidation (validateCharNotLineSeparator '\r') `shouldSatisfy` isJust
      describe "isSingleLine" $ do
        it "says that \"abc\" is a single line" $ isSingleLine "abc" `shouldBe` True
        it "says that \"d\ne\" is a single line" $ isSingleLine "d\ne" `shouldBe` False
      describe "validateStringSingleLine" $ do
        it "says that \"abc\" is a single line" $ prettyValidation (validateStringSingleLine "abc") `shouldSatisfy` isNothing
        it "says that \"d\ne\" is a single line" $ prettyValidation (validateStringSingleLine "d\ne") `shouldSatisfy` isJust
  describe "Ratio" $ do
    it "says that 0 is valid" $ NormalisedRatio (0 :% 1 :: Ratio Int) `shouldSatisfy` isValid
    it "says that 1 is valid" $ NormalisedRatio (1 :% 1 :: Ratio Int) `shouldSatisfy` isValid
    it "says that minBound is valid" $
      NormalisedRatio (minBound :% 1 :: Ratio Int) `shouldSatisfy` isValid
    it "says that maxBound is valid" $
      NormalisedRatio (maxBound :% 1 :: Ratio Int) `shouldSatisfy` isValid
    it "says that maxBound / minBound is invalid" $
      NormalisedRatio (maxBound :% minBound :: Ratio Int) `shouldSatisfy` (not . isValid)
    it "says that minBound / maxBound is invalid" $
      NormalisedRatio (minBound :% maxBound :: Ratio Int) `shouldSatisfy` (not . isValid)
    it "says that minBound / 2957808295740799111 is valid" $
      NormalisedRatio (minBound :% (2957808295740799111) :: Ratio Int) `shouldSatisfy` isValid
  describe "NormalisedRatio" $ do
    it "says that NaN is invalid" $ NormalisedRatio notANumber `shouldSatisfy` (not . isValid)
    it "says that +Inf is invalid" $ NormalisedRatio infinity `shouldSatisfy` (not . isValid)
    it "says that -Inf is invalid" $ NormalisedRatio (-infinity) `shouldSatisfy` (not . isValid)
    it "says that these non-normalised numbers are invalid" $ do
      NormalisedRatio ((5 :: Integer) :% 5) `shouldSatisfy` (not . isValid)
      NormalisedRatio ((1 :: Integer) :% (-5)) `shouldSatisfy` (not . isValid)
      NormalisedRatio ((6 :: Integer) :% 2) `shouldSatisfy` (not . isValid)
      NormalisedRatio ((2 :: Integer) :% 6) `shouldSatisfy` (not . isValid)
      NormalisedRatio ((2 :: Integer) :% 0) `shouldSatisfy` (not . isValid)
      NormalisedRatio ((0 :: Integer) :% 5) `shouldSatisfy` (not . isValid)
      NormalisedRatio ((0 :: Integer) :% 0) `shouldSatisfy` (not . isValid)
  describe "Wrong" $ do
    it "says Wrong is invalid" $ Wrong `shouldSatisfy` (not . isValid)
    it "says Fine is valid" $ Fine `shouldSatisfy` isValid
  describe "GeneratedValidity" $ do
    let nan = 1 :% 0
    it "says G (1:%0) 0 is not valid" $ G nan 0 `shouldSatisfy` (not . isValid)
    it "says G 0 (1:%0) is not valid" $ G 0 nan `shouldSatisfy` (not . isValid)
    it "says G 0 0 is valid" $ G 0 0 `shouldSatisfy` isValid