packages feed

yampa-test 0.13.5 → 0.13.6

raw patch · 5 files changed

+282/−17 lines, 5 filesdep ~YampaPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: Yampa

API changes (from Hackage documentation)

Files

CHANGELOG view
@@ -1,3 +1,9 @@+2022-08-07 Ivan Perez <ivan.perez@haskell.sexy>+        * yampa-test.cabal: Version bump (0.13.6) (#232).+        * tests/: Complete unit tests for FRP.Yampa.Basic (#219), complete unit+          tests for FRP.Yampa.Conditional (#225), complete unit tests for+          FRP.Yampa.Delays (#226).+ 2022-06-07 Ivan Perez <ivan.perez@haskell.sexy>         * yampa-test.cabal: Version bump (0.13.5) (#220), fix broken link in           description (#204), enable all warnings (#206), rename flag (#208),
tests/Test/FRP/Yampa/Basic.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} -- | -- Description : Test cases for basic signal functions -- Copyright   : Yale University, 2003@@ -7,6 +8,10 @@     )   where +#if __GLASGOW_HASKELL__ < 710+import Control.Applicative ((<*>))+import Data.Functor        ((<$>))+#endif import Test.QuickCheck import Test.Tasty (TestTree, testGroup) import Test.Tasty.QuickCheck (testProperty)@@ -25,12 +30,19 @@   , testProperty "identity (qc)"     prop_basic_identity_2   , testProperty "constant (fixed)"  (property $ basicsf_t1 ~= basicsf_t1r)   , testProperty "constant (qc)"     prop_basic_constant+  , testProperty "--> (qc)"          propInsert+  , testProperty "-:> (qc)"          propAlterFirstOutput+  , testProperty ">-- (qc)"          propInputInit+  , testProperty "-=> (qc)"          propModFirstOutput+  , testProperty ">=- (qc)"          propModFirstInput   , testProperty "initially (fixed)" (property $ basicsf_t4 ~= basicsf_t4r)   , testProperty "initially (qc)"    prop_basic_initially   ]  -- * Basic signal functions +-- ** identity+ basicsf_t0 :: [Double] basicsf_t0 = testSF1 identity basicsf_t0r =@@ -52,6 +64,8 @@   where myStream :: Gen (SignalSampleStream Float)         myStream = uniDistStream +-- ** constant+ basicsf_t1 :: [Double] basicsf_t1 = testSF1 (constant 42.0) basicsf_t1r =@@ -70,24 +84,175 @@  -- * Initialization -prop_insert =+-- ** @(-->)@++-- | Test that @initialValue --> integral@, when applied to any signal, is+-- initially equal to @constant initialValue@, and, in the future, always equal+-- to @integral@.+--+-- Note that it is important to understand that integral is "turned on" at time+-- zero, and its value discarded. This is not the same as using the constant SF+-- at time zero and turning @integral@ on at the next time (e.g., with+-- @switch@).+propInsert :: Property+propInsert =     forAll initialValueG $ \initialValue ->-    forAll finalValueG $ \finalValue ->     forAll myStream $ evalT $-      let sfStep = initialValue --> constant finalValue -      in And (prop (sfStep, const (== initialValue)))-             (Next $ Always $-                       (prop (sfStep, const (== finalValue))))+      -- SF that uses the actual function being tested+      let sfStep :: SF Float Float+          sfStep = initialValue --> integral -  where myStream :: Gen (SignalSampleStream Float)-        myStream = uniDistStream+      -- Expected behavior+      in And+           -- Currently equal to initialValue+           (SP $ (==) <$> sfStep <*> constant initialValue) -        initialValueG :: Gen Float-        initialValueG = arbitrary+           -- In the future, always equal to integral+           (Next $ Always $ SP $ (==) <$> sfStep <*> integral) -        finalValueG  :: Gen Float-        finalValueG = arbitrary+  where+    myStream :: Gen (SignalSampleStream Float)+    myStream = uniDistStream++    initialValueG :: Gen Float+    initialValueG = arbitrary++-- ** @(-:>)@++-- | Test that @initialValue -:> sf@, when applied to any signal, is initially+-- equal to @constant initialValue@, and, after that, the output is the same as+-- @sf@ (starting from that point).+propAlterFirstOutput :: Property+propAlterFirstOutput =+    forAll initialValueG $ \initialValue ->+    forAll myStream $ evalT $++      -- SF that uses the actual function being tested.+      --+      -- We pick a point-wise function for the test because we have no (easy)+      -- way of dropping a sample when we "turn of" the second sf in the+      -- comparison for future samples. For example, if we had picked integral,+      -- then the integral would start from the second sample (with the delay+      -- applied), but the temporal Next operator starts the SF now and waits+      -- until the next sample to check the property.+      let sfStep :: SF Float Float+          sfStep = (initialValue -:> arr (* 2)) >>> arr (^ 2)++      -- Expected behavior+      in And+           -- Currently equal to initialValue. In tis case it is safe to+           -- compare floating point numbers with (==) because the output HAS+           -- to be exactly the same. Note that, in the efinition of sfStep,+           -- the number initialValue should reach (arr (^ 2)) unchanged, and+           -- arr is just function application.+           (SP $ (==) <$> sfStep <*> constant (initialValue ^ 2))++           -- In the future, always equal to (arr ((^ 2) . (* 2)))). Note that+           -- we ignore initialValue completely.+           (Next $ Always $ SP $ (==) <$> sfStep <*> arr ((^ 2) . (* 2)))++  where+    myStream :: Gen (SignalSampleStream Float)+    myStream = uniDistStream++    initialValueG :: Gen Float+    initialValueG = arbitrary++-- ** @(>--)@++-- | Test that @initialValue >-- sf@, when applied to any signal, is initially+-- equal to @initialValue@, and, in the future, always equal to @sf@.+propInputInit :: Property+propInputInit =+    forAll initialValueG $ \initialValue ->+    forAll myStream $ evalT $++      -- SF that uses the actual function being tested+      let sfStep :: SF Float Float+          sfStep = initialValue --> arr (* 2)++      -- Expected behavior+      in And+           -- Currently equal to initialValue+           (SP $ (==) <$> sfStep <*> constant initialValue)++           -- In the future, always equal to arr (* 2)+           (Next $ Always $ SP $ (==) <$> sfStep <*> arr (* 2))++  where+    myStream :: Gen (SignalSampleStream Float)+    myStream = uniDistStream++    initialValueG :: Gen Float+    initialValueG = arbitrary++-- ** (-=>)++-- | Test that @(-=>)@ applies a transformation to the first output.+--+-- We test with the specific function @(* 4) -=> arr (^ 2)@.+propModFirstOutput :: Property+propModFirstOutput =+    forAll myStream $ evalT $++      -- SF that uses the actual function being tested.+      --+      -- We specifically pick transformations that do not commute, so that we+      -- test that transformations are applied in the expected order.+      let sfStep :: SF Float Float+          sfStep = (* 4) -=> arr (^ 2)++      -- Expected behavior+      in And+           -- Initially, both transformations are applied. Note that the+           -- difference between this comparison and the one for (>=-) is the+           -- order in which the two transformations are applied.+           (SP $ (==) <$> sfStep <*> arr ((* 4) . (^ 2)))++           -- In the future, only the second transformation is applied+           (Next $ Always $ SP $ (==) <$> sfStep <*> arr (^ 2))++  where+    myStream :: Gen (SignalSampleStream Float)+    myStream = uniDistStream++    initialValueG :: Gen Float+    initialValueG = arbitrary++-- ** @(>=-)@++-- | Test that @f -=> arr (^ 2)@, when applied to any signal, is initially+-- equal to initialValue, and, in the future, always equal to @arr (^ 2)@.+propModFirstInput :: Property+propModFirstInput =+    forAll myStream $ evalT $++      -- SF that uses the actual function being tested.+      --+      -- We specifically pick transformations that do not commute, so that we+      -- test that transformations are applied in the expected order.+      let sfStep :: SF Float Float+          sfStep = (* 2) >=- arr (^ 2)++      -- Expected behavior+      in And+           -- Initially, both transformations are applied. Note that the+           -- difference between this comparison and the one for (-=>) is the+           -- order in which the two transformations are applied.+           (SP $ (==) <$> sfStep <*> arr ((^ 2) . (* 2)))++           -- In the future, only the second transformation is applied+           (Next $ Always $ SP $ (==) <$> sfStep <*> arr (^ 2))++  where+    myStream :: Gen (SignalSampleStream Float)+    myStream = uniDistStream++    initialValueG :: Gen Float+    initialValueG = arbitrary++-- ** initially  basicsf_t4 :: [Double] basicsf_t4 = testSF1 (initially 42.0)
tests/Test/FRP/Yampa/Conditional.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE Arrows #-}+{-# LANGUAGE CPP    #-} -- | -- Description : Test cases for FRP.Yampa.Conditional -- Copyright   : Yale University, 2003@@ -7,12 +9,19 @@     )   where +#if __GLASGOW_HASKELL__ < 710+import Control.Applicative ((<*>))+import Data.Functor        ((<$>))+#endif import Test.QuickCheck import Test.Tasty (TestTree, testGroup) import Test.Tasty.QuickCheck (testProperty)  import FRP.Yampa as Yampa-import FRP.Yampa.Conditional (provided)+import FRP.Yampa.Conditional (pause, provided)+import FRP.Yampa.LTLFuture   (TPred (Always, SP), evalT)+import FRP.Yampa.QuickCheck  (uniDistStream)+import FRP.Yampa.Stream      (SignalSampleStream)  import TestsCommon @@ -20,6 +29,7 @@ tests = testGroup "Regression tests for FRP.Yampa.Conditional"   [ testProperty "provided (1, fixed)" (property $ utils_t8 ~= utils_t8r)   , testProperty "provided (2, fixed)" (property $ utils_t9 ~= utils_t9r)+  , testProperty "pause (qc)"          propPause   ]  -- * Guards and automata-oriented combinators@@ -59,3 +69,46 @@   , -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0   ,  0.0,  0.1,  0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9   ]++propPause :: Property+propPause =+    forAll initialValueG $ \initialValue ->+    forAll myStream $ evalT $+      -- The behavior of pause is always the same as some ideal behavior+      -- implemented by modelPause below. We give these auxiliary definitions+      -- names and pass initialValue as argument to facilitate debugging.+      Always $ SP $ (==) <$> sfPause initialValue <*> sfModelPause initialValue+  where+    myStream :: Gen (SignalSampleStream Float)+    myStream = uniDistStream++    initialValueG :: Gen Float+    initialValueG = arbitrary++    -- SF that uses the actual function being tested+    sfPause :: Float -> SF Float Float+    sfPause initialValue = pause initialValue (arr (odd . round)) integral++    -- Model SF that uses the actual function being tested+    sfModelPause :: Float -> SF Float Float+    sfModelPause initialValue =+      modelPause initialValue (arr (odd . round)) integral++    -- Model implementation of pause.+    modelPause :: b -> SF a Bool -> SF a b -> SF a b+    modelPause acc0 sf1 sf2 = proc (a) -> do+      rec c <- sf1 -< a++          -- Accumulator that is updated only when then condition is false.+          acc <- hold acc0 -< e++          -- When the condition is false, sf2 is turned on and executed,+          -- producing a new Event. Note that we need to put this in an+          -- ArrowCase block, we can't just run both and the decide whether we+          -- want to output the value or not based on the condition, because,+          -- in that case, the argument sf2 would still be executed and+          -- accumulate state.+          e <- if c then returnA -< NoEvent+                    else Event ^<< sf2 -< a++      returnA -< acc
tests/Test/FRP/Yampa/Delays.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} -- | -- Description : Test cases for FRP.Yampa.Delays -- Copyright   : Yale University, 2003@@ -7,11 +8,16 @@     )   where +#if __GLASGOW_HASKELL__ < 710+import Control.Applicative ((<*>))+import Data.Functor        ((<$>))+#endif import Test.QuickCheck import Test.Tasty (TestTree, testGroup) import Test.Tasty.QuickCheck (testProperty)  import FRP.Yampa as Yampa+import FRP.Yampa.Delays (fby) import FRP.Yampa.Stream import FRP.Yampa.QuickCheck import FRP.Yampa.LTLFuture@@ -20,7 +26,8 @@  tests :: TestTree tests = testGroup "Regression tests for FRP.Yampa.Delays"-  [ testProperty "iPre (0, fixed)"         (property $ pre_t0 ~= pre_t0r)+  [ testProperty "pre (qc)"                propPre+  , testProperty "iPre (0, fixed)"         (property $ pre_t0 ~= pre_t0r)   , testProperty "iPre (1, fixed)"         (property $ pre_t1 ~= pre_t1r)   , testProperty "iPre (2, fixed)"         (property $ pre_t2 ~= pre_t2r)   , testProperty "iPre (3, fixed)"         (property $ pre_t3 == pre_t3r)@@ -29,6 +36,7 @@   , testProperty "iPre (6, fixed)"         (property $ pre_t6 == pre_t6r)   , testProperty "iPre (7, fixed)"         (property $ pre_t7 == pre_t7r)   , testProperty "iPre (8, fixed)"         (property $ pre_t8 == pre_t8r)+  , testProperty "fby (qc)"                propFby   , testProperty "delay (0, fixed)"        (property $ delay_t0 ~= delay_t0r)   , testProperty "delay (1, fixed)"        (property $ delay_t1 ~= delay_t1r)   , testProperty "delay (2, fixed)"        (property $ delay_t2 ~= delay_t2r)@@ -39,8 +47,22 @@   , testProperty "delay (small delay, qc)" prop_delay_2   ] --- * Delays+-- * Basic delays +propPre :: Property+propPre =+    forAll initialValueG $ \initialValue ->+    forAll myStream $ evalT $+      -- The behavior of pre is always the same as iPre after the first sample.+      -- The value at time zero is undefined, so we don't need to test it.+      Next $ Always $ SP $ (==) <$> pre <*> iPre initialValue+  where+    myStream :: Gen (SignalSampleStream Float)+    myStream = uniDistStream++    initialValueG :: Gen Float+    initialValueG = arbitrary+ pre_t0 = testSF1 (iPre 17) pre_t0r =   [ 17.0,0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0@@ -211,6 +233,25 @@           , 10,10,10,10  -- 11s           , 10,10        -- 12s           ]++propFby :: Property+propFby =+    forAll initialValueG $ \initialValue ->+    forAll myStream $ evalT $+      -- fby is just a convenience function for iPre with composition+      Always $ SP $ (==) <$> fby initialValue sf <*> (sf >>> iPre initialValue)+  where+    myStream :: Gen (SignalSampleStream Float)+    myStream = uniDistStream++    initialValueG :: Gen Float+    initialValueG = arbitrary++    -- We pick the integral because it exploits the case where the SF has to be+    -- turned off sooner or later (it would produce different results if turned+    -- on at inconsistent times between fby and >>> iPre).+    sf :: SF Float Float+    sf = integral  -- * Timed delays 
yampa-test.cabal view
@@ -31,7 +31,7 @@ build-type:    Simple  name:          yampa-test-version:       0.13.5+version:       0.13.6 author:        Ivan Perez maintainer:    ivan.perez@keera.co.uk homepage:      http://github.com/ivanperez-keera/Yampa@@ -84,7 +84,7 @@       base               >= 4      && < 5     , normaldistribution     , QuickCheck-    , Yampa              >= 0.13.5 && < 0.14+    , Yampa              >= 0.13.6 && < 0.14    default-language:     Haskell2010