/*
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.core.convert.support;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.ConverterNotFoundException;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.Converter;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.*;
/**
* Tests for {@link StreamConverter}.
*
* @author Stephane Nicoll
* @since 4.2
*/
public class StreamConverterTests {
@Rule
public final ExpectedException thrown = ExpectedException.none();
private final GenericConversionService conversionService = new GenericConversionService();
private final StreamConverter streamConverter = new StreamConverter(this.conversionService);
@Before
public void setup() {
this.conversionService.addConverter(new CollectionToCollectionConverter(this.conversionService));
this.conversionService.addConverter(new ArrayToCollectionConverter(this.conversionService));
this.conversionService.addConverter(new CollectionToArrayConverter(this.conversionService));
this.conversionService.addConverter(this.streamConverter);
}
@Test
public void convertFromStreamToList() throws NoSuchFieldException {
this.conversionService.addConverter(Number.class, String.class, new ObjectToStringConverter());
Stream<Integer> stream = Arrays.asList(1, 2, 3).stream();
TypeDescriptor listOfStrings = new TypeDescriptor(Types.class.getField("listOfStrings")); ;
Object result = this.conversionService.convert(stream, listOfStrings);
assertNotNull("Converted object must not be null", result);
assertTrue("Converted object must be a list", result instanceof List);
@SuppressWarnings("unchecked")
List<String> content = (List<String>) result;
assertEquals("1", content.get(0));
assertEquals("2", content.get(1));
assertEquals("3", content.get(2));
assertEquals("Wrong number of elements", 3, content.size());
}
@Test
public void convertFromStreamToArray() throws NoSuchFieldException {
this.conversionService.addConverterFactory(new NumberToNumberConverterFactory());
Stream<Integer> stream = Arrays.asList(1, 2, 3).stream();
TypeDescriptor arrayOfLongs = new TypeDescriptor(Types.class.getField("arrayOfLongs")); ;
Object result = this.conversionService.convert(stream, arrayOfLongs);
assertNotNull("Converted object must not be null", result);
assertTrue("Converted object must be an array", result.getClass().isArray());
Long[] content = (Long[]) result;
assertEquals(Long.valueOf(1L), content[0]);
assertEquals(Long.valueOf(2L), content[1]);
assertEquals(Long.valueOf(3L), content[2]);
assertEquals("Wrong number of elements", 3, content.length);
}
@Test
public void convertFromStreamToRawList() throws NoSuchFieldException {
Stream<Integer> stream = Arrays.asList(1, 2, 3).stream();
TypeDescriptor listOfStrings = new TypeDescriptor(Types.class.getField("rawList")); ;
Object result = this.conversionService.convert(stream, listOfStrings);
assertNotNull("Converted object must not be null", result);
assertTrue("Converted object must be a list", result instanceof List);
@SuppressWarnings("unchecked")
List<Object> content = (List<Object>) result;
assertEquals(1, content.get(0));
assertEquals(2, content.get(1));
assertEquals(3, content.get(2));
assertEquals("Wrong number of elements", 3, content.size());
}
@Test
public void convertFromStreamToArrayNoConverter() throws NoSuchFieldException {
Stream<Integer> stream = Arrays.asList(1, 2, 3).stream();
TypeDescriptor arrayOfLongs = new TypeDescriptor(Types.class.getField("arrayOfLongs")); ;
thrown.expect(ConversionFailedException.class);
thrown.expectCause(is(instanceOf(ConverterNotFoundException.class)));
this.conversionService.convert(stream, arrayOfLongs);
}
@Test
@SuppressWarnings("resource")
public void convertFromListToStream() throws NoSuchFieldException {
this.conversionService.addConverterFactory(new StringToNumberConverterFactory());
List<String> stream = Arrays.asList("1", "2", "3");
TypeDescriptor streamOfInteger = new TypeDescriptor(Types.class.getField("streamOfIntegers")); ;
Object result = this.conversionService.convert(stream, streamOfInteger);
assertNotNull("Converted object must not be null", result);
assertTrue("Converted object must be a stream", result instanceof Stream);
@SuppressWarnings("unchecked")
Stream<Integer> content = (Stream<Integer>) result;
assertEquals(6, content.mapToInt((x) -> x).sum());
}
@Test
@SuppressWarnings("resource")
public void convertFromArrayToStream() throws NoSuchFieldException {
Integer[] stream = new Integer[] {1, 0, 1};
this.conversionService.addConverter(new Converter<Integer, Boolean>() {
@Override
public Boolean convert(Integer source) {
return source == 1;
}
});
TypeDescriptor streamOfBoolean = new TypeDescriptor(Types.class.getField("streamOfBooleans")); ;
Object result = this.conversionService.convert(stream, streamOfBoolean);
assertNotNull("Converted object must not be null", result);
assertTrue("Converted object must be a stream", result instanceof Stream);
@SuppressWarnings("unchecked")
Stream<Boolean> content = (Stream<Boolean>) result;
assertEquals(2, content.filter(x -> x).count());
}
@Test
@SuppressWarnings("resource")
public void convertFromListToRawStream() throws NoSuchFieldException {
List<String> stream = Arrays.asList("1", "2", "3");
TypeDescriptor streamOfInteger = new TypeDescriptor(Types.class.getField("rawStream")); ;
Object result = this.conversionService.convert(stream, streamOfInteger);
assertNotNull("Converted object must not be null", result);
assertTrue("Converted object must be a stream", result instanceof Stream);
@SuppressWarnings("unchecked")
Stream<Object> content = (Stream<Object>) result;
StringBuilder sb = new StringBuilder();
content.forEach(sb::append);
assertEquals("123", sb.toString());
}
@Test
public void doesNotMatchIfNoStream() throws NoSuchFieldException {
assertFalse("Should not match non stream type", this.streamConverter.matches(
new TypeDescriptor(Types.class.getField("listOfStrings")),
new TypeDescriptor(Types.class.getField("arrayOfLongs"))));
}
@Test
public void shouldFailToConvertIfNoStream() throws NoSuchFieldException {
thrown.expect(IllegalStateException.class);
this.streamConverter.convert(new Object(), new TypeDescriptor(Types.class.getField("listOfStrings")),
new TypeDescriptor(Types.class.getField("arrayOfLongs")));
}
@SuppressWarnings({ "rawtypes" })
static class Types {
public List<String> listOfStrings;
public Long[] arrayOfLongs;
public Stream<Integer> streamOfIntegers;
public Stream<Boolean> streamOfBooleans;
public Stream rawStream;
public List rawList;
}
}