packages feed

digestive-functors-0.7.1.1: tests/Text/Digestive/Form/QTests.hs

--------------------------------------------------------------------------------
{-# LANGUAGE GADTs             #-}
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Text.Digestive.Form.QTests
       ( tests
       ) where

--------------------------------------------------------------------------------
import           Test.Framework
import           Test.Framework.Providers.QuickCheck2
import           Test.QuickCheck                      hiding (Success)


--------------------------------------------------------------------------------
import           Text.Digestive.Form.Internal
import           Text.Digestive.Form.Internal.Field
import           Text.Digestive.Types


--------------------------------------------------------------------------------
import           Control.Monad
import           Control.Monad.Identity
import           Data.Maybe
import           Data.Text                            (Text, pack)

--------------------------------------------------------------------------------

tests :: Test
tests = testGroup "Text.Digestive.Types.Tests"
    [
         testProperty "Mapping consistency" prop_viewcons
       , testProperty "Label consistency - map" prop_refcons
       , testProperty "Child count consistency - label" prop_pushcons
       , testProperty "Labelling consistency - monadic" prop_refmoncons
    ]

--------------------------------------------------------------------------------
-- Mapping on the view does not change the child count
prop_viewcons :: FormTree Identity String Identity Int -> Bool
prop_viewcons ft = (length . children $ ft) ==
                   (length . children $ formMapView (length) ft)


--------------------------------------------------------------------------------
-- Adding a label does not change the child count
prop_pushcons :: FormTree Identity String Identity Int -> Bool
prop_pushcons ft = lc ft == lc ("empty" .: ft)
   where lc = length . children


--------------------------------------------------------------------------------
-- Sanity check - adding a ref and popping it yields the same Result
prop_refcons :: Text -> FormTree Identity String Identity Int -> Bool
prop_refcons ref ft = isJust ref' && fromJust ref' == ref
   where ref' = getRef (ref .: ft)


--------------------------------------------------------------------------------
-- Sanity check - monadic wrap does not affect reference consistency
prop_refmoncons :: Text -> FormTree Identity String Identity Int -> Bool
prop_refmoncons ref ft = isJust ref' && fromJust ref' == ref
   where ref' = getRef (monadic . return $ (ref .: ft))


--------------------------------------------------------------------------------
-- Limited arbitrary instance for form trees
instance (Monad t, Monad m, Arbitrary a) => Arbitrary (FormTree t v m a)
   where arbitrary = sized (innerarb $ liftM Pure arbitrary)
            where innerarb g 0 = g
                  innerarb g n = innerarb g' (n-1)
                     where g' = oneof
                             [
                                 arbitrary >>= \r -> liftM (Ref r) g
                                ,liftM  (Monadic . return) g
                                ,liftM  (Map (return . Success . id)) g
                                ,liftM2  App (liftM (fmap const) g) g
                             ]

--------------------------------------------------------------------------------
-- Arbitrary SomeFields - encompasses all field types except for choice.
instance (Arbitrary v) => Arbitrary (SomeField v)
   where arbitrary =
           oneof [
                 liftM (SomeField . Singleton) (arbitrary :: Gen Int)
               , liftM (SomeField . Text) arbitrary
               , liftM (SomeField . Bool) arbitrary
               , liftM  SomeField $ elements [File]
                 ]


--------------------------------------------------------------------------------
-- Arbitrary Fields - limited to Singleton fields
instance (Arbitrary a) => Arbitrary (Field v a)
   where arbitrary = liftM Singleton (arbitrary)


--------------------------------------------------------------------------------
-- Arbitrary Text - should be factored out
instance Arbitrary Text
   where arbitrary = liftM pack arbitrary

--------------------------------------------------------------------------------
-- Show instance - should probably be moved to Field.hs
instance (Show v) => Show (SomeField v)
   where show (SomeField f) = show f