-
Notifications
You must be signed in to change notification settings - Fork 67
Description
The type formatters API allows users to provide their own serialization algorithms to format arguments of certain types. To do so, two things are required:
- Define a class that derives from
Allure.Net.Commons.TypeFormatter<T>. - Call
Allure.Net.Commons.AllureLifecycle.AddTypeFormatter<T>(Allure.Net.Commons.TypeFormatter<T> formatter)early enough for the formatter to be picked up by Allure.
If everything is done right, Allure will use the formatter to convert arguments of the matched type to strings in two contexts:
- when converting test method arguments to strings (usually, at test end)
- when convertins arguments of attribute-based steps at step end
Limitations
If we'd like to format a value of type T, then:
Tmust be known at compile timeTmust be accessibleTmust be the exact type of the value (i.e.,value.GetType() == typeof(T)must betrue)
This is cumbersome in the following situations:
Tis a private or internal type of a 3rd party library- There are a lot of types we'd like to format similarly but have to call
AddTypeFormaterfor each of them anyway.
Solution
A solution is to make the matching algorithm less restrictive. We can try to find a match in the following order:
TypeFormatter<T>.TypeFormatter<G>, whereGis a generic type definition of a (bound) generic typeT.TypeFormatter<I>, whereIis a type of an interface implemented byT.TypeFormatter<IG>, whereIGis a generic type definition of an interface implemented byT.TypeFormatter<B>, whereBis a base class ofT.TypeFormatter<GB>, whereGBis a generic type definition of the base class ofT.
Options 2, 4, and 6 require a new AddTypeFormatter overload since these formatters can't be added with the existing one.
Options 5 and 6 apply repeatedly until we reach System.Object.
If the match result is found, we can cache it by adding the [value.GetType(), formatter] entry to the dictionary of formatters.