Skip to content

Commit 0492962

Browse files
committed
refactor: split a testing library
We split hedgehog generators, and some tasty glue into its own library (as part of the Primer package). We split these out to enable reuse of generators between primer and primer-service in the future. Note that whilst internal libraries are supported with cabal-version: 2.4, the ability to set visibility is only available from 3.0.
1 parent 148ebed commit 0492962

19 files changed

+158
-123
lines changed

primer/test/Gen/App.hs primer/gen/Primer/Gen/App.hs

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
-- |
66
-- This module generates well-typed 'Prog's
77
-- It is however, slow and the distribution is not very even.
8-
module Gen.App (
8+
module Primer.Gen.App (
99
genProg,
1010
) where
1111

@@ -16,7 +16,7 @@ import Primer.Module (Module (Module, moduleDefs, moduleName, moduleTypes), modu
1616
import Primer.Name (Name, unsafeMkName)
1717
import Primer.Typecheck (Cxt, SmartHoles, extendGlobalCxt, extendTypeDefCxt)
1818

19-
import Gen.Core.Typed (WT, freshNameForCxt, genChk, genTypeDefGroup, genWTType)
19+
import Primer.Gen.Core.Typed (WT, freshNameForCxt, genChk, genTypeDefGroup, genWTType)
2020

2121
import Hedgehog (GenT, MonadGen)
2222
import Hedgehog.Gen qualified as Gen
@@ -57,7 +57,7 @@ genProg sh initialImports = local (extendCxtByModules initialImports) $ do
5757
. extendGlobalCxt (M.toList . fmap (forgetTypeMetadata . defType) $ foldMap moduleDefsQualified ms)
5858
genModule :: Name -> Int -> GenT WT Module
5959
genModule prefix index = do
60-
let mn = ModuleName [prefix, unsafeMkName $ show index]
60+
let mn = ModuleName $ prefix :| [unsafeMkName $ show index]
6161
tds <- genTypeDefGroup $ Just mn
6262
defs <- local (extendTypeDefCxt $ M.fromList tds) (genASTDefGroup mn)
6363
pure $

primer/test/Gen/Core/Raw.hs primer/gen/Primer/Gen/Core/Raw.hs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
-- That is, syntax trees which are not (necessarily) well-typed, or even well-scoped.
44
-- It is however, fast and has good coverage properties.
55
--
6-
-- For generating well-typed terms, see "Gen.Core.Typed".
7-
module Gen.Core.Raw (
6+
-- For generating well-typed terms, see "Primer.Gen.Core.Typed".
7+
module Primer.Gen.Core.Raw (
88
runExprGen,
99
evalExprGen,
1010
genID,

primer/test/Gen/Core/Typed.hs primer/gen/Primer/Gen/Core/Typed.hs

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
-- This module generates well-typed terms and types.
77
-- It is however, slow and the distribution is not very even.
88
--
9-
-- For quickly generating non-well-typed-or-scoped terms, see "Gen.Core.Raw".
10-
module Gen.Core.Typed (
9+
-- For quickly generating non-well-typed-or-scoped terms, see "Primer.Gen.Core.Raw".
10+
module Primer.Gen.Core.Typed (
1111
WT,
1212
isolateWT,
1313
genWTType,
@@ -33,7 +33,6 @@ import Control.Monad.Fresh (MonadFresh, fresh)
3333
import Control.Monad.Morph (hoist)
3434
import Control.Monad.Reader (mapReaderT)
3535
import Data.Map qualified as M
36-
import Gen.Core.Raw (genLVarName, genModuleName, genName, genTyVarName)
3736
import Hedgehog (
3837
GenT,
3938
MonadGen,
@@ -69,6 +68,7 @@ import Primer.Core (
6968
valConType,
7069
)
7170
import Primer.Core.Utils (freeVarsTy)
71+
import Primer.Gen.Core.Raw (genLVarName, genModuleName, genName, genTyVarName)
7272
import Primer.Module (Module (..))
7373
import Primer.Name (Name, NameCounter, freshName, unName, unsafeMkName)
7474
import Primer.Refine (Inst (InstAPP, InstApp, InstUnconstrainedAPP), refine)
@@ -96,8 +96,8 @@ import Primer.Typecheck (
9696
primConInScope,
9797
typeDefs,
9898
)
99+
import Tasty (Property, property)
99100
import TestM (TestM, evalTestM, isolateTestM)
100-
import TestUtils (Property, property)
101101

102102
{-
103103
Generate well scoped and typed expressions.

primer/gen/Tasty.hs

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
module Tasty (Property, property, withTests, withDiscards) where
2+
3+
import Data.Coerce (coerce)
4+
import Data.String (fromString)
5+
import Hedgehog qualified as H
6+
import Test.Tasty.Discover qualified as TD
7+
import Test.Tasty.Hedgehog qualified as TH
8+
9+
import Foreword
10+
11+
-- | Work around tasty changes which give deprecation warnings for tasty-discover generated code
12+
newtype Property = Property
13+
{ unProperty :: H.Property
14+
}
15+
16+
instance TD.Tasty Property where
17+
tasty info =
18+
pure
19+
. TH.testPropertyNamed (TD.descriptionOf info) (fromString (TD.descriptionOf info))
20+
. unProperty
21+
22+
property :: HasCallStack => H.PropertyT IO () -> Property
23+
property = Property . H.property
24+
25+
withTests :: H.TestLimit -> Property -> Property
26+
withTests = coerce H.withTests
27+
28+
withDiscards :: H.DiscardLimit -> Property -> Property
29+
withDiscards = coerce H.withDiscards
File renamed without changes.

primer/primer.cabal

+36-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
cabal-version: 2.4
1+
cabal-version: 3.0
22
name: primer
33
version: 0.7.2.0
44
license: AGPL-3.0-or-later
@@ -88,15 +88,45 @@ library
8888
, uniplate >=1.6 && <=1.7
8989
, uuid >=1.3 && <=1.4
9090

91+
library primer-hedgehog
92+
visibility: public
93+
exposed-modules:
94+
Primer.Gen.App
95+
Primer.Gen.Core.Raw
96+
Primer.Gen.Core.Typed
97+
Tasty
98+
TestM
99+
100+
other-modules:
101+
hs-source-dirs: gen
102+
default-language: GHC2021
103+
default-extensions:
104+
NoImplicitPrelude
105+
DataKinds
106+
DerivingStrategies
107+
DerivingVia
108+
LambdaCase
109+
OverloadedStrings
110+
111+
ghc-options:
112+
-Wall -Wincomplete-uni-patterns -Wincomplete-record-updates
113+
-Wcompat -Widentities -Wredundant-constraints -fhide-source-paths
114+
115+
build-depends:
116+
, base
117+
, containers
118+
, hedgehog ^>=1.1.1
119+
, mmorph ^>=1.2.0
120+
, mtl
121+
, primer
122+
, tasty-discover ^>=4.2.4
123+
, tasty-hedgehog ^>=1.2.0
124+
91125
test-suite primer-test
92126
type: exitcode-stdio-1.0
93127
main-is: Test.hs
94128
hs-source-dirs: test
95129
other-modules:
96-
Gen.App
97-
Gen.Core.Raw
98-
Gen.Core.Typed
99-
TestM
100130
Tests.Action
101131
Tests.Action.Available
102132
Tests.Action.Capture
@@ -169,6 +199,7 @@ test-suite primer-test
169199
, prettyprinter >=1.7.1 && <=1.8
170200
, prettyprinter-ansi-terminal >=1.1.3 && <=1.2
171201
, primer
202+
, primer-hedgehog
172203
, protolude
173204
, stm
174205
, stm-containers

primer/test/TestUtils.hs

+1-29
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@ module TestUtils (
1414
zeroTypeIDs,
1515
clearMeta,
1616
clearTypeMeta,
17-
Property,
18-
property,
19-
withTests,
20-
withDiscards,
2117
runAPI,
2218
) where
2319

@@ -27,10 +23,8 @@ import Control.Concurrent.STM (
2723
newTBQueueIO,
2824
)
2925
import Control.Monad.Fresh (MonadFresh)
30-
import Data.Coerce (coerce)
31-
import Data.String (String, fromString)
26+
import Data.String (String)
3227
import Data.Typeable (typeOf)
33-
import Hedgehog qualified as H
3428
import Optics (over, set, view)
3529
import Primer.API (
3630
Env (..),
@@ -71,13 +65,11 @@ import Primer.Database (
7165
import Primer.Name (Name (unName))
7266
import Primer.Primitives (allPrimDefs)
7367
import StmContainers.Map qualified as StmMap
74-
import Test.Tasty.Discover qualified as TD
7568
import Test.Tasty.HUnit (
7669
assertBool,
7770
assertFailure,
7871
)
7972
import Test.Tasty.HUnit qualified as HUnit
80-
import Test.Tasty.Hedgehog qualified as TH
8173

8274
withPrimDefs :: MonadFresh ID m => (Map GVarName PrimDef -> m a) -> m a
8375
withPrimDefs f = do
@@ -143,26 +135,6 @@ assertException msg p action = do
143135
wrongException e = msg <> " threw " <> show e <> ", but we expected " <> exceptionType
144136
exceptionType = (show . typeOf) p
145137

146-
-- | Work around tasty changes which give deprecation warnings for tasty-discover generated code
147-
newtype Property = Property
148-
{ unProperty :: H.Property
149-
}
150-
151-
instance TD.Tasty Property where
152-
tasty info =
153-
pure
154-
. TH.testPropertyNamed (TD.descriptionOf info) (fromString (TD.descriptionOf info))
155-
. unProperty
156-
157-
property :: HasCallStack => H.PropertyT IO () -> Property
158-
property = Property . H.property
159-
160-
withTests :: H.TestLimit -> Property -> Property
161-
withTests = coerce H.withTests
162-
163-
withDiscards :: H.DiscardLimit -> Property -> Property
164-
withDiscards = coerce H.withDiscards
165-
166138
-- Run 2 threads: one that serves a 'NullDb', and one that runs Primer
167139
-- API actions. This allows us to simulate a database and API service.
168140
--

primer/test/Tests/API.hs

+5-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import Foreword
55
import Data.ByteString.Lazy qualified as BSL
66
import Data.Text.Lazy qualified as TL
77
import Data.UUID.V4 (nextRandom)
8-
import Gen.Core.Raw (evalExprGen, genExpr, genType)
98
import Hedgehog hiding (Property, property)
109
import Primer.API (
1110
PrimerErr,
@@ -37,15 +36,18 @@ import Primer.Examples (
3736
comprehensive,
3837
even3App,
3938
)
39+
import Primer.Gen.Core.Raw (evalExprGen, genExpr, genType)
4040
import Protolude.Unsafe (unsafeFromJust)
41+
import Tasty (
42+
Property,
43+
property,
44+
)
4145
import Test.Tasty (TestTree, testGroup)
4246
import Test.Tasty.Golden (goldenVsString)
4347
import Test.Tasty.HUnit hiding ((@?=))
4448
import TestUtils (
4549
ExceptionPredicate,
46-
Property,
4750
assertException,
48-
property,
4951
runAPI,
5052
(@?=),
5153
)

primer/test/Tests/Action.hs

+6-5
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,6 @@ import Foreword
55

66
import Data.Data (Data)
77
import Data.Generics.Uniplate.Data (universe)
8-
import Gen.Core.Raw (
9-
evalExprGen,
10-
genExpr,
11-
)
128
import Hedgehog hiding (
139
Action,
1410
Property,
@@ -32,6 +28,10 @@ import Primer.Core (
3228
getID,
3329
)
3430
import Primer.Core.DSL
31+
import Primer.Gen.Core.Raw (
32+
evalExprGen,
33+
genExpr,
34+
)
3535
import Primer.Typecheck (SmartHoles (NoSmartHoles, SmartHoles))
3636
import Primer.Zipper (
3737
down,
@@ -41,9 +41,10 @@ import Primer.Zipper (
4141
unfocusExpr,
4242
unfocusType,
4343
)
44+
import Tasty (Property, property)
4445
import Test.Tasty.HUnit (Assertion, assertFailure, (@?=))
4546
import TestM (evalTestM)
46-
import TestUtils (Property, clearMeta, constructCon, constructRefinedCon, constructTCon, property)
47+
import TestUtils (clearMeta, constructCon, constructRefinedCon, constructTCon)
4748

4849
-- Note: 'maximum' is partial, but we believe that 'maxID' itself is
4950
-- safe due to the fact that 'universe x' always contains at least

primer/test/Tests/AlphaEquality.hs

+6-6
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,6 @@ module Tests.AlphaEquality where
22

33
import Foreword
44

5-
import Gen.Core.Raw (
6-
evalExprGen,
7-
genTyVarName,
8-
genType,
9-
)
105
import Hedgehog hiding (Property, check, property)
116
import Primer.Builtins
127
import Primer.Core (
@@ -15,8 +10,13 @@ import Primer.Core (
1510
)
1611
import Primer.Core.DSL
1712
import Primer.Core.Utils (alphaEqTy, forgetTypeMetadata)
13+
import Primer.Gen.Core.Raw (
14+
evalExprGen,
15+
genTyVarName,
16+
genType,
17+
)
18+
import Tasty (Property, property)
1819
import Test.Tasty.HUnit hiding (assert)
19-
import TestUtils (Property, property)
2020

2121
unit_1 :: Assertion
2222
unit_1 =

primer/test/Tests/EvalFull.hs

+7-5
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import Data.Map qualified as M
99
import Data.Map qualified as Map
1010
import Data.Set qualified as S
1111
import Data.String (unlines)
12-
import Gen.Core.Typed (WT, forAllT, genChk, genSyn, genWTType, isolateWT, propertyWT)
1312
import Hedgehog hiding (Property, Var, check, property, test, withDiscards, withTests)
1413
import Hedgehog.Gen qualified as Gen
1514
import Hedgehog.Internal.Property (LabelName (unLabelName))
@@ -53,6 +52,7 @@ import Primer.Examples qualified as Examples (
5352
map',
5453
odd,
5554
)
55+
import Primer.Gen.Core.Typed (WT, forAllT, genChk, genSyn, genWTType, isolateWT, propertyWT)
5656
import Primer.Module (Module (Module, moduleDefs, moduleName, moduleTypes), moduleDefsQualified, moduleTypesQualified)
5757
import Primer.Name (Name)
5858
import Primer.Primitives (primitiveGVar, primitiveModule, tChar, tInt)
@@ -62,14 +62,16 @@ import Primer.Typecheck (
6262
extendGlobalCxt,
6363
typeDefs,
6464
)
65-
import Test.Tasty.HUnit (Assertion, assertBool, assertFailure, (@?=))
66-
import TestM
67-
import TestUtils (
65+
import Tasty (
6866
Property,
6967
property,
7068
withDiscards,
71-
withPrimDefs,
7269
withTests,
70+
)
71+
import Test.Tasty.HUnit (Assertion, assertBool, assertFailure, (@?=))
72+
import TestM
73+
import TestUtils (
74+
withPrimDefs,
7375
zeroIDs,
7476
)
7577
import Tests.Action.Prog (runAppTestM)

primer/test/Tests/Gen/App.hs

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,20 @@
44
module Tests.Gen.App where
55

66
import Foreword
7-
import Gen.App (genProg)
8-
import Gen.Core.Typed (
9-
propertyWT,
10-
)
117
import Hedgehog (
128
annotateShow,
139
failure,
1410
)
1511
import Hedgehog.Internal.Property (forAllT)
1612
import Primer.App (checkProgWellFormed)
1713
import Primer.Builtins (builtinModule)
14+
import Primer.Gen.App (genProg)
15+
import Primer.Gen.Core.Typed (
16+
propertyWT,
17+
)
1818
import Primer.Primitives (primitiveModule)
1919
import Primer.Typecheck (SmartHoles (NoSmartHoles), TypeError)
20-
import TestUtils (Property, withDiscards, withTests)
20+
import Tasty (Property, withDiscards, withTests)
2121

2222
tasty_genProg_well_formed :: Property
2323
tasty_genProg_well_formed = withTests 1000 $

0 commit comments

Comments
 (0)