Skip to content
This repository was archived by the owner on Nov 27, 2025. It is now read-only.

Commit 82fc92e

Browse files
authored
Merge pull request #80 from hedgehogqa/register-generators
addGenerators to ignore methods it doesn't understand instead of failing
2 parents bf62430 + 27d6c15 commit 82fc92e

File tree

1 file changed

+25
-27
lines changed
  • src/Hedgehog.Experimental

1 file changed

+25
-27
lines changed

src/Hedgehog.Experimental/Gen.fs

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -57,35 +57,33 @@ module AutoGenConfig =
5757
/// The type is expected to have static methods that return Gen<'a>.
5858
/// These methods can have parameters which are required to be of type Gen<_>.
5959
let addGenerators<'a> (config: AutoGenConfig) =
60-
let isGen (t: Type) = t.IsGenericType && t.GetGenericTypeDefinition() = typedefof<Gen<_>>
61-
62-
// Ensure that all the parameters are of type Gen<_>, and return the unwrapped types.
63-
let unwrapGenParameters (methodInfo: MethodInfo) : Type[] =
64-
methodInfo.GetParameters()
65-
|> Array.map (fun param ->
66-
if isGen param.ParameterType then
67-
param.ParameterType.GetGenericArguments()[0]
68-
else
69-
failwithf "Method %s.%s has a parameter '%s' which is not of type Gen<...>"
70-
methodInfo.DeclaringType.Name
71-
methodInfo.Name
72-
param.Name)
60+
let isGen (t: Type) =
61+
t.IsGenericType && t.GetGenericTypeDefinition() = typedefof<Gen<_>>
62+
63+
let tryUnwrapGenParameters (methodInfo: MethodInfo) : Option<Type[]> =
64+
methodInfo.GetParameters()
65+
|> Array.fold (fun acc param ->
66+
match acc, isGen param.ParameterType with
67+
| Some types, true ->
68+
Some (Array.append types [| param.ParameterType.GetGenericArguments().[0] |])
69+
| _ -> None
70+
) (Some [||])
7371

74-
// find all the static methods that return Gen<'a>
75-
let methods =
7672
typeof<'a>.GetMethods(BindingFlags.Static ||| BindingFlags.Public)
77-
|> Seq.filter (fun m -> isGen m.ReturnType)
78-
79-
// Register these methods as generator factories
80-
methods
81-
|> Seq.fold (fun cfg methodInfo ->
82-
let targetType = methodInfo.ReturnType.GetGenericArguments()[0]
83-
let typeArray = unwrapGenParameters methodInfo
84-
let factory: Type[] -> obj[] -> obj = fun types gens ->
85-
let methodToCall = if Array.isEmpty types then methodInfo else methodInfo.MakeGenericMethod(types)
86-
methodToCall.Invoke(null, gens)
87-
cfg |> mapGenerators (GeneratorCollection.addGenerator targetType typeArray factory)
88-
) config
73+
|> Seq.choose (fun methodInfo ->
74+
match isGen methodInfo.ReturnType, tryUnwrapGenParameters methodInfo with
75+
| true, Some typeArray ->
76+
let targetType = methodInfo.ReturnType.GetGenericArguments().[0]
77+
let factory: Type[] -> obj[] -> obj = fun types gens ->
78+
let methodToCall =
79+
if Array.isEmpty types then methodInfo
80+
else methodInfo.MakeGenericMethod(types)
81+
methodToCall.Invoke(null, gens)
82+
Some (targetType, typeArray, factory)
83+
| _ -> None)
84+
|> Seq.fold (fun cfg (targetType, typeArray, factory) ->
85+
cfg |> mapGenerators (GeneratorCollection.addGenerator targetType typeArray factory))
86+
config
8987

9088
module GenX =
9189

0 commit comments

Comments
 (0)