cucumber-jvm icon indicating copy to clipboard operation
cucumber-jvm copied to clipboard

Allow to define a default DocTypeTransformer for each content type

Open driver733 opened this issue 2 years ago • 4 comments

🤔 What's the problem you're trying to solve?

I am trying to find a way to define a single common DocType transformer for a contentType, which would be able to transform the given docString to the given Type. Similarly to the way the @DefaultParameterTransformer and other @Default... transformers work. This is necessary in order to get pre-converted objects of the targetType in the test steps.

@Given("Step with a JSON DocString with type A")
public void step1(A a) {
        
}

@Given("Step with a JSON DocString with type B")
public void step1(B a) {

}

✨ What's your proposed solution?

Add an option to define a @DefaultDocTypeTransformer for a contentType.

@DefaultDocStringTransformer(contentType = "json")
public Object transformJsonDocString(String json, Type toValueType) throws JsonProcessingException {
    return objectMapper.readValue(json, objectMapper.constructType(toValueType));
}

It would also be useful to be able to define, a fallback transformer, which is used if no transformers have been found for the corresponding contentType.

@DefaultDocStringTypeTransformer
public Object convert(String contentType, String docString, Type toType) {
    return ...
}

⛏ Have you considered any alternatives or workarounds?

As of now it's necessary to define a DocType transformer for each of the targetTypes, which leads to writing a lot of transformer methods with the same code.

@DocStringType(contentType = "json")
public A transformToA(String json) throws JsonProcessingException {
    return objectMapper.readValue(json, A.class);
}

@DocStringType(contentType = "json")
public B transformToA(String json) throws JsonProcessingException {
    return objectMapper.readValue(json, B.class);
}

📚 Any additional context?

The way I see it is that the DocStringTypeRegistryDocStringConverter class will fallback to the @DefaultDocTypeTransformer(contentType = "X") for the given contentType if it fails to find a DocString transformer for the given pair of a contentType and targetType. If there is no @DefaultDocTypeTransformer(contentType = "X") for the given contenType then the DocStringTypeRegistryDocStringConverter will fallback to the @DefaultDocTypeTransformer, which can transform a DocString with any given contentType to the given targetType.

driver733 avatar Jun 21 '23 19:06 driver733