File: TestUtil.hs

package info (click to toggle)
ghc 9.10.3-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 168,924 kB
  • sloc: haskell: 713,548; ansic: 84,223; cpp: 30,255; javascript: 9,003; sh: 7,870; fortran: 3,527; python: 3,228; asm: 2,523; makefile: 2,326; yacc: 1,570; lisp: 532; xml: 196; perl: 111; csh: 2
file content (159 lines) | stat: -rw-r--r-- 6,607 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
{-# LANGUAGE CPP #-}
{-# LANGUAGE TypeApplications #-}
{-# OPTIONS_GHC -Wno-orphans #-}

module TestUtil(
    module TestUtil,
    module Test.Tasty.QuickCheck,
    module Data.List,
    module Data.Maybe
    ) where

import Test.Tasty.QuickCheck hiding ((==>))
import Data.ByteString.Short (ShortByteString)
import Data.List
import Data.Maybe
import Control.Monad
import qualified System.FilePath.Windows as W
import qualified System.FilePath.Posix as P
#ifdef GHC_MAKE
import qualified System.OsPath.Windows.Internal as AFP_W
import qualified System.OsPath.Posix.Internal as AFP_P
#else
import qualified System.OsPath.Windows as AFP_W
import qualified System.OsPath.Posix as AFP_P
import System.OsPath.Types
#endif
import System.OsString.Internal.Types
import System.OsString.Encoding.Internal
import GHC.IO.Encoding.UTF16 ( mkUTF16le )
import GHC.IO.Encoding.UTF8 ( mkUTF8 )
import GHC.IO.Encoding.Failure


infixr 0 ==>
(==>) :: Bool -> Bool -> Bool
a ==> b = not a || b


newtype QFilePathValidW = QFilePathValidW FilePath deriving Show

instance Arbitrary QFilePathValidW where
    arbitrary = fmap (QFilePathValidW . W.makeValid) arbitraryFilePath
    shrink (QFilePathValidW x) = shrinkValid QFilePathValidW W.makeValid x

newtype QFilePathValidP = QFilePathValidP FilePath deriving Show

instance Arbitrary QFilePathValidP where
    arbitrary = fmap (QFilePathValidP . P.makeValid) arbitraryFilePath
    shrink (QFilePathValidP x) = shrinkValid QFilePathValidP P.makeValid x

newtype QFilePath = QFilePath FilePath deriving Show

instance Arbitrary QFilePath where
    arbitrary = fmap QFilePath arbitraryFilePath
    shrink (QFilePath x) = shrinkValid QFilePath id x


-- | Generate an arbitrary FilePath use a few special (interesting) characters.
arbitraryFilePath :: Gen FilePath
arbitraryFilePath = sized $ \n -> do
    k <- choose (0,n)
    replicateM k $ elements "?./:\\a ;_"

-- | Shrink, but also apply a validity function. Try and make shorter, or use more
--   @a@ (since @a@ is pretty dull), but make sure you terminate even after valid.
shrinkValid :: (FilePath -> a) -> (FilePath -> FilePath) -> FilePath -> [a]
shrinkValid wrap valid o =
    [ wrap y
    | y <- map valid $ shrinkList (\x -> ['a' | x /= 'a']) o
    , length y < length o || (length y == length o && countA y > countA o)]
    where countA = length . filter (== 'a')

encodeUtf16LE :: String -> ShortByteString
encodeUtf16LE = either (error . show) id . encodeWithTE (mkUTF16le TransliterateCodingFailure)

encodeUtf8 :: String -> ShortByteString
encodeUtf8 = either (error . show) id . encodeWithTE (mkUTF8 TransliterateCodingFailure)

decodeUtf16LE :: ShortByteString -> String
decodeUtf16LE = either (error . show) id . decodeWithTE (mkUTF16le TransliterateCodingFailure)

decodeUtf8 :: ShortByteString -> String
decodeUtf8 = either (error . show) id . decodeWithTE (mkUTF8 TransliterateCodingFailure)

#ifdef GHC_MAKE
newtype QFilePathValidAFP_W = QFilePathValidAFP_W ShortByteString deriving Show

instance Arbitrary QFilePathValidAFP_W where
    arbitrary = fmap (QFilePathValidAFP_W . AFP_W.makeValid . encodeUtf16LE) arbitraryFilePath
    shrink (QFilePathValidAFP_W x) = shrinkValid (QFilePathValidAFP_W . encodeUtf16LE) (decodeUtf16LE . AFP_W.makeValid . encodeUtf16LE) (decodeUtf16LE x)

newtype QFilePathValidAFP_P = QFilePathValidAFP_P ShortByteString deriving Show

instance Arbitrary QFilePathValidAFP_P where
    arbitrary = fmap (QFilePathValidAFP_P . AFP_P.makeValid . encodeUtf8) arbitraryFilePath
    shrink (QFilePathValidAFP_P x) = shrinkValid (QFilePathValidAFP_P . encodeUtf8) (decodeUtf8 . AFP_P.makeValid . encodeUtf8) (decodeUtf8 x)

newtype QFilePathAFP_W = QFilePathAFP_W ShortByteString deriving Show
newtype QFilePathAFP_P = QFilePathAFP_P ShortByteString deriving Show

instance Arbitrary QFilePathAFP_W where
    arbitrary = fmap (QFilePathAFP_W . encodeUtf16LE) arbitraryFilePath
    shrink (QFilePathAFP_W x) = shrinkValid (QFilePathAFP_W . encodeUtf16LE) id (decodeUtf16LE x)

instance Arbitrary QFilePathAFP_P where
    arbitrary = fmap (QFilePathAFP_P . encodeUtf8) arbitraryFilePath
    shrink (QFilePathAFP_P x) = shrinkValid (QFilePathAFP_P . encodeUtf8) id (decodeUtf8 x)

newtype QFilePathsAFP_W = QFilePathsAFP_W [ShortByteString] deriving Show
newtype QFilePathsAFP_P = QFilePathsAFP_P [ShortByteString] deriving Show

instance Arbitrary QFilePathsAFP_W where
    arbitrary = fmap (QFilePathsAFP_W . fmap encodeUtf16LE) (listOf arbitraryFilePath)

instance Arbitrary QFilePathsAFP_P where
    arbitrary = fmap (QFilePathsAFP_P . fmap encodeUtf8) (listOf arbitraryFilePath)

#else


newtype QFilePathValidAFP_W = QFilePathValidAFP_W WindowsPath deriving Show

instance Arbitrary QFilePathValidAFP_W where
    arbitrary = fmap (QFilePathValidAFP_W . AFP_W.makeValid . WS . encodeUtf16LE) arbitraryFilePath
    shrink (QFilePathValidAFP_W x) = shrinkValid (QFilePathValidAFP_W . WS . encodeUtf16LE) (decodeUtf16LE . getWindowsString . AFP_W.makeValid . WS . encodeUtf16LE) (decodeUtf16LE . getWindowsString $ x)

newtype QFilePathValidAFP_P = QFilePathValidAFP_P PosixPath deriving Show

instance Arbitrary QFilePathValidAFP_P where
    arbitrary = fmap (QFilePathValidAFP_P . AFP_P.makeValid . PS . encodeUtf8) arbitraryFilePath
    shrink (QFilePathValidAFP_P x) = shrinkValid (QFilePathValidAFP_P . PS . encodeUtf8) (decodeUtf8 . getPosixString . AFP_P.makeValid . PS . encodeUtf8) (decodeUtf8 . getPosixString $ x)

newtype QFilePathAFP_W = QFilePathAFP_W WindowsPath deriving Show
newtype QFilePathAFP_P = QFilePathAFP_P PosixPath deriving Show

instance Arbitrary QFilePathAFP_W where
    arbitrary = fmap (QFilePathAFP_W . WS . encodeUtf16LE) arbitraryFilePath
    shrink (QFilePathAFP_W x) = shrinkValid (QFilePathAFP_W . WS . encodeUtf16LE) id (decodeUtf16LE . getWindowsString $ x)

instance Arbitrary QFilePathAFP_P where
    arbitrary = fmap (QFilePathAFP_P . PS . encodeUtf8) arbitraryFilePath
    shrink (QFilePathAFP_P x) = shrinkValid (QFilePathAFP_P . PS . encodeUtf8) id (decodeUtf8 . getPosixString $ x)

newtype QFilePathsAFP_W = QFilePathsAFP_W [WindowsPath] deriving Show
newtype QFilePathsAFP_P = QFilePathsAFP_P [PosixPath] deriving Show

instance Arbitrary QFilePathsAFP_W where
    arbitrary = fmap (QFilePathsAFP_W . fmap (WS . encodeUtf16LE)) (listOf arbitraryFilePath)

instance Arbitrary QFilePathsAFP_P where
    arbitrary = fmap (QFilePathsAFP_P . fmap (PS . encodeUtf8)) (listOf arbitraryFilePath)

instance Arbitrary WindowsChar where
  arbitrary = WW <$> arbitrary

instance Arbitrary PosixChar where
  arbitrary = PW <$> arbitrary
#endif