Skip to content

Commit 6b22345

Browse files
committed
[Core] Look up docstring converter by type as fallback
Fixes: #2458
1 parent 0364976 commit 6b22345

File tree

4 files changed

+79
-5
lines changed

4 files changed

+79
-5
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1616
### Removed
1717

1818
### Fixed
19+
* [Core] Look up docstring converter by type as fallback ([#2459](https://github.com/cucumber/cucumber-jvm/pull/2459) M.P. Korstanje)
1920

2021
## [7.2.1] (2022-01-04)
2122

docstring/src/main/java/io/cucumber/docstring/DocStringTypeRegistry.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,11 @@ List<DocStringType> lookup(String contentType, Type type) {
5656
}
5757

5858
DocStringType docStringType = lookupByContentTypeAndType(contentType, type);
59-
if (docStringType == null) {
60-
return Collections.emptyList();
59+
if (docStringType != null) {
60+
return Collections.singletonList(docStringType);
6161
}
62-
return Collections.singletonList(docStringType);
62+
63+
return lookUpByType(type);
6364
}
6465

6566
private List<DocStringType> lookUpByType(Type type) {

docstring/src/main/java/io/cucumber/docstring/DocStringTypeRegistryDocStringConverter.java

+17-2
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,25 @@ public <T> T convert(DocString docString, Type targetType) {
3939
targetType.getTypeName()));
4040
}
4141
if (docStringTypes.size() > 1) {
42+
List<String> suggestedContentTypes = suggestedContentTypes(docStringTypes);
43+
if (docString.getContentType() == null) {
44+
if (suggestedContentTypes.size() > 1) {
45+
throw new CucumberDocStringException(format(
46+
"Multiple converters found for type %s, add one of the following content types to your docstring %s",
47+
targetType.getTypeName(),
48+
suggestedContentTypes));
49+
}
50+
throw new CucumberDocStringException(format(
51+
"In addition to the default converter a converter was found for type %s. The docstring not not declare an explicit content type. Change the content type of the docstring to '%s' to use this converter.",
52+
targetType.getTypeName(),
53+
suggestedContentTypes.get(0)));
54+
}
4255
throw new CucumberDocStringException(format(
43-
"Multiple converters found for type %s, add one of the following content types to your docstring %s",
56+
"Multiple converters found for type %s, and the content type '%s' did not match any of the registered types %s. Change the content type of the docstring or register a docstring type for '%s'",
4457
targetType.getTypeName(),
45-
suggestedContentTypes(docStringTypes)));
58+
docString.getContentType(),
59+
suggestedContentTypes,
60+
docString.getContentType()));
4661
}
4762

4863
return (T) docStringTypes.get(0).transform(docString.getContent());

docstring/src/test/java/io/cucumber/docstring/DocStringTypeRegistryDocStringConverterTest.java

+57
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,63 @@ void target_type_to_string_is_predefined() {
6060
assertThat(converted, is("hello world"));
6161
}
6262

63+
@Test
64+
void default_converter_is_used_if_registered_converter_does_not_match_type() {
65+
registry.defineDocStringType(new DocStringType(
66+
JsonNode.class,
67+
"json",
68+
(String s) -> new ObjectMapper().readTree(s)));
69+
70+
DocString docString = DocString.create(
71+
"hello world", "json");
72+
73+
String converted = converter.convert(docString, String.class);
74+
assertThat(converted, is("hello world"));
75+
}
76+
77+
@Test
78+
void throws_if_default_converter_conflicts_with_registered_converter_for_string() {
79+
registry.defineDocStringType(new DocStringType(
80+
String.class,
81+
"text",
82+
(String s) -> s));
83+
84+
DocString docString = DocString.create("hello world");
85+
86+
CucumberDocStringException exception = assertThrows(
87+
CucumberDocStringException.class,
88+
() -> converter.convert(docString, String.class));
89+
90+
assertThat(exception.getMessage(),
91+
is("In addition to the default converter a converter was found for type java.lang.String. " +
92+
"The docstring not not declare an explicit content type. Change the content type of the " +
93+
"docstring to 'text' to use this converter."));
94+
}
95+
96+
@Test
97+
void throws_if_converter_type_conflicts_with_type() {
98+
registry.defineDocStringType(new DocStringType(
99+
JsonNode.class,
100+
"json",
101+
(String s) -> new ObjectMapper().readTree(s)));
102+
103+
registry.defineDocStringType(new DocStringType(
104+
String.class,
105+
"text",
106+
(String s) -> s));
107+
108+
DocString docString = DocString.create("hello world", "json");
109+
110+
CucumberDocStringException exception = assertThrows(
111+
CucumberDocStringException.class,
112+
() -> converter.convert(docString, String.class));
113+
114+
assertThat(exception.getMessage(),
115+
is("Multiple converters found for type java.lang.String, and the content type 'json' " +
116+
"did not match any of the registered types [text]. Change the content type of the docstring " +
117+
"or register a docstring type for 'json'"));
118+
}
119+
63120
@Test
64121
void converts_doc_string_to_doc_string() {
65122
DocString docString = DocString.create(

0 commit comments

Comments
 (0)