Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding useful types to AutoGenConfig #59

Closed
AlexeyRaga opened this issue Sep 23, 2021 · 4 comments
Closed

Adding useful types to AutoGenConfig #59

AlexeyRaga opened this issue Sep 23, 2021 · 4 comments

Comments

@AlexeyRaga
Copy link
Contributor

Similarly to what FSCheck is doing

Can we consider adding types like:

NegativeInt
NonNegativeInt
PositiveInt
NonZeroInt
NormalFloat
NonEmptyString
StringNoNulls
NonWhiteSpaceString
XmlEncodedString
UnicodeChar
UnicodeString
Interval
IntWithMinMax
NonEmptySet
NonEmptyArray
FixedLengthArray

to AutoGenConfig so that they are available by default?

I know that they can be defined separately and configured via Property attribute, but since they are very generic and very useful having them "out-of-the-box" would be extremely convenient...

@cmeeren
Copy link
Collaborator

cmeeren commented Sep 23, 2021

Based on #60, I assume you're using Hedgehog from C#. I don't know how that works. The following is from an F# perspective. In any case, this repo will likely soon be merged into the main Hedgehog repo. I'll leave this decision for them.


Why not just add generators like Gen.negativeInt, Gen.nonNegativeInt etc.? That seems like it would be more useful in Hedgehog. In FsCheck, you don't control the generators directly, so you have to use those types. In Hedgehog, you combine primitive generators to make your own that generate exactly what you want for any type.

Also, I am wondering how this would help in Gen.auto. I can understand wanting to create one individually, but the way I see it, the benefit of Gen.auto is being able to automatically generate compositional types like records, DUs etc. These would typically be defined in your domain code. Therefore, you of course don't use those types you mention, since they originate from a testing library.

@AlexeyRaga
Copy link
Contributor Author

AlexeyRaga commented Sep 24, 2021

Based on #60, I assume you're using Hedgehog from C#

No, it was F# this time ;)
But I am using it with Hedgehog.XUnit, where you kind of don't control generators directly too...

I'd say that in FSCheck they are even more controllable/plugable because you can specify multiple of them in [<Property>] attribute:

[<Property( Arbitrary=[| typeof<PositiveInt>; typeof<NonEmptyString> |] )>]

so FSCheck can go "a la card", while in HH we'd gave to come up with a config type that adds all the necessary generators to the default config and then use it. Hence, new combination of gens -> new type required.... But it is a different story ;)

but the way I see it, the benefit of Gen.auto is being able to automatically generate compositional types like records, DUs etc

Absolutely. And this power is not taken away with adding these types. As I said, they are kind of a convenience thing, not more..

@TysonMN
Copy link
Member

TysonMN commented Sep 24, 2021

But I am using it with Hedgehog.XUnit

I thought so.

I'd say that in FSCheck they are even more controllable/plugable because you can specify multiple of them in [<Property>] attribute:

Can you create an issue about this in the GutHub repository for Hedgehog.XUnit?

@dharmaturtle
Copy link
Member

+1 to what cmeeren said:

These would typically be defined in your domain code.

(Also feel free to unsubscribe from this thread cmeeren!)

Hedgehog.Xunit pretty much forces you to separate the construction of test generators from the normal test code. My personal project's Hedgehog.fs file builds up all my domain objects and makes heavy usage of the default combinators (e.g. here). To again echo what cmereen said, adding a combinator like Gen.negativeInt makes more sense to me, because then I get to compose it with other functions like Gen.filter. Functions compose easily, whereas with composition with types is... not practical.

Here's a Hedgehog.Xunit test of mine that can serve as an example. (The testing in this repository is ugly as sin - please for the love of all that's holy don't copy what I do. I'm only using it as an example of "real world" usage.) The test generates 3 args of types User.Events.Event, User, and Template:

  1. User.Events.Event is registered here.
  2. All the test needs from User is for its Id to be different from the Id in User.Events.Event, so GenX.auto's default behavior is sufficient
  3. Template isn't used for anything but making the compiler happy, so again GenX.auto is fine.

Since the domain objects are constructed elsewhere, the business tests that I write don't really need a naked "positive integer" injected into them - they mostly only ask for correct domain objects. I'm curious what circumstance you're in that necessitates the injection of something like PositiveInt. Can you give a semi-real-world example/usage of something like PositiveInt?

I recognize that this comment sounds negative, but I am very willing to have my mind changed! Please don't hesitate to push back.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants