packages feed

registry 0.1.1.0 → 0.1.1.1

raw patch · 9 files changed

+175/−29 lines, 9 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Data.Registry.Lift: instance (GHC.Base.Applicative f, Data.Registry.Lift.ApplyVariadic f a' b', b ~ (f a -> b')) => Data.Registry.Lift.ApplyVariadic f (a -> a') b
- Data.Registry.Lift: instance (GHC.Base.Applicative f, Data.Registry.Lift.ApplyVariadic2 f g a' b', b ~ (a -> b')) => Data.Registry.Lift.ApplyVariadic2 f g (a -> a') b
- Data.Registry.Lift: instance (GHC.Base.Applicative f, b ~ f a) => Data.Registry.Lift.ApplyVariadic f a b
- Data.Registry.Lift: instance (GHC.Base.Applicative f, b ~ g a) => Data.Registry.Lift.ApplyVariadic2 f g (f a) b
- Data.Registry.Lift: instance (GHC.Base.Monad f, Data.Registry.Lift.ApplyVariadic1 f a' b', b ~ (f a -> b')) => Data.Registry.Lift.ApplyVariadic1 f (a -> a') b
- Data.Registry.Lift: instance (GHC.Base.Monad f, b ~ f a) => Data.Registry.Lift.ApplyVariadic1 f (f a) b
+ Data.Registry.Internal.Types: describeFunctions :: Functions -> Text
+ Data.Registry.Internal.Types: describeModifiers :: Modifiers -> Text
+ Data.Registry.Internal.Types: describeSpecializations :: Specializations -> Text
+ Data.Registry.Internal.Types: describeValues :: Values -> Text
+ Data.Registry.Internal.Types: getValueDynamic :: Value -> Dynamic
+ Data.Registry.Lift: instance (GHC.Base.Applicative f, Data.Registry.Lift.ApplyVariadic f a' b', b Data.Type.Equality.~ (f a -> b')) => Data.Registry.Lift.ApplyVariadic f (a -> a') b
+ Data.Registry.Lift: instance (GHC.Base.Applicative f, Data.Registry.Lift.ApplyVariadic2 f g a' b', b Data.Type.Equality.~ (a -> b')) => Data.Registry.Lift.ApplyVariadic2 f g (a -> a') b
+ Data.Registry.Lift: instance (GHC.Base.Applicative f, b Data.Type.Equality.~ f a) => Data.Registry.Lift.ApplyVariadic f a b
+ Data.Registry.Lift: instance (GHC.Base.Applicative f, b Data.Type.Equality.~ g a) => Data.Registry.Lift.ApplyVariadic2 f g (f a) b
+ Data.Registry.Lift: instance (GHC.Base.Monad f, Data.Registry.Lift.ApplyVariadic1 f a' b', b Data.Type.Equality.~ (f a -> b')) => Data.Registry.Lift.ApplyVariadic1 f (a -> a') b
+ Data.Registry.Lift: instance (GHC.Base.Monad f, b Data.Type.Equality.~ f a) => Data.Registry.Lift.ApplyVariadic1 f (f a) b
+ Data.Registry.Solver: type family (:++) (x :: [k]) (y :: [k]) :: [k]
- Data.Registry.Dot: makeDotEither :: forall a ins out. (Typeable a) => Registry ins out -> Either Text Dot
+ Data.Registry.Dot: makeDotEither :: forall a ins out. Typeable a => Registry ins out -> Either Text Dot
- Data.Registry.Dot: makeDotUnsafe :: forall a ins out. (Typeable a) => Registry ins out -> Dot
+ Data.Registry.Dot: makeDotUnsafe :: forall a ins out. Typeable a => Registry ins out -> Dot
- Data.Registry.Dot: makeOperationsEither :: forall a ins out. (Typeable a) => Registry ins out -> Either Text Operations
+ Data.Registry.Dot: makeOperationsEither :: forall a ins out. Typeable a => Registry ins out -> Either Text Operations
- Data.Registry.Dot: makeOperationsUnsafe :: forall a ins out. (Typeable a) => Registry ins out -> Operations
+ Data.Registry.Dot: makeOperationsUnsafe :: forall a ins out. Typeable a => Registry ins out -> Operations
- Data.Registry.Internal.Cache: Cache :: (MVar (Maybe a)) -> Cache a
+ Data.Registry.Internal.Cache: Cache :: MVar (Maybe a) -> Cache a
- Data.Registry.Internal.Cache: fetch :: forall a m. (MonadIO m) => Cache a -> m a -> m a
+ Data.Registry.Internal.Cache: fetch :: forall a m. MonadIO m => Cache a -> m a -> m a
- Data.Registry.Internal.Reflection: showTheFullFunctionType :: forall (r1 :: RuntimeRep) (arg :: TYPE r1). (TypeRep arg -> ([Text], Text))
+ Data.Registry.Internal.Reflection: showTheFullFunctionType :: forall (r1 :: RuntimeRep) (arg :: TYPE r1). TypeRep arg -> ([Text], Text)
- Data.Registry.Internal.Reflection: showTheFullValueType :: forall (r1 :: RuntimeRep) (arg :: TYPE r1). (TypeRep arg -> Text)
+ Data.Registry.Internal.Reflection: showTheFullValueType :: forall (r1 :: RuntimeRep) (arg :: TYPE r1). TypeRep arg -> Text
- Data.Registry.Internal.Types: createFunction :: (Typeable a) => a -> Function
+ Data.Registry.Internal.Types: createFunction :: Typeable a => a -> Function
- Data.Registry.Internal.Types: describeTypeableValue :: (Typeable a) => a -> ValueDescription
+ Data.Registry.Internal.Types: describeTypeableValue :: Typeable a => a -> ValueDescription
- Data.Registry.Make: makeEither :: forall a ins out. (Typeable a) => Registry ins out -> Either Text a
+ Data.Registry.Make: makeEither :: forall a ins out. Typeable a => Registry ins out -> Either Text a
- Data.Registry.Make: makeUnsafe :: forall a ins out. (Typeable a) => Registry ins out -> a
+ Data.Registry.Make: makeUnsafe :: forall a ins out. Typeable a => Registry ins out -> a
- Data.Registry.RIO: RIO :: Stop -> IO (a, Warmup) -> RIO a
+ Data.Registry.RIO: RIO :: (Stop -> IO (a, Warmup)) -> RIO a
- Data.Registry.Registry: (+:) :: (Typeable a) => Typed a -> Registry ins out -> Registry (Inputs a :++ ins) (Output a : out)
+ Data.Registry.Registry: (+:) :: Typeable a => Typed a -> Registry ins out -> Registry (Inputs a :++ ins) (Output a : out)
- Data.Registry.Registry: fun :: (Typeable a) => a -> Typed a
+ Data.Registry.Registry: fun :: Typeable a => a -> Typed a
- Data.Registry.Registry: register :: (Typeable a) => Typed a -> Registry ins out -> Registry (Inputs a :++ ins) (Output a : out)
+ Data.Registry.Registry: register :: Typeable a => Typed a -> Registry ins out -> Registry (Inputs a :++ ins) (Output a : out)
- Data.Registry.Registry: tweakUnsafe :: forall a ins out. (Typeable a) => (a -> a) -> Registry ins out -> Registry ins out
+ Data.Registry.Registry: tweakUnsafe :: forall a ins out. Typeable a => (a -> a) -> Registry ins out -> Registry ins out

Files

registry.cabal view
@@ -1,11 +1,13 @@--- This file has been generated from package.yaml by hpack version 0.28.2.+cabal-version: 1.12++-- This file has been generated from package.yaml by hpack version 0.31.0. -- -- see: https://github.com/sol/hpack ----- hash: a6b0a84be53407fd0d0dfd4cd14b966f573fc2925fdd6fb561542e4e93f26676+-- hash: e2e1d6fc54b123bc23add64e260b71809555917b9df05c2f2a1d3478cc89242c  name:           registry-version:        0.1.1.0+version:        0.1.1.1 synopsis:       data structure for assembling "components" description:    This library provides a "Registry" which is a data structure containing a list of functions and values representing dependencies in a directed acyclic graph. A `make` function can then be used to create a value of a specific type out of the registry.                 You can start with the [README](https://github.com/etorreborre/registry/blob/master/README.md) for a full description of the library.@@ -14,7 +16,6 @@ license:        MIT license-file:   LICENSE.txt build-type:     Simple-cabal-version:  >= 1.10  source-repository head   type: git@@ -58,6 +59,7 @@   main-is: test.hs   other-modules:       Test.Data.Registry.DotSpec+      Test.Data.Registry.GenSpec       Test.Data.Registry.Internal.CacheSpec       Test.Data.Registry.Internal.DynamicSpec       Test.Data.Registry.Internal.Gens
src/Data/Registry/Internal/Reflection.hs view
@@ -86,7 +86,8 @@ mustShowModuleName name = not $ P.any identity $   fmap (`isPrefixOf` name) [       "GHC.Types."    -- for Int, Double,..-    , "GHC.Base."     -- for Maybe+    , "GHC.Base."     -- for other Base types+    , "GHC.Maybe."    -- for Maybe     , "Data.Either."  -- for Either     , "Data.Text.Internal"] 
src/Data/Registry/Internal/Registry.hs view
@@ -20,8 +20,8 @@ --   where some of them are not functions --   There is also a list of specializations when we can specialize the values to use --   if a given type is part of the context-findValue-  :: SomeTypeRep+findValue ::+     SomeTypeRep   -> Context   -> Specializations   -> Values@@ -48,8 +48,8 @@  -- | Find a constructor function returning a target type --   from a list of constructors-findConstructor-  :: SomeTypeRep+findConstructor ::+     SomeTypeRep   -> Functions   -> Maybe Function findConstructor _      (Functions []        ) = Nothing@@ -76,8 +76,8 @@ --   to catch and report the error. Note that this error would be an implementation --   error (and not a user error) since at the type-level everything should be correct ---storeValue-  :: Modifiers+storeValue ::+     Modifiers   -> Value   -> Stack Value storeValue (Modifiers ms) value =
src/Data/Registry/Internal/Types.hs view
@@ -9,7 +9,8 @@ import           Data.Registry.Internal.Reflection import           Data.Text                         as T import           Prelude                           (show)-import           Protolude                         hiding (show)+import           Protolude                         as P hiding (show)+import qualified Protolude                         as P import           Type.Reflection  -- | A 'Function' is the 'Dynamic' representation of a Haskell value + its description@@ -20,6 +21,11 @@   | ProvidedValue Dynamic ValueDescription   deriving (Show) +-- | Return the dynamic part of a value+getValueDynamic :: Value -> Dynamic+getValueDynamic (CreatedValue d _)  = d+getValueDynamic (ProvidedValue d _) = d+ -- | Description of a value. It might just have --   a description for its type when it is a value --   created by the resolution algorithm@@ -70,7 +76,7 @@ -- | A ValueDescription as 'Text'. If the actual content of the 'Value' --   is provided display the type first then the content valDescriptionToText :: ValueDescription -> Text-valDescriptionToText (ValueDescription t Nothing) = t+valDescriptionToText (ValueDescription t Nothing)  = t valDescriptionToText (ValueDescription t (Just v)) = t <> ": " <> v  -- | A Function is the 'Dynamic' representation of a Haskell function + its description@@ -127,6 +133,14 @@ -- | The list of functions available for constructing other values newtype Functions = Functions [Function] deriving (Show, Semigroup, Monoid) +-- | Display a list of constructors+describeFunctions :: Functions -> Text+describeFunctions (Functions fs) =+  if P.null fs then+    ""+  else+    unlines (funDescriptionToText . funDescription <$> fs)+ -- | Add one more Function to the list of Functions addFunction :: Function -> Functions -> Functions addFunction f (Functions fs) = Functions (f : fs)@@ -134,6 +148,14 @@ -- | List of values available for constructing other values newtype Values = Values [Value] deriving (Show, Semigroup, Monoid) +-- | Display a list of values+describeValues :: Values -> Text+describeValues (Values vs) =+  if P.null vs then+    ""+  else+    unlines (valDescriptionToText . valDescription <$> vs)+ -- | Add one more Value to the list of Values addValue :: Value -> Values -> Values addValue v (Values vs) = Values (v : vs)@@ -145,7 +167,25 @@ --   construction when a corresponding type comes in context newtype Specializations = Specializations [(SomeTypeRep, Value)] deriving (Show, Semigroup, Monoid) +-- | Display a list of specializations for the Registry, just showing the+--   context (a type) in which a value must be selected+describeSpecializations :: Specializations -> Text+describeSpecializations (Specializations ss) =+  if P.null ss then+    ""+  else+    "specializations\n" <> unlines (P.show <$> ss)+ -- | List of functions modifying some values right after they have been --   built. This enables "tweaking" the creation process with slightly --   different results. Here SomeTypeRep is the target value type 'a' and newtype Modifiers = Modifiers [(SomeTypeRep, Function)] deriving (Show, Semigroup, Monoid)++-- | Display a list of modifiers for the Registry, just showing the+--   type of the modified value+describeModifiers :: Modifiers -> Text+describeModifiers (Modifiers ms) =+  if P.null ms then+    ""+  else+    "modifiers for types\n" <> unlines (P.show . fst <$> ms)
src/Data/Registry/Registry.hs view
@@ -78,15 +78,13 @@   }  instance Show (Registry inputs outputs) where-  show (Registry (Values vs) (Functions fs) _ _) =-    let describeValues =-          if null vs then ""-          else            unlines (valDescriptionToText . valDescription <$> vs)-        describeFunctions =-            if null fs then ""-            else            unlines (funDescriptionToText . funDescription <$> fs)-    in-        toS $ unlines [describeValues, describeFunctions]+  show (Registry vs fs ss ms) =+    toS $ unlines [+        describeValues vs+      , describeFunctions fs+      , describeSpecializations ss+      , describeModifiers ms+      ]  instance Semigroup (Registry inputs outputs) where   (<>) (Registry (Values vs1) (Functions fs1) (Specializations ss1) (Modifiers ms1))
+ test/Test/Data/Registry/GenSpec.hs view
@@ -0,0 +1,106 @@+{-# LANGUAGE PartialTypeSignatures #-}+{-# LANGUAGE TemplateHaskell       #-}+{-# OPTIONS_GHC -fno-warn-missing-signatures #-}++{-+  This module shows how to use the registry with hedgehog generators+-}+module Test.Data.Registry.GenSpec where++import           Data.Registry+import           Hedgehog.Gen          as Gen+import           Hedgehog.Range        as Range+import           Protolude             as P+import           Test.Tasty.Extensions++-- * DATA MODEL++newtype Company =+  Company { departments :: [Department] }+  deriving (Eq, Show)++newtype Department =+  Department { employees :: [Employee] }+  deriving (Eq, Show)++data Employee = Employee {+    name   :: Name+  , age    :: Age+  , salary :: Salary+} deriving (Eq, Show)++newtype Name = Name Text deriving (Eq, Show)+newtype Age  = Age Int deriving (Eq, Show, Ord, Num)++data Salary =+    Fixed Int+  | Variable Int Double+  deriving (Eq, Show)++-- * GENERATORS++genText :: Gen Text+genText = Gen.text (Range.linear 2 10) Gen.ascii++genList :: forall a . (Typeable a) => Gen a -> Gen [a]+genList = Gen.list (Range.linear 0 3)++genInt :: Gen Int+genInt = Gen.int (Range.linear 1 100)++genDouble :: Gen Double+genDouble = Gen.double (Range.linearFrac 1 100)++setDepartmentWithOneEmployee :: Monad m => RegistryProperty m ()+setDepartmentWithOneEmployee = do+  e <- forall @Employee+  tweakGen @[Employee] (const $ pure [e])++setCompanyWithOneDepartment :: Monad m => RegistryProperty m ()+setCompanyWithOneDepartment = do+  d <- forall @Department+  tweakGen @[Department] (const (pure [d]))++setMinimalCompany :: Monad m => RegistryProperty m ()+setMinimalCompany =+  -- be careful, this is NOT commutative!+  -- if you set a company with one department first you may end up+  -- with a department with no employees, generated once and forall+  setDepartmentWithOneEmployee >>+  setCompanyWithOneDepartment++-- | Create a registry for all generators+registry =+     funTo @Gen Company+  +: funTo @Gen Department+  +: funTo @Gen Employee+  +: funTo @Gen Fixed+  +: funTo @Gen Name+  +: funTo @Gen Age+  +: fun (genList @Department)+  +: fun (genList @Employee)+  +: fun genInt+  +: fun genText+  +: fun genDouble+  +: end++test_company_with_one_employee = noShrink $ prop "generate just one employee" $ run $ do+  setMinimalCompany+  company <- forall @Company+  let allEmployees = company & departments >>= (& employees)+  length allEmployees === 1++-- * HELPERS++type RegistryProperty m a = forall ins out . StateT (Registry ins out) (PropertyT m) a++forall :: forall a m . (HasCallStack, Typeable a, Show a, Monad m) => RegistryProperty m a+forall = withFrozenCallStack $ get >>= P.lift . forAll . makeUnsafe @(Gen a)++tweakGen :: forall a m . (Typeable a, Monad m) => (Gen a -> Gen a) -> RegistryProperty m ()+tweakGen f = modify $ tweakUnsafe @(Gen a) f++run :: Monad m => RegistryProperty m a -> PropertyT m a+run = flip evalStateT registry+----+tests = $(testGroupGenerator)
test/Test/Data/Registry/Internal/Gens.hs view
@@ -64,9 +64,7 @@   pure (value, values)  genSomeTypeRep :: Gen Value -> Gen SomeTypeRep-genSomeTypeRep genValue = do-  ProvidedValue a _ <- genValue-  pure $ dynTypeRep a+genSomeTypeRep = fmap (dynTypeRep . getValueDynamic)  genDynamic :: Gen Dynamic genDynamic = Gen.element [toDyn (1 :: Int), toDyn (2 :: Int), toDyn ("1" :: Text)]
test/Test/Data/Registry/Internal/RegistrySpec.hs view
@@ -1,15 +1,16 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TemplateHaskell     #-} {-# LANGUAGE TypeApplications    #-}-{-# OPTIONS_GHC -fno-warn-missing-signatures #-} {-# OPTIONS_GHC -fno-warn-deprecations #-}+{-# OPTIONS_GHC -fno-warn-missing-signatures #-}+{-# OPTIONS_GHC -fno-warn-incomplete-uni-patterns #-}  module Test.Data.Registry.Internal.RegistrySpec where  import           Data.Dynamic-import           Data.Registry.Internal.Types-import           Data.Registry.Internal.Stack import           Data.Registry.Internal.Registry+import           Data.Registry.Internal.Stack+import           Data.Registry.Internal.Types import           Protolude                        as P hiding (show) import           Test.Data.Registry.Internal.Gens import           Test.Tasty.Extensions
test/Test/Data/Registry/RegistrySpec.hs view
@@ -30,7 +30,7 @@ newLogger = pure (Logger print)  refLogger :: IORef Text -> Logger-refLogger ref = Logger (\t -> writeIORef ref t)+refLogger ref = Logger (writeIORef ref)  registry =      fun newLogger