allure-framework / allure-framework/allure-csharp

Allow an argument to match a type formatter by its interface/base class/generic definition

Open
#644 2 comments 1 reaction 0 assignees View on GitHub
enhancement
Dominant language
C#
Stars
125
Forks
76
Avg merge
1d 2h
Merged PRs (30d)
18

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:

1. Define a class that derives from `Allure.Net.Commons.TypeFormatter`.
2. Call `Allure.Net.Commons.AllureLifecycle.AddTypeFormatter(Allure.Net.Commons.TypeFormatter 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:

1. `T` must be known at compile time
2. `T` must be accessible
3. `T` must be the exact type of the value (i.e., `value.GetType() == typeof(T)` must be `true`)

This is cumbersome in the following situations:

1. `T` is a private or internal type of a 3rd party library
2. There are a lot of types we'd like to format similarly but have to call `AddTypeFormater` for 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:

1. `TypeFormatter`.
2. `TypeFormatter`, where `G` is a generic type definition of a (bound) generic type `T`.
3. `TypeFormatter`, where `I` is a type of an interface implemented by `T`.
4. `TypeFormatter`, where `IG` is a generic type definition of an interface implemented by `T`.
5. `TypeFormatter`, where `B` is a base class of `T`.
6. `TypeFormatter`, where `GB` is a generic type definition of the base class of `T`.

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.

Contributor guide

Open the contributing guide

Research direction

Start by locating AllureLifecycle.AddTypeFormatter and the dictionary used to match TypeFormatter instances. Review how test method arguments and attribute-based step arguments are converted, then implement the stated exact, generic, interface, and base-class matching order with caching. Done means formatters can match the listed broader type forms without registering every concrete type.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
testing
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.