{-# OPTIONS_GHC -fno-warn-orphans #-}

module Data.GenValidity.DirForest where

import Data.DirForest (DirForest (..), DirTree (..), FOD (..))
import qualified Data.DirForest as DF
import Data.GenValidity
import Data.GenValidity.Containers ()
import Data.GenValidity.Path ()
import qualified Data.Map as M
import Path
import System.FilePath as FP
import Test.QuickCheck

instance GenValid a => GenValid (FOD a) where
  shrinkValid :: FOD a -> [FOD a]
shrinkValid = forall a.
(Generic a, GValidRecursivelyShrink (Rep a),
 GValidSubterms (Rep a) a) =>
a -> [a]
shrinkValidStructurallyWithoutExtraFiltering
  genValid :: Gen (FOD a)
genValid = forall a. (Generic a, GGenValid (Rep a)) => Gen a
genValidStructurallyWithoutExtraChecking

instance (Ord a, GenValid a) => GenValid (DirForest a) where
  shrinkValid :: DirForest a -> [DirForest a]
shrinkValid = forall a.
(Validity a, Generic a, GValidRecursivelyShrink (Rep a),
 GValidSubterms (Rep a) a) =>
a -> [a]
shrinkValidStructurally
  genValid :: Gen (DirForest a)
genValid = forall a. Ord a => Gen a -> Gen (DirForest a)
genDirForestOf forall a. GenValid a => Gen a
genValid

instance (Ord a, GenValid a) => GenValid (DirTree a) where
  genValid :: Gen (DirTree a)
genValid = forall a. Ord a => Gen a -> Gen (DirTree a)
genDirTreeOf forall a. GenValid a => Gen a
genValid
  shrinkValid :: DirTree a -> [DirTree a]
shrinkValid = forall a.
(Generic a, GValidRecursivelyShrink (Rep a),
 GValidSubterms (Rep a) a) =>
a -> [a]
shrinkValidStructurallyWithoutExtraFiltering

genDirForestOf :: Ord a => Gen a -> Gen (DirForest a)
genDirForestOf :: forall a. Ord a => Gen a -> Gen (DirForest a)
genDirForestOf Gen a
gen = forall a. Map FilePath (DirTree a) -> DirForest a
DirForest forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. Ord k => [(k, a)] -> Map k a
M.fromList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Gen a -> Gen [a]
genListOf Gen (FilePath, DirTree a)
genPathValuePair
  where
    genPathValuePair :: Gen (FilePath, DirTree a)
genPathValuePair = forall a. (Int -> Gen a) -> Gen a
sized forall a b. (a -> b) -> a -> b
$ \Int
s -> do
      (Int
a, Int
b) <- Int -> Gen (Int, Int)
genSplit Int
s
      forall a. [Gen a] -> Gen a
oneof
        [ (,)
            forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Int -> Gen a -> Gen a
resize Int
a (Path Rel File -> FilePath
fromRelFile forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. GenValid a => Gen a
genValid)
            forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Int -> Gen a -> Gen a
resize Int
b (forall a. a -> DirTree a
NodeFile forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen a
gen),
          (,)
            forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Int -> Gen a -> Gen a
resize Int
a (FilePath -> FilePath
FP.dropTrailingPathSeparator forall b c a. (b -> c) -> (a -> b) -> a -> c
. Path Rel Dir -> FilePath
fromRelDir forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. GenValid a => Gen a
genValid)
            forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Int -> Gen a -> Gen a
resize Int
b (forall a. DirForest a -> DirTree a
NodeDir forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Ord a => Gen a -> Gen (DirForest a)
genDirForestOf Gen a
gen)
        ]

genDirTreeOf :: Ord a => Gen a -> Gen (DirTree a)
genDirTreeOf :: forall a. Ord a => Gen a -> Gen (DirTree a)
genDirTreeOf Gen a
gen =
  forall a. (Int -> Gen a) -> Gen a
sized forall a b. (a -> b) -> a -> b
$ \Int
s ->
    forall a. [Gen a] -> Gen a
oneof
      [ forall a. a -> DirTree a
NodeFile forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Int -> Gen a -> Gen a
resize (forall a. Ord a => a -> a -> a
max Int
0 forall a b. (a -> b) -> a -> b
$ Int
s forall a. Num a => a -> a -> a
- Int
1) Gen a
gen,
        forall a. DirForest a -> DirTree a
NodeDir forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Int -> Gen a -> Gen a
resize (forall a. Ord a => a -> a -> a
max Int
0 forall a b. (a -> b) -> a -> b
$ Int
s forall a. Num a => a -> a -> a
- Int
1) (forall a. Ord a => Gen a -> Gen (DirForest a)
genDirForestOf Gen a
gen)
      ]

changedDirForest :: (Ord a, GenValid a) => DirForest a -> Gen (DirForest a)
changedDirForest :: forall a. (Ord a, GenValid a) => DirForest a -> Gen (DirForest a)
changedDirForest = forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (\a
v -> forall a. GenValid a => Gen a
genValid forall a. Gen a -> (a -> Bool) -> Gen a
`suchThat` (forall a. Eq a => a -> a -> Bool
/= a
v))

disjunctDirForest :: (Ord a, GenValid a) => DirForest a -> Gen (DirForest a)
disjunctDirForest :: forall a. (Ord a, GenValid a) => DirForest a -> Gen (DirForest a)
disjunctDirForest DirForest a
m = forall a. GenValid a => Gen a
genValid forall a. Gen a -> (a -> Bool) -> Gen a
`suchThat` (forall a. DirForest a -> Bool
DF.null forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. DirForest a -> DirForest b -> DirForest a
DF.intersection DirForest a
m)