ApplicationConversionServiceTests Class — spring-boot Architecture
Architecture documentation for the ApplicationConversionServiceTests class in ApplicationConversionServiceTests.java from the spring-boot codebase.
Entity Profile
Source Code
core/spring-boot/src/test/java/org/springframework/boot/convert/ApplicationConversionServiceTests.java lines 67–431
class ApplicationConversionServiceTests {
private final FormatterRegistry registry = mock(FormatterRegistry.class,
withSettings().extraInterfaces(ConversionService.class));
@Test
void addBeansWhenHasGenericConverterBeanAddConverter() {
try (ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(
ExampleGenericConverter.class)) {
ApplicationConversionService.addBeans(this.registry, context);
then(this.registry).should().addConverter(context.getBean(ExampleGenericConverter.class));
then(this.registry).shouldHaveNoMoreInteractions();
}
}
@Test
void addBeansWhenHasConverterBeanAddConverter() {
try (ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(ExampleConverter.class)) {
ApplicationConversionService.addBeans(this.registry, context);
then(this.registry).should().addConverter(context.getBean(ExampleConverter.class));
then(this.registry).shouldHaveNoMoreInteractions();
}
}
@Test
void addBeansWhenHasFormatterBeanAddsOnlyFormatter() {
try (ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(ExampleFormatter.class)) {
ApplicationConversionService.addBeans(this.registry, context);
then(this.registry).should().addFormatter(context.getBean(ExampleFormatter.class));
then(this.registry).shouldHaveNoMoreInteractions();
}
}
@Test
void addBeansWhenHasPrinterBeanAddPrinter() {
try (ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(ExamplePrinter.class)) {
ApplicationConversionService.addBeans(this.registry, context);
then(this.registry).should().addPrinter(context.getBean(ExamplePrinter.class));
then(this.registry).shouldHaveNoMoreInteractions();
}
}
@Test
void addBeansWhenHasParserBeanAddParser() {
try (ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(ExampleParser.class)) {
ApplicationConversionService.addBeans(this.registry, context);
then(this.registry).should().addParser(context.getBean(ExampleParser.class));
then(this.registry).shouldHaveNoMoreInteractions();
}
}
@Test
@SuppressWarnings("unchecked")
void addBeansWhenHasConverterBeanMethodAddConverter() {
try (ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(
ConverterBeanMethodConfiguration.class)) {
Converter<String, Integer> converter = (Converter<String, Integer>) context.getBean("converter");
willThrow(IllegalArgumentException.class).given(this.registry).addConverter(converter);
ApplicationConversionService.addBeans(this.registry, context);
then(this.registry).should().addConverter(any(ConverterBeanAdapter.class));
then(this.registry).shouldHaveNoMoreInteractions();
}
}
@Test
@SuppressWarnings("unchecked")
void addBeansWhenHasPrinterBeanMethodAddPrinter() {
try (ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(
PrinterBeanMethodConfiguration.class)) {
Printer<Integer> printer = (Printer<Integer>) context.getBean("printer");
willThrow(IllegalArgumentException.class).given(this.registry).addPrinter(printer);
ApplicationConversionService.addBeans(this.registry, context);
then(this.registry).should(never()).addPrinter(printer);
then(this.registry).should().addConverter(any(PrinterBeanAdapter.class));
then(this.registry).shouldHaveNoMoreInteractions();
}
}
@Test
@SuppressWarnings("unchecked")
void addBeansWhenHasParserBeanMethodAddParser() {
try (ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(
ParserBeanMethodConfiguration.class)) {
Parser<Integer> parser = (Parser<Integer>) context.getBean("parser");
willThrow(IllegalArgumentException.class).given(this.registry).addParser(parser);
ApplicationConversionService.addBeans(this.registry, context);
then(this.registry).should(never()).addParser(parser);
then(this.registry).should().addConverter(any(ParserBeanAdapter.class));
then(this.registry).shouldHaveNoMoreInteractions();
}
}
@Test
void isConvertViaObjectSourceTypeWhenObjectSourceReturnsTrue() {
// Uses ObjectToCollectionConverter
ApplicationConversionService conversionService = new ApplicationConversionService();
TypeDescriptor sourceType = TypeDescriptor.valueOf(Long.class);
TypeDescriptor targetType = TypeDescriptor.valueOf(List.class);
assertThat(conversionService.canConvert(sourceType, targetType)).isTrue();
assertThat(conversionService.isConvertViaObjectSourceType(sourceType, targetType)).isTrue();
}
@Test
void isConvertViaObjectSourceTypeWhenNotObjectSourceReturnsFalse() {
// Uses StringToCollectionConverter
ApplicationConversionService conversionService = new ApplicationConversionService();
TypeDescriptor sourceType = TypeDescriptor.valueOf(String.class);
TypeDescriptor targetType = TypeDescriptor.valueOf(List.class);
assertThat(conversionService.canConvert(sourceType, targetType)).isTrue();
assertThat(conversionService.isConvertViaObjectSourceType(sourceType, targetType)).isFalse();
}
@Test
@SuppressWarnings("unchecked")
void sharedInstanceCannotBeModified() {
ApplicationConversionService instance = (ApplicationConversionService) ApplicationConversionService
.getSharedInstance();
Printer<?> printer = mock(Printer.class);
Parser<?> parser = mock(Parser.class);
assertUnmodifiableExceptionThrown(() -> instance.addPrinter(printer));
assertUnmodifiableExceptionThrown(() -> instance.addParser(parser));
assertUnmodifiableExceptionThrown(() -> instance.addFormatter(mock(Formatter.class)));
assertUnmodifiableExceptionThrown(() -> instance.addFormatterForFieldType(getClass(), mock(Formatter.class)));
assertUnmodifiableExceptionThrown(() -> instance.addConverter(mock(Converter.class)));
assertUnmodifiableExceptionThrown(() -> instance.addFormatterForFieldType(getClass(), printer, parser));
assertUnmodifiableExceptionThrown(
() -> instance.addFormatterForFieldAnnotation(mock(AnnotationFormatterFactory.class)));
assertUnmodifiableExceptionThrown(() -> instance.addConverter(getClass(), getClass(), mock(Converter.class)));
assertUnmodifiableExceptionThrown(() -> instance.addConverter(mock(GenericConverter.class)));
assertUnmodifiableExceptionThrown(() -> instance.addConverterFactory(mock(ConverterFactory.class)));
assertUnmodifiableExceptionThrown(() -> instance.removeConvertible(getClass(), getClass()));
}
@Test
void addPrinterBeanWithTypeConvertsUsingTypeInformation() {
FormattingConversionService conversionService = new FormattingConversionService();
Printer<?> printer = (object, locale) -> object.toString().toUpperCase(locale);
ApplicationConversionService.addBean(conversionService, printer,
ResolvableType.forClassWithGenerics(Printer.class, ExampleRecord.class));
assertThat(conversionService.convert(new ExampleRecord("test"), String.class)).isEqualTo("TEST");
assertThatExceptionOfType(ConverterNotFoundException.class)
.isThrownBy(() -> conversionService.convert(new OtherRecord("test"), String.class));
assertThatIllegalArgumentException().isThrownBy(() -> conversionService.addPrinter(printer))
.withMessageContaining("Unable to extract");
}
@Test
void addParserBeanWithTypeConvertsUsingTypeInformation() {
FormattingConversionService conversionService = new FormattingConversionService();
Parser<?> parser = (text, locale) -> new ExampleRecord(text.toString());
ApplicationConversionService.addBean(conversionService, parser,
ResolvableType.forClassWithGenerics(Parser.class, ExampleRecord.class));
assertThat(conversionService.convert("test", ExampleRecord.class)).isEqualTo(new ExampleRecord("test"));
assertThatExceptionOfType(ConverterNotFoundException.class)
.isThrownBy(() -> conversionService.convert("test", OtherRecord.class));
assertThatIllegalArgumentException().isThrownBy(() -> conversionService.addParser(parser))
.withMessageContaining("Unable to extract");
}
@Test
@SuppressWarnings("rawtypes")
void addFormatterBeanWithTypeConvertsUsingTypeInformation() {
FormattingConversionService conversionService = new FormattingConversionService();
Formatter<?> formatter = new Formatter() {
@Override
public String print(Object object, Locale locale) {
return object.toString().toUpperCase(locale);
}
@Override
public Object parse(String text, Locale locale) throws ParseException {
return new ExampleRecord(text.toString());
}
};
ApplicationConversionService.addBean(conversionService, formatter,
ResolvableType.forClassWithGenerics(Formatter.class, ExampleRecord.class));
assertThat(conversionService.convert(new ExampleRecord("test"), String.class)).isEqualTo("TEST");
assertThat(conversionService.convert("test", ExampleRecord.class)).isEqualTo(new ExampleRecord("test"));
assertThatExceptionOfType(ConverterNotFoundException.class)
.isThrownBy(() -> conversionService.convert(new OtherRecord("test"), String.class));
assertThatExceptionOfType(ConverterNotFoundException.class)
.isThrownBy(() -> conversionService.convert("test", OtherRecord.class));
assertThatIllegalArgumentException().isThrownBy(() -> conversionService.addFormatter(formatter))
.withMessageContaining("Unable to extract");
}
@Test
void addConverterBeanWithTypeConvertsUsingTypeInformation() {
FormattingConversionService conversionService = new FormattingConversionService();
Converter<?, ?> converter = (source) -> new ExampleRecord(source.toString());
ApplicationConversionService.addBean(conversionService, converter,
ResolvableType.forClassWithGenerics(Converter.class, CharSequence.class, ExampleRecord.class));
assertThat(conversionService.convert("test", ExampleRecord.class)).isEqualTo(new ExampleRecord("test"));
assertThat(conversionService.convert(new StringBuilder("test"), ExampleRecord.class))
.isEqualTo(new ExampleRecord("test"));
assertThatExceptionOfType(ConverterNotFoundException.class)
.isThrownBy(() -> conversionService.convert("test", OtherRecord.class));
assertThatIllegalArgumentException().isThrownBy(() -> conversionService.addConverter(converter))
.withMessageContaining("Unable to determine");
}
@Test
@SuppressWarnings("rawtypes")
void addConverterBeanWithTypeWhenConditionalChecksCondition() {
FormattingConversionService conversionService = new FormattingConversionService();
ConditionalConverterConverter<?, ?> converter = new ConditionalConverterConverter() {
@Override
public Object convert(Object source) {
return new ExampleRecord(source.toString());
}
@Override
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
return sourceType.getType() != StringBuilder.class;
}
};
ApplicationConversionService.addBean(conversionService, converter,
ResolvableType.forClassWithGenerics(Converter.class, CharSequence.class, ExampleRecord.class));
assertThat(conversionService.convert("test", ExampleRecord.class)).isEqualTo(new ExampleRecord("test"));
assertThatExceptionOfType(ConverterNotFoundException.class)
.isThrownBy(() -> conversionService.convert(new StringBuilder("test"), ExampleRecord.class));
assertThatIllegalArgumentException().isThrownBy(() -> conversionService.addConverter(converter))
.withMessageContaining("Unable to determine");
}
@Test
@SuppressWarnings("unchecked")
void addConverterBeanWithTypeWhenNullSourceCanConvertToOptionEmpty() {
FormattingConversionService conversionService = new FormattingConversionService();
Converter<?, ?> converter = (source) -> new ExampleRecord(source.toString());
ApplicationConversionService.addBean(conversionService, converter,
ResolvableType.forClassWithGenerics(Converter.class, CharSequence.class, ExampleRecord.class));
assertThat(conversionService.convert(null, ExampleRecord.class)).isNull();
assertThat(conversionService.convert(null, Optional.class)).isEmpty();
}
@Test
@SuppressWarnings("rawtypes")
void addConverterFactoryBeanWithTypeConvertsUsingTypeInformation() {
FormattingConversionService conversionService = new FormattingConversionService();
Converter<?, ?> converter = (source) -> new ExampleRecord(source.toString());
ConverterFactory converterFactory = (targetType) -> converter;
ApplicationConversionService.addBean(conversionService, converterFactory,
ResolvableType.forClassWithGenerics(ConverterFactory.class, CharSequence.class, ExampleRecord.class));
assertThat(conversionService.convert("test", ExampleRecord.class)).isEqualTo(new ExampleRecord("test"));
assertThat(conversionService.convert(new StringBuilder("test"), ExampleRecord.class))
.isEqualTo(new ExampleRecord("test"));
assertThatExceptionOfType(ConverterNotFoundException.class)
.isThrownBy(() -> conversionService.convert("test", OtherRecord.class));
assertThatIllegalArgumentException().isThrownBy(() -> conversionService.addConverterFactory(converterFactory))
.withMessageContaining("Unable to determine");
}
private void assertUnmodifiableExceptionThrown(ThrowingCallable throwingCallable) {
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(throwingCallable)
.withMessage("This ApplicationConversionService cannot be modified");
}
static class ExampleGenericConverter implements GenericConverter {
@Override
public @Nullable Set<ConvertiblePair> getConvertibleTypes() {
return null;
}
@Override
public @Nullable Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
return null;
}
}
static class ExampleConverter implements Converter<String, @Nullable Integer> {
@Override
public @Nullable Integer convert(String source) {
return null;
}
}
static class ExampleFormatter implements Formatter<Integer> {
@Override
public String print(Integer object, Locale locale) {
return "";
}
@Override
public Integer parse(String text, Locale locale) throws ParseException {
return 1;
}
}
static class ExampleParser implements Parser<Integer> {
@Override
public Integer parse(String text, Locale locale) throws ParseException {
return 1;
}
}
static class ExamplePrinter implements Printer<Integer> {
@Override
public String print(Integer object, Locale locale) {
return "";
}
}
@Configuration
static class ConverterBeanMethodConfiguration {
@Bean
Converter<String, Integer> converter() {
return Integer::valueOf;
}
}
@Configuration
static class PrinterBeanMethodConfiguration {
@Bean
Printer<Integer> printer() {
return (object, locale) -> object.toString();
}
}
@Configuration
static class ParserBeanMethodConfiguration {
@Bean
Parser<Integer> parser() {
return (text, locale) -> Integer.valueOf(text);
}
}
record ExampleRecord(String value) {
@Override
public final String toString() {
return value();
}
}
record OtherRecord(String value) {
}
interface ConditionalConverterConverter<S, T> extends Converter<S, T>, ConditionalConverter {
}
}
Source
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free