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

Add ability to override custom types in auto-generator #19

Closed
cmeeren opened this issue Nov 19, 2017 · 16 comments · Fixed by #43
Closed

Add ability to override custom types in auto-generator #19

cmeeren opened this issue Nov 19, 2017 · 16 comments · Fixed by #43

Comments

@cmeeren
Copy link
Collaborator

cmeeren commented Nov 19, 2017

It would be great if the user could specify overrides for any complex type they desire. For example, say Customer is a type that has a field of type Customer list (sub-customers of the current customer). This is recursive and (currently) needs a specifically designed generator to avoid stack overflow. Say then that I want to generate an Order type which, among other things, contains a Customer, then I'd want to just say auto<Order>(...) and somehow specify that I want Customer objects to be generated using my specific generator, and otherwise the defaults are fine.

I'm not sure how to do this though, or if it is easy/feasible/possible.

@cmeeren cmeeren changed the title Add ability to override custom types in auto.gen Add ability to override custom types in auto-generator Nov 19, 2017
@cmeeren
Copy link
Collaborator Author

cmeeren commented Jan 8, 2018

Any thoughts on this?

@moodmosaic
Copy link
Member

I apologize for the delay, I've been busy. I'll get back to this soon. /cc @jystic

@moodmosaic
Copy link
Member

moodmosaic commented Jan 9, 2018

There should be quite a few ways of doing this, and I think I'm not convinced with any of them:

@moodmosaic
Copy link
Member

I'd start looking for the most type safe approach which immediately excludes the emulation of Haskell typeclasses and the dictionary lookup.

@cmeeren
Copy link
Collaborator Author

cmeeren commented Jan 23, 2018

I haven't thought too hard on this, but recursively auto-generating custom types seems inherently un-typesafe to me. How could it be made type-safe? Could you share an example?

@cmeeren
Copy link
Collaborator Author

cmeeren commented Jan 23, 2018

Hmm, I just thought of another way to solve the specific problem of stack overflow when auto-generating recursive types (which is the main reason I wanted this override functionality in the first place).

We can add a recursionDepth: int parameter to the config. An inner auto function can get passed a Map<System.Type, int> that describes how many times the given type has recursed. When it reaches the recursion depth, it will as far as possible stop generating these (e.g. None if it's an option of that type, or empty list if it's a list of that type).

For example, say we have a Customer with a list of child customers also of the type Customer. We generate this with a recursion depth of 1. For each sub-type it generates, it checks the map to see how many times it has recursed. Initially of course, the map won't contain the Customer type key (i.e., recursed zero times). So now it adds Customer to the map with the value 1, and generates a list of sub-customers, passing along the modified map. When this auto call gets to the same Customer list generation, it'll see that Customer has recursed once, and the recursion limit (from the config) is 1, so it'll generate an empty list.

What do you think?

@cmeeren
Copy link
Collaborator Author

cmeeren commented Jan 23, 2018

Nearly finished with an implementation of what I described above. Seems to work brilliantly. Will create a PR when I'm done, need to test it thoroughly.

@moodmosaic
Copy link
Member

On mobile right now, but looking forward to your PR.

@dharmaturtle
Copy link
Member

I'm interested in this feature. In my case, attempting to auto NodaTime's Instant yields "System.Exception: Class NodaTime.Instant lacking an appropriate ctor". Since my application uses Instant liberally (it's analogous to System.DateTime or System.DateTimeOffset), creating handcrafted generators for each type is annoying.

Of the 5 options given, I feel like I only understand the dictionary approach. I'd pass a list of Generators as a new field on AutoGenConfig, then use reflection to create an internal dictionary.

@moodmosaic have your thoughts evolved on this issue?

@cmeeren
Copy link
Collaborator Author

cmeeren commented Dec 9, 2020

I'd pass a list of Generators as a new field on AutoGenConfig, then use reflection to create an internal dictionary.

How does reflection enter into the picture? Are you talking about using reflection to obtain a list of the defined generators in the test library, and fill a dictionary with those?


@moodmosaic I don't see any important downsides to the dictionary approach. Could you elaborate, if you still hold this position? The only "downside" I can see is that the user, when using auto, has no guarantees about the contents of the config (specifically the custom generator map), and therefore isn't guaranteed that their custom configs are actually used. But I don't see how that can be guaranteed no matter which solution is used.

@moodmosaic
Copy link
Member

I can't remember (it's been ~3 years) but it seems strange to me right now why I excluded the dictionary approach.

(I could understand that excluding the typeclass emulation sounds reasonable.)

I'd just go with the dictionary approach now.

@TysonMN
Copy link
Member

TysonMN commented Dec 11, 2020

I think this functionality would provide a workaround for hedgehogqa/fsharp-hedgehog#249.

@moodmosaic
Copy link
Member

Yep. (Though I think we ought to provide out-of-the-box primitive generators.)

@TysonMN
Copy link
Member

TysonMN commented Dec 11, 2020

Agree. I just think it is interesting to see the connection.

@moodmosaic
Copy link
Member

So in this case the user would pass the generator for that type through the dictionary.

@cmeeren
Copy link
Collaborator Author

cmeeren commented Dec 11, 2020

I hope to have implemented this feature during the weekend. I will make a PR so you can have a look at it.

Also I think I'll wait with releasing a new version until hedgehogqa/fsharp-hedgehog#249 is fixed, so I can include changes that depend on that, too (specifically, adding support for single and decimal to the auto-generator).

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

Successfully merging a pull request may close this issue.

4 participants