{-
   Copyright 2007 Dino Morelli

   This file is part of storylen

   storylen is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   storylen is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with storylen; if not, write to the Free Software
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  
   02110-1301  USA
-}

module TestDescNovel
   ( testDescNovel
   )
   where

import StoryLen.Describe ( describeStory )
import Test.QuickCheck


expectedOutput :: String
goodMin, goodMax, maxAll :: Int
goodEdges, badEdges :: [Int]
goodRange, badRangeLow, badRangeHigh :: (Int, Int)

-- These things are specific to this set of tests
expectedOutput = "novel"

goodMin = 60001
goodMax = 199999
-- end of specific values, everything else is const or calculated

maxAll = 201500

goodEdges = [goodMin, goodMax]
goodRange = (goodMin + 1, goodMax - 1)

badEdges = [goodMin - 1, goodMax + 1]
badRangeLow = (0, goodMin - 2)
badRangeHigh = (goodMax + 2, maxAll)

outside :: Eq a => [a] -> a -> Bool
outside xs = not . flip elem xs


newtype GoodValue = GoodValue { fromGood :: Int }
   deriving Show

instance Arbitrary GoodValue where
   arbitrary = do
      value <- frequency
         [ (16, elements goodEdges)
         , (84, choose goodRange)
         ]
      return $ GoodValue value

   coarbitrary = undefined


newtype BadValue = BadValue { fromBad :: Int }
   deriving Show

instance Arbitrary BadValue where
   arbitrary = do
      value <- frequency
         [ (16, elements badEdges)
         , (42, choose badRangeLow)
         , (42, choose badRangeHigh)
         ]
      return $ BadValue value

   coarbitrary = undefined


prop_DescNovelPos wc =
   outside goodEdges intWc `trivial`
      (describeStory intWc == expectedOutput)
   where intWc = fromGood wc


prop_DescNovelNeg wc =
   outside badEdges intWc `trivial`
      (describeStory intWc /= expectedOutput)
   where intWc = fromBad wc


testDescNovel :: IO ()
testDescNovel = do
   putStr "TestDescNovel (positive): "
   quickCheck prop_DescNovelPos

   putStr "TestDescNovel (negative): "
   quickCheck prop_DescNovelNeg