Skip to content

Commit

Permalink
[#252] Switch testing from 'tasty-*' libraries to 'hspec-*' libraries (
Browse files Browse the repository at this point in the history
…#257)

* [#252] Switch testing from 'tasty-*' libraries to 'hspec-*' libraries

Resolves #252

* Fix 8.2 and Stack CI builds
  • Loading branch information
vrom911 authored May 6, 2020
1 parent 1d4c2b7 commit 6864054
Show file tree
Hide file tree
Showing 25 changed files with 483 additions and 353 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,5 @@ TAGS

# other
.DS_Store

.golden/
29 changes: 16 additions & 13 deletions src/Toml/Parser/Item.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ module Toml.Parser.Item
, setTableName

, tomlP
, keyValP
) where

import Control.Applicative (liftA2, many)
Expand Down Expand Up @@ -90,19 +91,21 @@ tomlItemP = asum
, TableArrayName <$> tableArrayNameP <?> "array of tables name"
, keyValP
]
where
-- parser for "key = val" pairs; can be one of three forms:
-- 1. key = { ... }
-- 2. key = [ {...}, {...}, ... ]
-- 3. key = ...
keyValP :: Parser TomlItem
keyValP = do
key <- keyP <* text "="
asum
[ InlineTable key <$> inlineTableP <?> "inline table"
, InlineTableArray key <$> try inlineTableArrayP <?> "inline array of tables"
, KeyVal key <$> anyValueP <?> "key-value pair"
]

{- | parser for @"key = val"@ pairs; can be one of three forms:
1. key = { ... }
2. key = [ {...}, {...}, ... ]
3. key = ...
-}
keyValP :: Parser TomlItem
keyValP = do
key <- keyP <* text "="
asum
[ InlineTable key <$> inlineTableP <?> "inline table"
, InlineTableArray key <$> try inlineTableArrayP <?> "inline array of tables"
, KeyVal key <$> anyValueP <?> "key-value pair"
]

-- | Parser for the full content of the .toml file.
tomlP :: Parser [TomlItem]
Expand Down
5 changes: 4 additions & 1 deletion stack.yaml
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
resolver: nightly-2019-10-10
resolver: lts-15.11

