StrictCheck 0.1.0 → 0.1.1
raw patch · 6 files changed
+84/−7 lines, 6 filesdep ~QuickCheckdep ~containersdep ~template-haskellPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: QuickCheck, containers, template-haskell
API changes (from Hackage documentation)
- Test.StrictCheck: data NP k (a :: k -> *) (b :: [k]) :: forall k. () => (k -> *) -> [k] -> *
- Test.StrictCheck.Consume: instance Test.StrictCheck.Consume.Consume a => Test.StrictCheck.Consume.Consume (Data.List.NonEmpty.NonEmpty a)
- Test.StrictCheck.Examples.Map: instance (GHC.Classes.Eq v, GHC.Classes.Eq k) => GHC.Classes.Eq (Test.StrictCheck.Examples.Map.Map k v)
- Test.StrictCheck.Examples.Map: instance (GHC.Classes.Ord v, GHC.Classes.Ord k) => GHC.Classes.Ord (Test.StrictCheck.Examples.Map.Map k v)
- Test.StrictCheck.Examples.Map: instance (GHC.Show.Show v, GHC.Show.Show k) => GHC.Show.Show (Test.StrictCheck.Examples.Map.Map k v)
- Test.StrictCheck.Examples.Map: instance (Test.StrictCheck.Consume.Consume v, Test.StrictCheck.Consume.Consume k) => Test.StrictCheck.Consume.Consume (Test.StrictCheck.Examples.Map.Map k v)
- Test.StrictCheck.Examples.Map: instance (Test.StrictCheck.Shaped.Shaped v, Test.StrictCheck.Shaped.Shaped k) => Test.StrictCheck.Shaped.Shaped (Test.StrictCheck.Examples.Map.Map k v)
- Test.StrictCheck.Internal.Inputs: instance Data.Semigroup.Semigroup Test.StrictCheck.Internal.Inputs.Variant
+ Test.StrictCheck: data NP (a :: k -> *) (b :: [k]) :: forall k. () => k -> * -> [k] -> *
+ Test.StrictCheck.Consume: instance Test.StrictCheck.Consume.Consume a => Test.StrictCheck.Consume.Consume (GHC.Base.NonEmpty a)
+ Test.StrictCheck.Examples.Map: instance (GHC.Classes.Eq k, GHC.Classes.Eq v) => GHC.Classes.Eq (Test.StrictCheck.Examples.Map.Map k v)
+ Test.StrictCheck.Examples.Map: instance (GHC.Classes.Ord k, GHC.Classes.Ord v) => GHC.Classes.Ord (Test.StrictCheck.Examples.Map.Map k v)
+ Test.StrictCheck.Examples.Map: instance (GHC.Show.Show k, GHC.Show.Show v) => GHC.Show.Show (Test.StrictCheck.Examples.Map.Map k v)
+ Test.StrictCheck.Examples.Map: instance (Test.StrictCheck.Consume.Consume k, Test.StrictCheck.Consume.Consume v) => Test.StrictCheck.Consume.Consume (Test.StrictCheck.Examples.Map.Map k v)
+ Test.StrictCheck.Examples.Map: instance (Test.StrictCheck.Shaped.Shaped k, Test.StrictCheck.Shaped.Shaped v) => Test.StrictCheck.Shaped.Shaped (Test.StrictCheck.Examples.Map.Map k v)
+ Test.StrictCheck.Internal.Inputs: instance GHC.Base.Semigroup Test.StrictCheck.Internal.Inputs.Variant
- Test.StrictCheck: [:*] :: NP k a (:) k x xs
+ Test.StrictCheck: [:*] :: NP a x : xs
- Test.StrictCheck: [Nil] :: NP k a [] k
+ Test.StrictCheck: [Nil] :: NP a ([] :: [k])
- Test.StrictCheck: class (AllF k f xs, SListI k xs) => All k (f :: k -> Constraint) (xs :: [k])
+ Test.StrictCheck: class (AllF f xs, SListI xs) => All (f :: k -> Constraint) (xs :: [k])
- Test.StrictCheck: newtype I a :: * -> *
+ Test.StrictCheck: newtype I a
- Test.StrictCheck.Internal.Inputs: Variant :: (forall a. Gen a -> Gen a) -> Variant
+ Test.StrictCheck.Internal.Inputs: Variant :: forall a. Gen a -> Gen a -> Variant
Files
- LICENSE +21/−0
- README.md +10/−0
- StrictCheck.cabal +6/−6
- src/Test/StrictCheck/Observe.hs +4/−0
- tests/RefTrans.hs +37/−0
- tests/Tests.hs +6/−1
LICENSE view
@@ -0,0 +1,21 @@+MIT License++Copyright (c) 2018 Kenneth Foner, Hengchu Zhang, and Leonidas Lampropoulos++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in all+copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+SOFTWARE.
README.md view
@@ -0,0 +1,10 @@+ # StrictCheck: Keep Your Laziness In Check+ + StrictCheck is a property-based random testing framework for+ observing, specifying, and testing the strictness behaviors of Haskell+ functions. Strictness behavior is traditionally considered a non-functional+ property; StrictCheck allows it to be tested as if it were one, by reifying+ demands on data structures so they can be manipulated and examined within+ Haskell.+ + For details, see the library on Hackage: <https://hackage.haskell.org/package/StrictCheck>.
StrictCheck.cabal view
@@ -1,5 +1,5 @@ name: StrictCheck-version: 0.1.0+version: 0.1.1 synopsis: StrictCheck: Keep Your Laziness In Check description: StrictCheck is a property-based random testing framework for observing, specifying, and testing the strictness behaviors of Haskell@@ -22,11 +22,11 @@ hs-source-dirs: src default-language: Haskell2010 build-depends: base >= 4.7 && < 5,- QuickCheck >= 2.10 && < 2.11,- containers >= 0.5 && < 0.6,+ QuickCheck >= 2.10 && < 2.12,+ containers >= 0.5 && < 0.7, generics-sop >= 0.3.2 && < 0.4, bifunctors >= 5.5 && < 5.6,- template-haskell >= 2.12 && < 2.13+ template-haskell >= 2.12 && < 2.15 exposed-modules: Test.StrictCheck Test.StrictCheck.Curry, Test.StrictCheck.Consume,@@ -59,7 +59,7 @@ type: exitcode-stdio-1.0 hs-source-dirs: tests main-is: Tests.hs- other-modules: Specs+ other-modules: Specs, RefTrans default-language: Haskell2010 default-extensions: DataKinds, GADTs, BangPatterns, TypeFamilies, RankNTypes, AllowAmbiguousTypes, UndecidableInstances,@@ -71,7 +71,7 @@ MultiParamTypeClasses, GeneralizedNewtypeDeriving, ViewPatterns, PatternSynonyms- ghc-options: -Wall -fno-warn-unused-imports+ ghc-options: -Wall -fno-warn-unused-imports -O2 build-depends: base, HUnit, generics-sop,
src/Test/StrictCheck/Observe.hs view
@@ -50,6 +50,7 @@ -- This tells us that our context did indeed evaluate the result of @reverse@ -- to force only its first constructor, and that doing so required the entire -- spine of the list to be evaluated, but did not evaluate any of its elements.+{-# NOINLINE observe1 #-} observe1 :: (Shaped a, Shaped b) => (b -> ()) -> (a -> b) -> a -> (Demand b, Demand a)@@ -76,6 +77,7 @@ -- -- This is mostly useful for implementing the internals of StrictCheck; -- 'observe' is more ergonomic for exploration by end-users.+{-# NOINLINE observeNP #-} observeNP :: (All Shaped inputs, Shaped result) => (result -> ())@@ -136,3 +138,5 @@ , NP Demand (Args function) ) observe context function = curryAll (observeNP context (uncurryAll function))++-- NOTE: We don't need a NOINLINE annotation here because this wraps observeNP.
+ tests/RefTrans.hs view
@@ -0,0 +1,37 @@+{-# LANGUAGE GADTs #-}++module RefTrans where++import System.Exit+import System.IO++import Test.StrictCheck++notEqualRefTrans :: Eq a => String -> a -> a -> IO Bool+notEqualRefTrans functionName x y =+ if x /= y+ then return True+ else do+ putStrLn $ "!!! " ++ functionName ++ " referentially opaque"+ return False++checkRefTrans :: IO ()+checkRefTrans = do+ let strict = snd (observe1 id (\() -> ()) ())+ let lazy = snd (observe1 id (\_ -> ()) ())++ observe1_ok <- notEqualRefTrans "observe1" strict lazy++ let strict' = snd (observeNP id (\(I () :* Nil) -> ()) (I () :* Nil))+ let lazy' = snd (observeNP id (\(I _ :* Nil) -> ()) (I () :* Nil))++ observe_ok <- notEqualRefTrans "observe" strict' lazy'++ let strict'' = snd (observe id (\() -> ()) ())+ let lazy'' = snd (observe id (\_ -> ()) ())++ observeNP_ok <- notEqualRefTrans "observeNP" strict'' lazy''++ if and [observe1_ok, observe_ok, observeNP_ok]+ then return ()+ else putStrLn "\n" >> hFlush stdout >> exitFailure
tests/Tests.hs view
@@ -1,6 +1,11 @@ module Main where import Specs+import RefTrans main :: IO ()-main = runSpecs+main = do+ -- specification unit tests+ runSpecs+ -- regression test for issue #2 (CSE breaks referential transparency)+ checkRefTrans