Add FunctionType abstraction and test it

This commit is contained in:
Dave Syer
2018-02-26 09:56:02 +00:00
parent 42a7babb7d
commit 38f6caf4dc
4 changed files with 350 additions and 14 deletions

View File

@@ -0,0 +1,163 @@
/*
* Copyright 2016-2017 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.cloud.function.context;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.Map;
import java.util.function.Function;
import org.junit.Test;
import org.springframework.core.ResolvableType;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import static org.assertj.core.api.Assertions.assertThat;
import reactor.core.publisher.Flux;
/**
* @author Dave Syer
*
*/
public class FunctionTypeTests {
@Test
public void plainFunction() {
FunctionType function = new FunctionType(IntegerToString.class);
assertThat(function.getInputType()).isEqualTo(Integer.class);
assertThat(function.getOutputType()).isEqualTo(String.class);
assertThat(function.getInputWrapper()).isEqualTo(Integer.class);
assertThat(function.getOutputWrapper()).isEqualTo(String.class);
assertThat(function.isMessage()).isEqualTo(false);
}
@Test
public void genericFunction() {
FunctionType function = new FunctionType(StringToMap.class);
assertThat(function.getInputType()).isEqualTo(String.class);
assertThat(function.getOutputType()).isEqualTo(Map.class);
assertThat(function.getInputWrapper()).isEqualTo(String.class);
assertThat(function.getOutputWrapper()).isEqualTo(Map.class);
assertThat(function.isMessage()).isEqualTo(false);
}
@Test
public void pojoFunction() {
FunctionType function = new FunctionType(FooToFoo.class);
assertThat(function.getInputType()).isEqualTo(Foo.class);
assertThat(function.getOutputType()).isEqualTo(Bar.class);
assertThat(function.getInputWrapper()).isEqualTo(Foo.class);
assertThat(function.getOutputWrapper()).isEqualTo(Bar.class);
assertThat(function.isMessage()).isEqualTo(false);
}
@Test
public void fluxFunction() {
FunctionType function = new FunctionType(FluxToFlux.class);
assertThat(function.getInputType()).isEqualTo(Foo.class);
assertThat(function.getOutputType()).isEqualTo(Bar.class);
assertThat(function.getInputWrapper()).isEqualTo(Flux.class);
assertThat(function.getOutputWrapper()).isEqualTo(Flux.class);
assertThat(function.isMessage()).isEqualTo(false);
}
@Test
public void fluxMessageFunction() {
FunctionType function = new FunctionType(FluxMessageToFluxMessage.class);
assertThat(function.getInputType()).isEqualTo(Foo.class);
assertThat(function.getOutputType()).isEqualTo(Bar.class);
assertThat(function.getInputWrapper()).isEqualTo(Flux.class);
assertThat(function.getOutputWrapper()).isEqualTo(Flux.class);
assertThat(function.isMessage()).isEqualTo(true);
}
@Test
public void plainFunctionFromType() {
Type type = ResolvableType
.forClassWithGenerics(Function.class, Integer.class, String.class)
.getType();
FunctionType function = new FunctionType(type);
assertThat(function.getInputType()).isEqualTo(Integer.class);
assertThat(function.getOutputType()).isEqualTo(String.class);
assertThat(function.getInputWrapper()).isEqualTo(Integer.class);
assertThat(function.getOutputWrapper()).isEqualTo(String.class);
assertThat(function.isMessage()).isEqualTo(false);
}
@Test
public void fluxMessageFunctionFromType() {
Type type = ResolvableType
.forClassWithGenerics(Function.class,
ResolvableType.forClassWithGenerics(
Flux.class,
ResolvableType.forClassWithGenerics(Message.class,
Foo.class)),
ResolvableType.forClassWithGenerics(Flux.class, ResolvableType
.forClassWithGenerics(Message.class, Bar.class)))
.getType();
FunctionType function = new FunctionType(type);
assertThat(function.getInputType()).isEqualTo(Foo.class);
assertThat(function.getOutputType()).isEqualTo(Bar.class);
assertThat(function.getInputWrapper()).isEqualTo(Flux.class);
assertThat(function.getOutputWrapper()).isEqualTo(Flux.class);
assertThat(function.isMessage()).isEqualTo(true);
}
private static class IntegerToString implements Function<Integer, String> {
@Override
public String apply(Integer t) {
return "" + t;
}
}
private static class StringToMap implements Function<String, Map<String, Integer>> {
@Override
public Map<String, Integer> apply(String t) {
return Collections.emptyMap();
}
}
private static class FooToFoo implements Function<Foo, Bar> {
@Override
public Bar apply(Foo t) {
return new Bar();
}
}
private static class FluxToFlux implements Function<Flux<Foo>, Flux<Bar>> {
@Override
public Flux<Bar> apply(Flux<Foo> t) {
return t.map(f -> new Bar());
}
}
private static class FluxMessageToFluxMessage
implements Function<Flux<Message<Foo>>, Flux<Message<Bar>>> {
@Override
public Flux<Message<Bar>> apply(Flux<Message<Foo>> t) {
return t.map(f -> MessageBuilder.withPayload(new Bar())
.copyHeadersIfAbsent(f.getHeaders()).build());
}
}
private static class Foo {
}
private static class Bar {
}
}