extra-deps:
- hspec-hedgehog-0.0.1.2
37 changes: 36 additions & 1 deletion test/Spec.hs
Original file line number Diff line number Diff line change
@@ -1 +1,36 @@
{-# OPTIONS_GHC -F -pgmF tasty-discover #-}
module Main (main) where

import Test.Hspec (hspec)
import Test.Hspec.Hedgehog (modifyMaxDiscardRatio)

import Test.Toml.BiCode.Property (biCodePropertySpec)
import Test.Toml.BiMap.Property (biMapPropertySpec)
import Test.Toml.Parsing.Examples (parsingExamplesSpec)
import Test.Toml.Parsing.Property (parsingPropertySpec)
import Test.Toml.Parsing.Unit (parsingUnitSpec)
import Test.Toml.PrefixTree.Property (prefixTreePropertySpec)
import Test.Toml.PrefixTree.Unit (prefixTreeUnitSpec)
import Test.Toml.Printer.Golden (prettyPrinterGoldenSpec)
import Test.Toml.TOML.Property (tomlLawsSpec)


{- Default QuickCheck discard Ratio is 10 while @hedgehog@s is 100.
So we need to modify it manually in here.
See issue: <https://github.com/parsonsmatt/hspec-hedgehog/issues/9>
-}
main :: IO ()
main = hspec $ modifyMaxDiscardRatio (+ 90) $ do
biCodePropertySpec
biMapPropertySpec
-- parsing
parsingExamplesSpec
parsingPropertySpec
parsingUnitSpec
-- prefix tree
prefixTreePropertySpec
prefixTreeUnitSpec
-- Printer
prettyPrinterGoldenSpec
-- toml
tomlLawsSpec
41 changes: 27 additions & 14 deletions test/Test/Toml/BiCode/Property.hs
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
{-# LANGUAGE FlexibleInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}

module Test.Toml.BiCode.Property where
{-# LANGUAGE FlexibleInstances #-}

module Test.Toml.BiCode.Property
( biCodePropertySpec
) where

import Control.Applicative (liftA2, (<|>))
import Control.Category ((>>>))
import Data.ByteString (ByteString)
import Data.Char (chr, ord)
import Data.HashSet (HashSet)
import Data.IntSet (IntSet)
import Data.List.NonEmpty (NonEmpty)
Expand All @@ -13,39 +18,47 @@ import Data.Monoid (All (..), Any (..), First (..), Last (..), Product (..), Sum
import Data.Semigroup ((<>))
import Data.Set (Set)
import Data.Text (Text)
import Data.Char (chr, ord)
import Data.Time (Day, LocalTime, TimeOfDay, ZonedTime, zonedTimeToUTC)
import GHC.Exts (fromList)
import GHC.Generics (Generic)
import Hedgehog (Gen, forAll, tripping, (===))
import Numeric.Natural (Natural)
import Test.Hspec (Arg, Expectation, Spec, SpecWith, describe, it)
import Test.Hspec.Hedgehog (hedgehog)

import Toml (TomlBiMap, TomlCodec, (.=), genericCodec, HasCodec, hasCodec, HasItemCodec, BiMap, AnyValue, iso, _Int, Key)
import Toml (AnyValue, BiMap, HasCodec, HasItemCodec, Key, TomlBiMap, TomlCodec, genericCodec,
hasCodec, iso, (.=), _Int)
import Toml.Bi.Code (decode, encode)

import Test.Toml.Gen (PropertyTest, genBool, genByteString, genDay, genDouble, genFloat, genHashSet,
genHours, genInt, genIntSet, genInteger, genLByteString, genLocal, genNatural,
genNonEmpty, genString, genText, genWord, genZoned, prop)
import Test.Toml.Gen (genBool, genByteString, genDay, genDouble, genFloat, genHashSet, genHours,
genInt, genIntSet, genInteger, genLByteString, genLocal, genNatural,
genNonEmpty, genString, genText, genWord, genZoned)

import qualified Data.ByteString.Lazy as L
import qualified Hedgehog.Gen as Gen
import qualified Hedgehog.Range as Range
import qualified Toml


test_encodeDecodeProp :: PropertyTest
test_encodeDecodeProp = prop "decode . encode == id" $ do
biCodePropertySpec :: Spec
biCodePropertySpec = describe "BiCode Property tests" $ do
encodeDecodeSpec
genericCodecRoundtripSpec
genericCustomCodecEncodeDecodeSpec

encodeDecodeSpec :: SpecWith (Arg Expectation)
encodeDecodeSpec = it "decode . encode ≡ id" $ hedgehog $ do
bigType <- forAll genBigType
tripping bigType (encode bigTypeCodec) (decode bigTypeCodec)

test_genericCodecRoundtripProp :: PropertyTest
test_genericCodecRoundtripProp = prop "genericCodecDecode . genericCodecEncode == id" $ do
genericCodecRoundtripSpec :: SpecWith (Arg Expectation)
genericCodecRoundtripSpec = it "genericCodecDecode . genericCodecEncode id" $ hedgehog $ do
bigType <- forAll genBigType
tripping bigType (encode bigTypeGenericCodec) (decode bigTypeGenericCodec)

test_genericCustomCodecEncodeDecodeProp :: PropertyTest
test_genericCustomCodecEncodeDecodeProp =
prop "(decode . encode) genericCodec == (decode . encode) customCodec" $ do
genericCustomCodecEncodeDecodeSpec :: SpecWith (Arg Expectation)
genericCustomCodecEncodeDecodeSpec =
it "(decode . encode) genericCodec (decode . encode) customCodec" $ hedgehog $ do
bigType <- forAll genBigType
decode bigTypeGenericCodec (encode bigTypeGenericCodec bigType) === decode bigTypeCodec (encode bigTypeCodec bigType)

Expand Down
81 changes: 41 additions & 40 deletions test/Test/Toml/BiMap/Property.hs
Original file line number Diff line number Diff line change
@@ -1,65 +1,66 @@
{-# OPTIONS_GHC -fno-warn-orphans #-}

module Test.Toml.BiMap.Property where
module Test.Toml.BiMap.Property
( biMapPropertySpec
) where

import Data.Time (ZonedTime (..))
import Hedgehog (Gen, PropertyT, assert, forAll, tripping, (===))

import Data.Time (ZonedTime (..))
import Test.Tasty (testGroup)
import Test.Toml.Gen (PropertyTest, prop)
import Test.Hspec (Spec, describe, it)
import Test.Hspec.Hedgehog (hedgehog)
import Toml.Bi.Map (BiMap (..), TomlBiMap)

import qualified Hedgehog.Gen as Gen
import qualified Test.Toml.Gen as G
import qualified Toml.Bi.Map as B


biMapPropertySpec :: Spec
biMapPropertySpec = describe "BiMap Rountrip Property tests" $ do
it "Bool" (testBiMap B._Bool G.genBool)
it "Integer" (testBiMap B._Integer G.genInteger)
it "Natural" (testBiMap B._Natural G.genNatural)
it "Int" (testBiMap B._Int G.genInt)
it "Word" (testBiMap B._Word G.genWord)
it "Word8" (testBiMap B._Word8 G.genWord8)
it "Double" testDouble
it "Float" (testBiMap B._Float G.genFloat)
it "Text" (testBiMap B._Text G.genText)
it "LazyText" (testBiMap B._LText G.genLText)
it "String" (testBiMap B._String G.genString)
it "Read (Integer)" (testBiMap B._Read G.genInteger)
it "ByteString" (testBiMap B._ByteString G.genByteString)
it "Lazy ByteString" (testBiMap B._LByteString G.genLByteString)
it "ByteStringArray" (testBiMap B._ByteStringArray G.genByteString)
it "Lazy ByteStringArray" (testBiMap B._LByteStringArray G.genLByteString)
it "ZonedTime" (testBiMap B._ZonedTime G.genZoned)
it "LocalTime" (testBiMap B._LocalTime G.genLocal)
it "TimeOfDay" (testBiMap B._TimeOfDay G.genHours)
it "Day" (testBiMap B._Day G.genDay)
it "IntSet" (testBiMap B._IntSet G.genIntSet)
it "Array (Day)" (testBiMap (B._Array B._Day) (G.genList G.genDay))
it "Set (Day)" (testBiMap (B._Set B._Day) (Gen.set G.range100 G.genDay))
it "NonEmpty (Day)" (testBiMap (B._NonEmpty B._Day) (G.genNonEmpty G.genDay))
it "HashSet (Integer)" (testBiMap (B._HashSet B._Integer) (G.genHashSet G.genInteger))

testBiMap
:: (Monad m, Show a, Show b, Eq a)
:: (Show a, Show b, Eq a)
=> TomlBiMap a b
-> Gen a
-> PropertyT m ()
testBiMap bimap gen = do
-> PropertyT IO ()
testBiMap bimap gen = hedgehog $ do
x <- forAll gen
tripping x (forward bimap) (backward bimap =<<)

-- Double needs a special test because NaN /= NaN
testDouble :: PropertyT IO ()
testDouble = do
testDouble = hedgehog $ do
x <- forAll G.genDouble
if isNaN x
then assert $
fmap isNaN (forward B._Double x >>= backward B._Double) == Right True
else (forward B._Double x >>= backward B._Double) === Right x

test_BiMaps :: PropertyTest
test_BiMaps = pure $ testGroup "BiMap roundtrip tests" $ concat
[ prop "Bool" (testBiMap B._Bool G.genBool)
, prop "Integer" (testBiMap B._Integer G.genInteger)
, prop "Natural" (testBiMap B._Natural G.genNatural)
, prop "Int" (testBiMap B._Int G.genInt)
, prop "Word" (testBiMap B._Word G.genWord)
, prop "Word8" (testBiMap B._Word8 G.genWord8)
, prop "Double" testDouble
, prop "Float" (testBiMap B._Float G.genFloat)
, prop "Text" (testBiMap B._Text G.genText)
, prop "LazyText" (testBiMap B._LText G.genLText)
, prop "String" (testBiMap B._String G.genString)
, prop "Read (Integer)" (testBiMap B._Read G.genInteger)
, prop "ByteString" (testBiMap B._ByteString G.genByteString)
, prop "Lazy ByteString" (testBiMap B._LByteString G.genLByteString)
, prop "ByteStringArray" (testBiMap B._ByteStringArray G.genByteString)
, prop "Lazy ByteStringArray" (testBiMap B._LByteStringArray G.genLByteString)
, prop "ZonedTime" (testBiMap B._ZonedTime G.genZoned)
, prop "LocalTime" (testBiMap B._LocalTime G.genLocal)
, prop "TimeOfDay" (testBiMap B._TimeOfDay G.genHours)
, prop "Day" (testBiMap B._Day G.genDay)
, prop "IntSet" (testBiMap B._IntSet G.genIntSet)
, prop "Array (Day)" (testBiMap (B._Array B._Day) (G.genList G.genDay))
, prop "Set (Day)" (testBiMap (B._Set B._Day) (Gen.set G.range100 G.genDay))
, prop "NonEmpty (Day)" (testBiMap (B._NonEmpty B._Day) (G.genNonEmpty G.genDay))
, prop "HashSet (Integer)" (testBiMap (B._HashSet B._Integer) (G.genHashSet G.genInteger))
]
then assert $
fmap isNaN (forward B._Double x >>= backward B._Double) == Right True
else (forward B._Double x >>= backward B._Double) === Right x

-- Orphan instances

Expand Down
Loading

0 comments on commit 6864054

Please sign in to comment.