grid-7.6.9: test/Math/Geometry/Grid/SquareQC.hs
------------------------------------------------------------------------
-- |
-- Module : Math.Geometry.Grid.SquareQC
-- Copyright : (c) Amy de Buitléir 2012-2014
-- License : BSD-style
-- Maintainer : amy@nualeargais.ie
-- Stability : experimental
-- Portability : portable
--
-- QuickCheck tests.
--
------------------------------------------------------------------------
{-# LANGUAGE FlexibleContexts, ExistentialQuantification,
TypeFamilies #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Math.Geometry.Grid.SquareQC
(
test
) where
import Math.Geometry.Grid.SquareInternal
import Math.Geometry.GridInternal
import Math.Geometry.GridQC
import Prelude hiding (null)
import Test.Framework as TF (Test, testGroup)
import Test.QuickCheck
(Gen, Arbitrary, arbitrary, sized, choose, elements, Property, vectorOf)
instance Arbitrary SquareDirection where
arbitrary =
elements [North, South, East, West]
--
-- Unbounded grids with square tiles
--
data UnboundedSquareGridTD =
UnboundedSquareGridTD [(Int,Int)] ((Int,Int),(Int,Int)) SquareDirection
deriving Show
instance TestData UnboundedSquareGridTD where
type BaseGrid UnboundedSquareGridTD = UnboundedSquareGrid
grid _ = UnboundedSquareGrid
points (UnboundedSquareGridTD ps _ _) = ps
twoClosePoints (UnboundedSquareGridTD _ qs _) = qs
neighbourCountBounds _ = (4, 4)
direction (UnboundedSquareGridTD _ _ d) = d
sizedUnboundedSquareGridTD :: Int -> Gen UnboundedSquareGridTD
sizedUnboundedSquareGridTD n = do
k <- choose (0,n)
ps <- vectorOf (k+2) arbitrary :: Gen [(Int,Int)]
qs <- chooseClosePointsUnbounded
d <- arbitrary
return $ UnboundedSquareGridTD ps qs d
instance Arbitrary UnboundedSquareGridTD where
arbitrary = sized sizedUnboundedSquareGridTD
unboundedSquareGridProperties :: [(String, UnboundedSquareGridTD -> Property)]
unboundedSquareGridProperties = gridProperties "UnboundedSquareGrid"
unboundedSquareGridTests :: [Test]
unboundedSquareGridTests = makeTests unboundedSquareGridProperties
--
-- Rectangular grids with square tiles
--
data RectSquareGridTD =
RectSquareGridTD RectSquareGrid [(Int,Int)] ((Int,Int),(Int,Int)) SquareDirection
deriving Show
instance TestData RectSquareGridTD where
type BaseGrid RectSquareGridTD = RectSquareGrid
grid (RectSquareGridTD g _ _ _) = g
points (RectSquareGridTD _ ps _ _) = ps
twoClosePoints (RectSquareGridTD _ _ qs _) = qs
neighbourCountBounds _ = (0, 4)
direction (RectSquareGridTD _ _ _ d) = d
instance TestDataF RectSquareGridTD where
maxDistance (RectSquareGridTD g _ _ _) = r + c - 2
where (r, c) = size g
expectedTileCount (RectSquareGridTD g _ _ _) = r*c
where (r,c) = size g
instance TestDataB RectSquareGridTD where
expectedBoundaryCount (RectSquareGridTD g _ _ _) =
(cartesianBoundaryCount . size) g
-- We want the number of tiles in a test grid to be O(n)
sizedRectSquareGridTD :: Int -> Gen RectSquareGridTD
sizedRectSquareGridTD n = do
r <- choose (0,n)
let c = n `div` (r+1)
let g = rectSquareGrid r c
ps <- chooseIndices g n
qs <- chooseClosePoints g
d <- arbitrary
return $ RectSquareGridTD g ps qs d
instance Arbitrary RectSquareGridTD where
arbitrary = sized sizedRectSquareGridTD
rectSquareGridProperties :: [(String, RectSquareGridTD -> Property)]
rectSquareGridProperties = gridProperties "RectSquareGrid"
++ finiteGridProperties "RectSquareGrid"
++ boundedGridProperties "RectSquareGrid"
++ boundedGridProperties2 "RectSquareGrid"
rectSquareGridTests :: [Test]
rectSquareGridTests = makeTests rectSquareGridProperties
--
-- Toroidal grids with square tiles
--
data TorSquareGridTD =
TorSquareGridTD TorSquareGrid [(Int,Int)] ((Int,Int),(Int,Int)) SquareDirection
deriving Show
instance TestData TorSquareGridTD where
type BaseGrid TorSquareGridTD = TorSquareGrid
grid (TorSquareGridTD g _ _ _) = g
points (TorSquareGridTD _ ps _ _) = ps
twoClosePoints (TorSquareGridTD _ _ qs _) = qs
neighbourCountBounds _ = (0, 4)
direction (TorSquareGridTD _ _ _ d) = d
instance TestDataF TorSquareGridTD where
maxDistance (TorSquareGridTD g _ _ _) = (r+c) `div` 2
where (r, c) = size g
expectedTileCount (TorSquareGridTD g _ _ _) = r*c
where (r,c) = size g
-- We want the number of tiles in a test grid to be O(n)
sizedTorSquareGridTD :: Int -> Gen TorSquareGridTD
sizedTorSquareGridTD n = do
r <- choose (0,n)
let c = n `div` (r+1)
let g = torSquareGrid r c
ps <- chooseIndices g n
qs <- chooseClosePoints g
d <- arbitrary
return $ TorSquareGridTD g ps qs d
instance Arbitrary TorSquareGridTD where
arbitrary = sized sizedTorSquareGridTD
torSquareGridProperties :: [(String, TorSquareGridTD -> Property)]
torSquareGridProperties = gridProperties "TorSquareGrid"
++ finiteGridProperties "TorSquareGrid"
torSquareGridTests :: [Test]
torSquareGridTests = makeTests torSquareGridProperties
--TODO replace these
--TODO replace these
--TODO replace these
--prop_UnboundedSquareGrid_num_min_paths_correct ::
-- UnboundedSquareGrid -> Int -> Int -> Property
--prop_UnboundedSquareGrid_num_min_paths_correct g i j = nonNull g ==>
-- minPathCount g a b == M.choose (deltaX+deltaY) deltaX
-- where a = g `pointAt` i
-- b = g `pointAt` j
-- deltaX = abs $ fst b - fst a
-- deltaY = abs $ snd b - snd a
---- If the ordering produced by rectSquareGrid is ever changed, this
---- property may need to be changed too. It relies on the first and last
---- elements being at opposite corners.
--prop_RectSquareGrid_distance_corner_to_corner :: RectSquareGrid -> Property
--prop_RectSquareGrid_distance_corner_to_corner g = r > 0 && c > 0 ==>
-- distance g a b == r + c - 2
-- where (r, c) = size g
-- ps = indices g
-- a = head ps
-- b = last ps
--prop_RectSquareGrid_num_min_paths_correct ::
-- RectSquareGrid -> Int -> Int -> Property
--prop_RectSquareGrid_num_min_paths_correct g i j = nonNull g ==>
-- minPathCount g a b == M.choose (deltaX+deltaY) deltaX
-- where a = g `pointAt` i
-- b = g `pointAt` j
-- deltaX = abs $ fst b - fst a
-- deltaY = abs $ snd b - snd a
---- If the ordering produced by torSquareGrid is ever changed, this property
---- may need to be changed too.
--prop_TorSquareGrid_distance_corner_to_corner :: TorSquareGrid -> Property
--prop_TorSquareGrid_distance_corner_to_corner g = r > 0 && c > 0 ==>
-- distance g a b == f
-- where (r, c) = size g
-- ps = indices g
-- a = head ps
-- b = last ps
-- f | r == 1 && c == 1 = 0 -- single-tile torus
-- | r == 1 || c == 1 = 1 -- a and b are the same
-- | otherwise = 2
test :: Test
test = testGroup "Math.Geometry.Grid.SquareQC"
(unboundedSquareGridTests ++ rectSquareGridTests ++ torSquareGridTests)