-- |
-- Copyright: © 2018-2020 IOHK
-- License: Apache-2.0
--
-- File path related test utilities.

module Test.Utils.FilePath
    ( PathElement (..)
    ) where

import Prelude

import System.FilePath.Windows
    ( makeValid )
import Test.QuickCheck
    ( Arbitrary (..), elements, listOf1, scale )
import Test.Utils.Windows
    ( isWindows )

-- | A file or directory name. The 'Arbitrary' instance will generate values
-- which are valid on Windows and POSIX.
--
-- <https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file>
newtype PathElement = PathElement FilePath deriving (Int -> PathElement -> ShowS
[PathElement] -> ShowS
PathElement -> String
(Int -> PathElement -> ShowS)
-> (PathElement -> String)
-> ([PathElement] -> ShowS)
-> Show PathElement
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PathElement] -> ShowS
$cshowList :: [PathElement] -> ShowS
show :: PathElement -> String
$cshow :: PathElement -> String
showsPrec :: Int -> PathElement -> ShowS
$cshowsPrec :: Int -> PathElement -> ShowS
Show, PathElement -> PathElement -> Bool
(PathElement -> PathElement -> Bool)
-> (PathElement -> PathElement -> Bool) -> Eq PathElement
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PathElement -> PathElement -> Bool
$c/= :: PathElement -> PathElement -> Bool
== :: PathElement -> PathElement -> Bool
$c== :: PathElement -> PathElement -> Bool
Eq)

instance Arbitrary PathElement where
    arbitrary :: Gen PathElement
arbitrary = String -> PathElement
PathElement (String -> PathElement) -> ShowS -> String -> PathElement
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS
makeValid' (String -> PathElement) -> Gen String -> Gen PathElement
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen String -> Gen String
forall a. Gen a -> Gen a
limitLen Gen String
genName
      where
        genName :: Gen String
genName = Gen Char -> Gen String
forall a. Gen a -> Gen [a]
listOf1 (String -> Gen Char
forall a. [a] -> Gen a
elements [Char
'a'..Char
'z'])
        limitLen :: Gen a -> Gen a
limitLen = (Int -> Int) -> Gen a -> Gen a
forall a. (Int -> Int) -> Gen a -> Gen a
scale (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
250)

makeValid' :: FilePath -> FilePath
makeValid' :: ShowS
makeValid' = if Bool
isWindows then ShowS
makeValid else ShowS
forall a. a -> a
id