diff --git a/primer/test/Gen/App.hs b/primer/gen/Primer/Gen/App.hs similarity index 94% rename from primer/test/Gen/App.hs rename to primer/gen/Primer/Gen/App.hs index 0440f3ce4..271b485ac 100644 --- a/primer/test/Gen/App.hs +++ b/primer/gen/Primer/Gen/App.hs @@ -5,7 +5,7 @@ -- | -- This module generates well-typed 'Prog's -- It is however, slow and the distribution is not very even. -module Gen.App ( +module Primer.Gen.App ( genProg, ) where @@ -16,7 +16,7 @@ import Primer.Module (Module (Module, moduleDefs, moduleName, moduleTypes), modu import Primer.Name (Name, unsafeMkName) import Primer.Typecheck (Cxt, SmartHoles, extendGlobalCxt, extendTypeDefCxt) -import Gen.Core.Typed (WT, freshNameForCxt, genChk, genTypeDefGroup, genWTType) +import Primer.Gen.Core.Typed (WT, freshNameForCxt, genChk, genTypeDefGroup, genWTType) import Hedgehog (GenT, MonadGen) import Hedgehog.Gen qualified as Gen @@ -57,7 +57,7 @@ genProg sh initialImports = local (extendCxtByModules initialImports) $ do . extendGlobalCxt (M.toList . fmap (forgetTypeMetadata . defType) $ foldMap moduleDefsQualified ms) genModule :: Name -> Int -> GenT WT Module genModule prefix index = do - let mn = ModuleName [prefix, unsafeMkName $ show index] + let mn = ModuleName $ prefix :| [unsafeMkName $ show index] tds <- genTypeDefGroup $ Just mn defs <- local (extendTypeDefCxt $ M.fromList tds) (genASTDefGroup mn) pure $ diff --git a/primer/test/Gen/Core/Raw.hs b/primer/gen/Primer/Gen/Core/Raw.hs similarity index 98% rename from primer/test/Gen/Core/Raw.hs rename to primer/gen/Primer/Gen/Core/Raw.hs index fbb98a080..3adfcb8aa 100644 --- a/primer/test/Gen/Core/Raw.hs +++ b/primer/gen/Primer/Gen/Core/Raw.hs @@ -3,8 +3,8 @@ -- That is, syntax trees which are not (necessarily) well-typed, or even well-scoped. -- It is however, fast and has good coverage properties. -- --- For generating well-typed terms, see "Gen.Core.Typed". -module Gen.Core.Raw ( +-- For generating well-typed terms, see "Primer.Gen.Core.Typed". +module Primer.Gen.Core.Raw ( runExprGen, evalExprGen, genID, diff --git a/primer/test/Gen/Core/Typed.hs b/primer/gen/Primer/Gen/Core/Typed.hs similarity index 98% rename from primer/test/Gen/Core/Typed.hs rename to primer/gen/Primer/Gen/Core/Typed.hs index 5f60c39a6..9b4c5750e 100644 --- a/primer/test/Gen/Core/Typed.hs +++ b/primer/gen/Primer/Gen/Core/Typed.hs @@ -6,8 +6,8 @@ -- This module generates well-typed terms and types. -- It is however, slow and the distribution is not very even. -- --- For quickly generating non-well-typed-or-scoped terms, see "Gen.Core.Raw". -module Gen.Core.Typed ( +-- For quickly generating non-well-typed-or-scoped terms, see "Primer.Gen.Core.Raw". +module Primer.Gen.Core.Typed ( WT, isolateWT, genWTType, @@ -33,7 +33,6 @@ import Control.Monad.Fresh (MonadFresh, fresh) import Control.Monad.Morph (hoist) import Control.Monad.Reader (mapReaderT) import Data.Map qualified as M -import Gen.Core.Raw (genLVarName, genModuleName, genName, genTyVarName) import Hedgehog ( GenT, MonadGen, @@ -69,6 +68,7 @@ import Primer.Core ( valConType, ) import Primer.Core.Utils (freeVarsTy) +import Primer.Gen.Core.Raw (genLVarName, genModuleName, genName, genTyVarName) import Primer.Module (Module (..)) import Primer.Name (Name, NameCounter, freshName, unName, unsafeMkName) import Primer.Refine (Inst (InstAPP, InstApp, InstUnconstrainedAPP), refine) @@ -96,8 +96,8 @@ import Primer.Typecheck ( primConInScope, typeDefs, ) +import Tasty (Property, property) import TestM (TestM, evalTestM, isolateTestM) -import TestUtils (Property, property) {- Generate well scoped and typed expressions. diff --git a/primer/gen/Tasty.hs b/primer/gen/Tasty.hs new file mode 100644 index 000000000..fd909724c --- /dev/null +++ b/primer/gen/Tasty.hs @@ -0,0 +1,29 @@ +module Tasty (Property, property, withTests, withDiscards) where + +import Data.Coerce (coerce) +import Data.String (fromString) +import Hedgehog qualified as H +import Test.Tasty.Discover qualified as TD +import Test.Tasty.Hedgehog qualified as TH + +import Foreword + +-- | Work around tasty changes which give deprecation warnings for tasty-discover generated code +newtype Property = Property + { unProperty :: H.Property + } + +instance TD.Tasty Property where + tasty info = + pure + . TH.testPropertyNamed (TD.descriptionOf info) (fromString (TD.descriptionOf info)) + . unProperty + +property :: HasCallStack => H.PropertyT IO () -> Property +property = Property . H.property + +withTests :: H.TestLimit -> Property -> Property +withTests = coerce H.withTests + +withDiscards :: H.DiscardLimit -> Property -> Property +withDiscards = coerce H.withDiscards diff --git a/primer/test/TestM.hs b/primer/gen/TestM.hs similarity index 100% rename from primer/test/TestM.hs rename to primer/gen/TestM.hs diff --git a/primer/primer.cabal b/primer/primer.cabal index 03c5552d0..10f4db3cc 100644 --- a/primer/primer.cabal +++ b/primer/primer.cabal @@ -1,4 +1,4 @@ -cabal-version: 2.4 +cabal-version: 3.0 name: primer version: 0.7.2.0 license: AGPL-3.0-or-later @@ -88,15 +88,45 @@ library , uniplate >=1.6 && <=1.7 , uuid >=1.3 && <=1.4 +library primer-hedgehog + visibility: public + exposed-modules: + Primer.Gen.App + Primer.Gen.Core.Raw + Primer.Gen.Core.Typed + Tasty + TestM + + other-modules: + hs-source-dirs: gen + default-language: GHC2021 + default-extensions: + NoImplicitPrelude + DataKinds + DerivingStrategies + DerivingVia + LambdaCase + OverloadedStrings + + ghc-options: + -Wall -Wincomplete-uni-patterns -Wincomplete-record-updates + -Wcompat -Widentities -Wredundant-constraints -fhide-source-paths + + build-depends: + , base + , containers + , hedgehog ^>=1.1.1 + , mmorph ^>=1.2.0 + , mtl + , primer + , tasty-discover ^>=4.2.4 + , tasty-hedgehog ^>=1.2.0 + test-suite primer-test type: exitcode-stdio-1.0 main-is: Test.hs hs-source-dirs: test other-modules: - Gen.App - Gen.Core.Raw - Gen.Core.Typed - TestM Tests.Action Tests.Action.Available Tests.Action.Capture @@ -169,6 +199,7 @@ test-suite primer-test , prettyprinter >=1.7.1 && <=1.8 , prettyprinter-ansi-terminal >=1.1.3 && <=1.2 , primer + , primer-hedgehog , protolude , stm , stm-containers diff --git a/primer/test/TestUtils.hs b/primer/test/TestUtils.hs index 83d3dd429..de3217fa7 100644 --- a/primer/test/TestUtils.hs +++ b/primer/test/TestUtils.hs @@ -14,10 +14,6 @@ module TestUtils ( zeroTypeIDs, clearMeta, clearTypeMeta, - Property, - property, - withTests, - withDiscards, runAPI, ) where @@ -27,10 +23,8 @@ import Control.Concurrent.STM ( newTBQueueIO, ) import Control.Monad.Fresh (MonadFresh) -import Data.Coerce (coerce) -import Data.String (String, fromString) +import Data.String (String) import Data.Typeable (typeOf) -import Hedgehog qualified as H import Optics (over, set, view) import Primer.API ( Env (..), @@ -71,13 +65,11 @@ import Primer.Database ( import Primer.Name (Name (unName)) import Primer.Primitives (allPrimDefs) import StmContainers.Map qualified as StmMap -import Test.Tasty.Discover qualified as TD import Test.Tasty.HUnit ( assertBool, assertFailure, ) import Test.Tasty.HUnit qualified as HUnit -import Test.Tasty.Hedgehog qualified as TH withPrimDefs :: MonadFresh ID m => (Map GVarName PrimDef -> m a) -> m a withPrimDefs f = do @@ -143,26 +135,6 @@ assertException msg p action = do wrongException e = msg <> " threw " <> show e <> ", but we expected " <> exceptionType exceptionType = (show . typeOf) p --- | Work around tasty changes which give deprecation warnings for tasty-discover generated code -newtype Property = Property - { unProperty :: H.Property - } - -instance TD.Tasty Property where - tasty info = - pure - . TH.testPropertyNamed (TD.descriptionOf info) (fromString (TD.descriptionOf info)) - . unProperty - -property :: HasCallStack => H.PropertyT IO () -> Property -property = Property . H.property - -withTests :: H.TestLimit -> Property -> Property -withTests = coerce H.withTests - -withDiscards :: H.DiscardLimit -> Property -> Property -withDiscards = coerce H.withDiscards - -- Run 2 threads: one that serves a 'NullDb', and one that runs Primer -- API actions. This allows us to simulate a database and API service. -- diff --git a/primer/test/Tests/API.hs b/primer/test/Tests/API.hs index af1ee3483..c5785ff58 100644 --- a/primer/test/Tests/API.hs +++ b/primer/test/Tests/API.hs @@ -5,7 +5,6 @@ import Foreword import Data.ByteString.Lazy qualified as BSL import Data.Text.Lazy qualified as TL import Data.UUID.V4 (nextRandom) -import Gen.Core.Raw (evalExprGen, genExpr, genType) import Hedgehog hiding (Property, property) import Primer.API ( PrimerErr, @@ -37,15 +36,18 @@ import Primer.Examples ( comprehensive, even3App, ) +import Primer.Gen.Core.Raw (evalExprGen, genExpr, genType) import Protolude.Unsafe (unsafeFromJust) +import Tasty ( + Property, + property, + ) import Test.Tasty (TestTree, testGroup) import Test.Tasty.Golden (goldenVsString) import Test.Tasty.HUnit hiding ((@?=)) import TestUtils ( ExceptionPredicate, - Property, assertException, - property, runAPI, (@?=), ) diff --git a/primer/test/Tests/Action.hs b/primer/test/Tests/Action.hs index 65fb44244..a06ade931 100644 --- a/primer/test/Tests/Action.hs +++ b/primer/test/Tests/Action.hs @@ -5,10 +5,6 @@ import Foreword import Data.Data (Data) import Data.Generics.Uniplate.Data (universe) -import Gen.Core.Raw ( - evalExprGen, - genExpr, - ) import Hedgehog hiding ( Action, Property, @@ -32,6 +28,10 @@ import Primer.Core ( getID, ) import Primer.Core.DSL +import Primer.Gen.Core.Raw ( + evalExprGen, + genExpr, + ) import Primer.Typecheck (SmartHoles (NoSmartHoles, SmartHoles)) import Primer.Zipper ( down, @@ -41,9 +41,10 @@ import Primer.Zipper ( unfocusExpr, unfocusType, ) +import Tasty (Property, property) import Test.Tasty.HUnit (Assertion, assertFailure, (@?=)) import TestM (evalTestM) -import TestUtils (Property, clearMeta, constructCon, constructRefinedCon, constructTCon, property) +import TestUtils (clearMeta, constructCon, constructRefinedCon, constructTCon) -- Note: 'maximum' is partial, but we believe that 'maxID' itself is -- safe due to the fact that 'universe x' always contains at least diff --git a/primer/test/Tests/AlphaEquality.hs b/primer/test/Tests/AlphaEquality.hs index e8b4e5eef..629d38b88 100644 --- a/primer/test/Tests/AlphaEquality.hs +++ b/primer/test/Tests/AlphaEquality.hs @@ -2,11 +2,6 @@ module Tests.AlphaEquality where import Foreword -import Gen.Core.Raw ( - evalExprGen, - genTyVarName, - genType, - ) import Hedgehog hiding (Property, check, property) import Primer.Builtins import Primer.Core ( @@ -15,8 +10,13 @@ import Primer.Core ( ) import Primer.Core.DSL import Primer.Core.Utils (alphaEqTy, forgetTypeMetadata) +import Primer.Gen.Core.Raw ( + evalExprGen, + genTyVarName, + genType, + ) +import Tasty (Property, property) import Test.Tasty.HUnit hiding (assert) -import TestUtils (Property, property) unit_1 :: Assertion unit_1 = diff --git a/primer/test/Tests/EvalFull.hs b/primer/test/Tests/EvalFull.hs index 317f8c9d2..201980a85 100644 --- a/primer/test/Tests/EvalFull.hs +++ b/primer/test/Tests/EvalFull.hs @@ -9,7 +9,6 @@ import Data.Map qualified as M import Data.Map qualified as Map import Data.Set qualified as S import Data.String (unlines) -import Gen.Core.Typed (WT, forAllT, genChk, genSyn, genWTType, isolateWT, propertyWT) import Hedgehog hiding (Property, Var, check, property, test, withDiscards, withTests) import Hedgehog.Gen qualified as Gen import Hedgehog.Internal.Property (LabelName (unLabelName)) @@ -53,6 +52,7 @@ import Primer.Examples qualified as Examples ( map', odd, ) +import Primer.Gen.Core.Typed (WT, forAllT, genChk, genSyn, genWTType, isolateWT, propertyWT) import Primer.Module (Module (Module, moduleDefs, moduleName, moduleTypes), moduleDefsQualified, moduleTypesQualified) import Primer.Name (Name) import Primer.Primitives (primitiveGVar, primitiveModule, tChar, tInt) @@ -62,14 +62,16 @@ import Primer.Typecheck ( extendGlobalCxt, typeDefs, ) -import Test.Tasty.HUnit (Assertion, assertBool, assertFailure, (@?=)) -import TestM -import TestUtils ( +import Tasty ( Property, property, withDiscards, - withPrimDefs, withTests, + ) +import Test.Tasty.HUnit (Assertion, assertBool, assertFailure, (@?=)) +import TestM +import TestUtils ( + withPrimDefs, zeroIDs, ) import Tests.Action.Prog (runAppTestM) diff --git a/primer/test/Tests/Gen/App.hs b/primer/test/Tests/Gen/App.hs index e8e18ab52..54d46b975 100644 --- a/primer/test/Tests/Gen/App.hs +++ b/primer/test/Tests/Gen/App.hs @@ -4,10 +4,6 @@ module Tests.Gen.App where import Foreword -import Gen.App (genProg) -import Gen.Core.Typed ( - propertyWT, - ) import Hedgehog ( annotateShow, failure, @@ -15,9 +11,13 @@ import Hedgehog ( import Hedgehog.Internal.Property (forAllT) import Primer.App (checkProgWellFormed) import Primer.Builtins (builtinModule) +import Primer.Gen.App (genProg) +import Primer.Gen.Core.Typed ( + propertyWT, + ) import Primer.Primitives (primitiveModule) import Primer.Typecheck (SmartHoles (NoSmartHoles), TypeError) -import TestUtils (Property, withDiscards, withTests) +import Tasty (Property, withDiscards, withTests) tasty_genProg_well_formed :: Property tasty_genProg_well_formed = withTests 1000 $ diff --git a/primer/test/Tests/Gen/Core/Typed.hs b/primer/test/Tests/Gen/Core/Typed.hs index 58db23036..b9cca6784 100644 --- a/primer/test/Tests/Gen/Core/Typed.hs +++ b/primer/test/Tests/Gen/Core/Typed.hs @@ -5,16 +5,6 @@ module Tests.Gen.Core.Typed where import Data.Map qualified as M import Foreword hiding (diff) -import Gen.Core.Typed ( - WT, - genChk, - genCxtExtendingGlobal, - genCxtExtendingLocal, - genSyns, - genWTKind, - genWTType, - propertyWT, - ) import Hedgehog ( PropertyT, annotateShow, @@ -37,6 +27,16 @@ import Primer.Core.Utils ( generateIDs, generateTypeIDs, ) +import Primer.Gen.Core.Typed ( + WT, + genChk, + genCxtExtendingGlobal, + genCxtExtendingLocal, + genSyns, + genWTKind, + genWTType, + propertyWT, + ) import Primer.Module (Module) import Primer.Primitives (primitiveModule) import Primer.Typecheck ( @@ -52,7 +52,7 @@ import Primer.Typecheck ( synth, synthKind, ) -import TestUtils (Property, withDiscards, withTests) +import Tasty (Property, withDiscards, withTests) inExtendedGlobalCxt :: PropertyT WT a -> PropertyT WT a inExtendedGlobalCxt p = do diff --git a/primer/test/Tests/Primitives.hs b/primer/test/Tests/Primitives.hs index 33c003cae..7a1634c86 100644 --- a/primer/test/Tests/Primitives.hs +++ b/primer/test/Tests/Primitives.hs @@ -5,7 +5,6 @@ module Tests.Primitives where import Foreword import Data.Map qualified as M -import Gen.Core.Typed (forAllT, genPrimCon, propertyWT) import Hedgehog (assert) import Hedgehog.Gen (choice) import Primer.Core ( @@ -20,6 +19,7 @@ import Primer.Core ( primConName, ) import Primer.Core.DSL (char, tcon) +import Primer.Gen.Core.Typed (forAllT, genPrimCon, propertyWT) import Primer.Primitives (allPrimTypeDefs, primitiveModule, tChar) import Primer.Typecheck ( SmartHoles (NoSmartHoles), @@ -30,7 +30,7 @@ import Primer.Typecheck ( checkValidContext, synth, ) -import TestUtils (Property) +import Tasty (Property) import Primer.Builtins (builtinModule) import Test.Tasty.HUnit (Assertion, assertBool, (@?=)) diff --git a/primer/test/Tests/Question.hs b/primer/test/Tests/Question.hs index 61cf99a11..d0f63d459 100644 --- a/primer/test/Tests/Question.hs +++ b/primer/test/Tests/Question.hs @@ -4,7 +4,6 @@ module Tests.Question where import Foreword hiding (diff) import Data.List (nub, nubBy) -import Gen.Core.Raw (evalExprGen, genKind, genName, genTyVarName, genType) import Hedgehog hiding (Property, check, property) import Hedgehog.Classes import Hedgehog.Gen qualified as Gen @@ -25,6 +24,7 @@ import Primer.Core ( ) import Primer.Core.DSL import Primer.Core.Utils (forgetTypeMetadata) +import Primer.Gen.Core.Raw (evalExprGen, genKind, genName, genTyVarName, genType) import Primer.Name import Primer.Questions ( ShadowedVarsExpr (M), @@ -42,10 +42,10 @@ import Primer.Typecheck ( synth, ) import Primer.Zipper (ExprZ, TypeZip, down, focus, right) +import Tasty (Property, property) import Test.Tasty import Test.Tasty.HUnit (Assertion, assertFailure, (@?=)) import Test.Tasty.Hedgehog -import TestUtils (Property, property) import Tests.Typecheck (runTypecheckTestM) test_laws :: TestTree diff --git a/primer/test/Tests/Refine.hs b/primer/test/Tests/Refine.hs index 7a7f436cb..524512cfb 100644 --- a/primer/test/Tests/Refine.hs +++ b/primer/test/Tests/Refine.hs @@ -5,13 +5,6 @@ import Foreword hiding (diff) import Control.Monad.Fresh (MonadFresh) import Data.Map qualified as M import Data.Set qualified as S -import Gen.Core.Typed ( - forAllT, - freshTyVarNameForCxt, - genInstApp, - genWTKind, - genWTType, - ) import Hedgehog ( annotateShow, diff, @@ -34,6 +27,13 @@ import Primer.Core ( valConType, ) import Primer.Core.Utils (forgetMetadata, freeVarsTy, generateIDs, noHoles) +import Primer.Gen.Core.Typed ( + forAllT, + freshTyVarNameForCxt, + genInstApp, + genWTKind, + genWTType, + ) import Primer.Name (NameCounter) import Primer.Primitives (primitiveModule) import Primer.Refine (Inst (InstAPP, InstApp, InstUnconstrainedAPP), refine) @@ -48,9 +48,9 @@ import Primer.Typecheck ( mkTAppCon, typeDefs, ) +import Tasty (Property, withDiscards) import Test.Tasty.HUnit (Assertion, (@?=)) import TestM (evalTestM) -import TestUtils (Property, withDiscards) import Tests.Gen.Core.Typed (propertyWTInExtendedLocalGlobalCxt, synthTest) defaultCxt :: Cxt diff --git a/primer/test/Tests/Typecheck.hs b/primer/test/Tests/Typecheck.hs index 46f3b24a1..99c5a9646 100644 --- a/primer/test/Tests/Typecheck.hs +++ b/primer/test/Tests/Typecheck.hs @@ -5,19 +5,6 @@ import Foreword import Control.Monad.Fresh (MonadFresh) import Data.Map qualified as Map -import Gen.App (genProg) -import Gen.Core.Raw ( - evalExprGen, - genTyConName, - genType, - ) -import Gen.Core.Typed ( - forAllT, - genChk, - genSyn, - genWTType, - propertyWT, - ) import Hedgehog hiding (Property, Var, check, property, withDiscards, withTests) import Hedgehog.Gen qualified as Gen import Hedgehog.Range qualified as Range @@ -83,6 +70,19 @@ import Primer.Core ( ) import Primer.Core.DSL import Primer.Core.Utils (alphaEqTy, forgetMetadata, forgetTypeMetadata, generateIDs, generateTypeIDs) +import Primer.Gen.App (genProg) +import Primer.Gen.Core.Raw ( + evalExprGen, + genTyConName, + genType, + ) +import Primer.Gen.Core.Typed ( + forAllT, + genChk, + genSyn, + genWTType, + propertyWT, + ) import Primer.Module import Primer.Name (Name, NameCounter) import Primer.Primitives (primitiveGVar, primitiveModule, tChar) @@ -103,15 +103,12 @@ import Primer.Typecheck ( synthKind, typeTtoType, ) +import Tasty (Property, property, withDiscards, withTests) import Test.Tasty.HUnit (Assertion, assertBool, assertFailure, (@?=)) import TestM (TestM, evalTestM) import TestUtils ( - Property, - property, tcn, vcn, - withDiscards, - withTests, zeroIDs, zeroTypeIDs, ) diff --git a/primer/test/Tests/Unification.hs b/primer/test/Tests/Unification.hs index 24a8d2278..cbac5b6f4 100644 --- a/primer/test/Tests/Unification.hs +++ b/primer/test/Tests/Unification.hs @@ -5,16 +5,6 @@ import Foreword hiding (diff) import Control.Monad.Fresh (MonadFresh) import Data.Map qualified as M import Data.Set qualified as S -import Gen.Core.Typed ( - WT, - forAllT, - freshLVarNameForCxt, - freshTyVarNameForCxt, - genCxtExtendingGlobal, - genWTKind, - genWTType, - propertyWT, - ) import Hedgehog ( GenT, PropertyT, @@ -37,6 +27,16 @@ import Primer.Core ( TypeDef (TypeDefAST), ) import Primer.Core.Utils (forgetTypeMetadata, freeVarsTy, generateTypeIDs) +import Primer.Gen.Core.Typed ( + WT, + forAllT, + freshLVarNameForCxt, + freshTyVarNameForCxt, + genCxtExtendingGlobal, + genWTKind, + genWTType, + propertyWT, + ) import Primer.Module (Module) import Primer.Name (NameCounter) import Primer.Primitives (primitiveModule, tInt) @@ -52,9 +52,10 @@ import Primer.Typecheck ( extendTypeDefCxt, ) import Primer.Unification (unify) +import Tasty (Property, withDiscards) import Test.Tasty.HUnit (Assertion, assertBool, (@?=)) import TestM (evalTestM) -import TestUtils (Property, tcn, withDiscards) +import TestUtils (tcn) import Tests.Gen.Core.Typed ( checkKindTest, checkValidContextTest, diff --git a/primer/test/Tests/Zipper.hs b/primer/test/Tests/Zipper.hs index a32254386..fcc64742c 100644 --- a/primer/test/Tests/Zipper.hs +++ b/primer/test/Tests/Zipper.hs @@ -4,16 +4,16 @@ module Tests.Zipper where import Foreword import Data.Generics.Uniplate.Data (para) -import Gen.Core.Raw ( +import Hedgehog hiding (Property, property) +import Hedgehog.Gen qualified as Gen +import Primer.Core +import Primer.Gen.Core.Raw ( evalExprGen, genExpr, runExprGen, ) -import Hedgehog hiding (Property, property) -import Hedgehog.Gen qualified as Gen -import Primer.Core import Primer.Zipper -import TestUtils (Property, property) +import Tasty (Property, property) -- | @unfocus . focus == id@ tasty_focus_unfocus_roundtrip :: Property