packages feed

tasty-laws (empty) → 0.2

raw patch · 11 files changed

+368/−0 lines, 11 filesdep +basedep +smallcheckdep +smallcheck-lawssetup-changed

Dependencies added: base, smallcheck, smallcheck-laws, smallcheck-series, tagged, tasty, tasty-laws, tasty-smallcheck, transformers

Files

+ CHANGELOG.md view
@@ -0,0 +1,16 @@+# Change Log+All notable changes to this project will be documented in this file. This file+follows the formatting recommendations from [Keep a+CHANGELOG](http://keepachangelog.com/). This project adheres to [Semantic+Versioning](http://semver.org/).++## [0.2] - 2015-09-04+### Removed+- `smallcheck` specific modules from+  [`smallcheck-laws-0.1`](https://hackage.haskell.org/package/smallcheck-laws-0.1).+  This package now contains `Tasty` specific modules.++### Changed+- Simplify module hierarchy: `Test.Tasty.SmallCheck.Laws` -> `Test.Tasty.Laws`++[0.2]: https://github.com/jdnavarro/tasty-laws/compare/bf1caa5...v0.2
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2015, J. Daniel Navarro++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of J. Daniel Navarro nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,22 @@+# Tasty Laws++[![Hackage Version](https://img.shields.io/hackage/v/tasty-laws.svg)](https://hackage.haskell.org/package/tasty-laws)+[![Build Status](https://img.shields.io/travis/jdnavarro/tasty-laws.svg)](https://travis-ci.org/jdnavarro/tasty-laws)++Preassembled `tasty` runners for property testing the following laws:++- Monoids+- Functors+- Applicatives+- Monads++It uses [`smallcheck-laws`](https://github.com/jdnavarro/smallcheck-laws) under+the hood. If you don't find any runners that suite you, you can use this+package as a reference to implement your own `smallcheck-laws` test runners.++## Contact++Contributions and bug reports are welcome!++Please feel free to contact jdnavarro on the #haskell IRC channel on+irc.freenode.net.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ Test/Tasty/Laws/Applicative.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ScopedTypeVariables #-}+module Test.Tasty.Laws.Applicative where++#if !MIN_VERSION_base(4,8,0)+import Control.Applicative (Applicative)+#endif+import Data.Functor.Identity (Identity)+import Data.Proxy (Proxy(..))+import Test.Tasty (TestTree, testGroup)+import Test.Tasty.SmallCheck (testProperty)+import Test.SmallCheck.Series (Series, Serial(series))++import qualified Test.SmallCheck.Laws.Applicative as Applicative+import Test.Tasty.Laws.Functor++-- | @tasty@ 'TestTree' for 'Applicative' laws. You need to provide the type+--   wrapped in a `Proxy` and make sure 'a' is an instance of 'Serial'.+testApplicative+  :: forall f a .+     ( Applicative f+     , Show a, Eq a+     , Show (f a), Eq (f a), (Eq (f (f a)))+     , Show (f (a -> a))+     , Serial IO a+     , Serial IO (f a)+     , Serial IO (a -> a)+     , Serial IO (f (a -> a))+     , Serial Identity a, Serial Identity (f a)+     )+  => Proxy (f a) -> TestTree+testApplicative proxy = testGroup "Applicative"+  [ testFunctor proxy+  , testProperty "pure id <*> v ≡ v"+  $ Applicative.identity (series :: Series IO (f a))+  , testProperty "(.) <$> u <*> v <*> w ≡  u <*> (v <*> w)"+  $ Applicative.composition+      (series :: Series IO (f (a -> a)))+      (series :: Series IO (f a))+      (series :: Series IO (f (a -> a)))+  , testProperty "pure f <*> pure x ≡ pure (f x)" $ Applicative.homomorphism+      (Proxy :: Proxy f)+      (series :: Series IO a)+      (series :: Series IO (a -> a))+  , testProperty "u <*> pure y ≡ pure ($ y) <*> u" $ Applicative.interchange+      (series :: Series IO a)+      (series :: Series IO (f (a -> a)))+  ]
+ Test/Tasty/Laws/Functor.hs view
@@ -0,0 +1,29 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ScopedTypeVariables #-}+module Test.Tasty.Laws.Functor where++import Data.Proxy (Proxy)+import Data.Functor.Identity (Identity)+import Test.Tasty (TestTree, testGroup)+import Test.Tasty.SmallCheck (testProperty)+import Test.SmallCheck.Series (Serial(series), Series)++import qualified Test.SmallCheck.Laws.Functor as Functor++-- | @tasty@ 'TestTree' for 'Functor' laws. You need to provide the type+--   wrapped in a `Proxy` and make sure 'a' is an instance of 'Serial'.+testFunctor+  :: forall f a .+     ( Eq (f a), Eq (f (f a)), Functor f, Show a, Show (f a)+     , Serial IO (f a)+     , Serial IO (a -> a)+     , Serial Identity a, Serial Identity (f a)+     )+  => Proxy (f a) -> TestTree+testFunctor _ = testGroup "Functor laws"+  [ testProperty "fmap id ≡ id" $ Functor.identity (series :: Series IO (f a))+  , testProperty "fmap (f . g) ≡ fmap f . fmap g" $ Functor.composition+      (series :: Series IO (f a))+      (series :: Series IO (a -> a))+      (series :: Series IO (a -> a))+  ]
+ Test/Tasty/Laws/Monad.hs view
@@ -0,0 +1,36 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ScopedTypeVariables #-}+module Test.Tasty.Laws.Monad where++#if !MIN_VERSION_base(4,8,0)+import Control.Applicative (Applicative)+#endif+import Data.Functor.Identity (Identity)+import Data.Proxy (Proxy(..))+import Test.SmallCheck.Series (Series, Serial(series))+import Test.Tasty (TestTree, testGroup)+import Test.Tasty.SmallCheck (testProperty)+import qualified Test.SmallCheck.Laws.Monad as Monad++import Test.Tasty.Laws.Applicative++-- | @tasty@ 'TestTree' for 'Monad' laws. You need to provide the type+--   wrapped in a `Proxy` and make sure 'a' is an instance of 'Serial'.+testMonad+  :: forall f a .+     ( Applicative f, Monad f+     , Show a, Show (f a), Show (f (a -> a))+     , Eq a, Eq (f a), Eq (f (f a))+     , Serial IO a, Serial IO (a -> a)+     , Serial IO (f a) ,Serial IO (f (a -> a)), Serial IO (a -> f a)+     , Serial Identity a, Serial Identity (f a)+     )+  => Proxy (f a) -> TestTree+testMonad proxy = testGroup "Monad laws"+  [ testApplicative proxy+  , testProperty "(m >>= f) >>= g ≡ m (f >=> g)"+  $ Monad.associativity (series :: Series IO (f a))+                        (series :: Series IO (a -> f a))+                        (series :: Series IO (a -> f a))+  ]
+ Test/Tasty/Laws/Monoid.hs view
@@ -0,0 +1,26 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ScopedTypeVariables #-}+module Test.Tasty.Laws.Monoid where++#if !MIN_VERSION_base(4,8,0)+import Data.Monoid (Monoid)+#endif+import Data.Proxy (Proxy)+import Test.SmallCheck.Series (Series, Serial(series))+import Test.Tasty (TestTree, testGroup)+import Test.Tasty.SmallCheck (testProperty)++import qualified Test.SmallCheck.Laws.Monoid as Monoid++-- | @tasty@ 'TestTree' for 'Applicative' laws. You need to provide the type+--   wrapped in a `Proxy` and make sure 'a' is an instance of 'Serial'.+testMonoid :: forall a . (Show a, Eq a, Monoid a, Serial IO a) => Proxy a -> TestTree+testMonoid _ = testGroup "Monoid laws"+  [ testProperty "mempty <> x ≡ x" $ Monoid.leftIdentity (series :: Series IO a)+  , testProperty "x <> mempty ≡ x" $ Monoid.rightIdentity (series :: Series IO a)+  , testProperty "x <> (y <> z) ≡ (x <> y) <> z"+  $ Monoid.associativity (series :: Series IO a) series series+  , testProperty "mconcat ≡ foldr mappend mempty"+  $ Monoid.mconcat (series :: Series IO a)+  ]
+ stack.yaml view
@@ -0,0 +1,7 @@+flags: {}+packages:+- '.'+extra-deps:+- smallcheck-laws-0.2+- smallcheck-series-0.5.1+resolver: lts-3.4
+ tasty-laws.cabal view
@@ -0,0 +1,52 @@+name:                tasty-laws+version:             0.2+synopsis:            Test common laws+description:+  Preassembled 'tasty' runners for property testing 'Monoid', 'Functor',+  'Applicative' and 'Monad' laws.+license:             BSD3+license-file:        LICENSE+author:              Danny Navarro+maintainer:          j@dannynavarro.net+category:            Testing+build-type:          Simple+cabal-version:       >=1.10+extra-source-files:  README.md CHANGELOG.md stack.yaml++source-repository head+  type: git+  location: git://github.com/jdnavarro/tasty-laws.git++library+  ghc-options:         -Wall+  default-language:    Haskell2010+  exposed-modules:     Test.Tasty.Laws.Applicative,+                       Test.Tasty.Laws.Functor,+                       Test.Tasty.Laws.Monad,+                       Test.Tasty.Laws.Monoid+  build-depends:       base >=4.6 && <4.9,+                       smallcheck >=1.1.1,+                       smallcheck-laws >=0.1,+                       smallcheck-series >=0.3,+                       tasty >=0.10,+                       tasty-smallcheck >=0.8.0.1+  if impl(ghc < 7.10)+     build-depends: transformers >=0.3.0.0++  if impl(ghc < 7.8)+     build-depends: tagged >=0.7.2++test-suite tasty+  default-language:    Haskell2010+  type:                exitcode-stdio-1.0+  hs-source-dirs:      tests+  main-is:             tasty.hs+  ghc-options:         -Wall -threaded+  build-depends:       base >=4.6 && <4.9,+                       smallcheck >=1.1.1,+                       tasty >=0.10,+                       smallcheck-laws >=0.1,+                       tasty-laws++  if impl(ghc < 7.8)+     build-depends: tagged >=0.7.2
+ tests/tasty.hs view
@@ -0,0 +1,99 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleInstances #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}+module Main where++#if !MIN_VERSION_base(4,8,0)+import Control.Applicative ((<$>))+#endif+import Data.Monoid (Sum(..), Product(..))+import Data.Proxy (Proxy(..))++import Test.SmallCheck.Series (Serial(series))+import Test.Tasty (TestTree, defaultMain, testGroup)++import Test.Tasty.Laws.Applicative+import Test.Tasty.Laws.Functor+import Test.Tasty.Laws.Monad+import Test.Tasty.Laws.Monoid++main :: IO ()+main = defaultMain $ testGroup "Laws"+     [ monoidTests+     , functorTests+     , applicativeTests+     , monadTests+     ]++monoidTests :: TestTree+monoidTests = testGroup "Monoid"+  [ testGroup "Sum"+    [ testGroup "Int"+      [ testMonoid (Proxy :: Proxy (Sum Int)) ]+    , testGroup "Integer"+      [ testMonoid (Proxy :: Proxy (Sum Integer)) ]+    , testGroup "Float"+      [ testMonoid (Proxy :: Proxy (Sum Float)) ]+    ]+  , testGroup "Product"+     [ testGroup "Int"+      [ testMonoid (Proxy :: Proxy (Product Int)) ]+    , testGroup "Integer"+      [ testMonoid (Proxy :: Proxy (Product Integer)) ]+    , testGroup "Float"+      [ testMonoid (Proxy :: Proxy (Product Float)) ]+    ]+  ]++functorTests :: TestTree+functorTests = testGroup "Functor"+  [ testGroup "Maybe"+    [ testGroup "Int"+      [ testFunctor (Proxy :: Proxy (Maybe Int)) ]+    , testGroup "Char"+      [ testFunctor (Proxy :: Proxy (Maybe Char)) ]+    ]+  , testGroup "[]"+    [ testGroup "Bool"+      [ testFunctor (Proxy :: Proxy [Bool]) ]+    , testGroup "Int"+      [ testFunctor (Proxy :: Proxy [Int]) ]+    ]+  ]++applicativeTests :: TestTree+applicativeTests = testGroup "Applicative"+  [ testGroup "Maybe"+    [ testGroup "Int"+      [ testApplicative (Proxy :: Proxy (Maybe Int)) ]+    , testGroup "Float"+      [ testApplicative (Proxy :: Proxy (Maybe Float)) ]+    ]+  , testGroup "[]"+    [ testGroup "Bool"+      [ testApplicative (Proxy :: Proxy [Bool]) ]+    , testGroup "Char"+      [ testApplicative (Proxy :: Proxy [Char]) ]+    ]+  ]++monadTests :: TestTree+monadTests = testGroup "Monad"+  [ testGroup "Maybe"+    [ testGroup "()"+      [ testMonad (Proxy :: Proxy (Maybe ())) ]+    , testGroup "Int"+      [ testMonad (Proxy :: Proxy (Maybe Int)) ]+    ]+  , testGroup "[]"+    [ testGroup "()"+      [ testMonad (Proxy :: Proxy [()]) ]+    ]+  ]++instance (Monad m, Serial m a) => Serial m (Sum a) where+    series = Sum <$> series++instance (Monad m, Serial m a) => Serial m (Product a) where+    series = Product <$> series