-
Notifications
You must be signed in to change notification settings - Fork 28
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 support for additional types, specified by user. #5
Comments
This would indeed be useful for situations where I don't want the conversion to occur (e.g. want to treat the values from the tables as strings). I could chip in on this, just let me know if there are any special requirements for building the project. |
@vzakanj I submitted PR #4 a while back that seems to relate to your comment - would generics fit the bill? I wanted to do exactly what you suggest as an example, treating values from tables as strings, even if they looked like another type. If you want to use any of that as a starting point for your own PR, please do. |
Hi, that sounds like a good idea! The PR in there now is pretty big (43 files touched and changed), can you use that as your base and make a smaller, more directed PR? Looking forward to something new in this old library. Happy that you are using it. |
@Lumirris @marcusoftnet generics wouldn't really be fitting for my use case because I'm currently writing specs for logic which reads a CSVfile, processes it and writes it back to another csv file. This process is generic meaning the CSV fields are detected on the fly, an ExpandoObject is created with properties which match the names of the CSV columns and it's processed further down the line to produce the resulting CSV. This means that I don't have a strongly typed class in this case, and would have to create a class which would correspond to the result of a single CSV processing - meaning I'd the number of these classes would match the number of different CSV entries. That being said I'd also either need different step definitions for each of these (each one calling the method with a different type) or use reflection to resolve the type param from a Specflow parameter and dynamically invoke the method with that type param. What would work better in my case is to either go with the solution @Friischling suggested (would need to get more acquainted with specflow code/structure to see how that would work - from what I can gather it boils down to registering converters with a DI container and then using them to convert data, otherwise fallback to default behavior), or have an overloads for CompareToDynamicSet/CompareToDynamicInstance/CreateDynamicSet/CreateDynamicInstance which takes in a collection of converters as an additional parameter. Any feedback on this would be great. Also, a few questions regarding the project:
|
Ok - I've read the comment now and I would suggest that you go with the DependencyInjection to register a new converter. Constructor DI is supported by SpecFlow out of the box so that would be pretty easy. However that is in the step definition class. The helper functions are defined on static class as extension methods, to show up nicely on the SpecFlow Table object. Getting that injected dependency to be visible and usable on the helper functions can be tricky, me thinks. One way could be to simple expose an property where you set the "converter" object in the step definitions. If nothing is set (i.e. the Converter property is null) we'll use my default conversion. I'm all for converting to 2015 (haven't touched this code in ages) but let's create a separate PR for that. |
Couldn't resist - fixed the VS2015 issue. |
Great, thanks! |
I looked at the implementation and it seems that method injection (passing the converters as an additional parameter) would fit most naturally here and here's why:
So my suggestion would be to have an overload for the existing extension methods which can take an IEnumerable (these would be ordered by conversion priority) or a single IValueConverter. Another option is to also add overloads with Func<string, object> so that the conversion logic can be specified inline for simple cases (i.e. no need for a separate class). So, method injection seems like the best fit given the current API, but let me know if you have any better ideas. |
Oh - me stupid. Been in JavaScript land for too long. No extension properties. Forgot about that. The solution sounds good - go for it! |
Hi, I'm having problems with the conversion of my table. I need to have only strings to compare this with a json message. Is it possible to override the CreateTypedValue method? Or do you have the alternative with CreateDynamicInstance ready? |
Hi @anniekvandijk - not entirely sure what you are looking for, but you can do quite a lot on your own with SpecFlow, even without the use of my library. Check out step argument conversion that is a very power feature that has helped me a lot. With it you can write stuff like: Given this JSON string '{}' and then write a generic conversion for all JSON string with: [Binding]
public class Transforms
{
[StepArgumentTransformation("JSON string '{}'"]
public IList<object> JSONTransform(string json)
{
// Do some funky transformation of the json parameter
// into an object structure (using, for example http://www.newtonsoft.com/json)
}
} I hope this helps you somewhat. Merry Christmas |
I created PR #21 which allows the user to optionally specify a custom property value parser. If not specified, the default property value parser will be used. For example:
It can then be used as follows:
Thank you. |
Closing this - too long ago... |
A nice addition, would be to allow the user to add custom converters to the type-conversion.
This would give the flexibility of the Dynamic but with the freedom of creating custom types whenever this is needed.
At the moment, only the types specified below is supported.
One could utilize the IObjectContainer to register additional converters, and this could be queried in the process below.
The text was updated successfully, but these errors were encountered: