/*
* Copyright 2014 mango.jfaster.org
*
* The Mango Project licenses this file to you 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.jfaster.mango.invoker;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.primitives.Ints;
import org.jfaster.mango.annotation.Getter;
import org.jfaster.mango.invoker.function.LongListToStringFunction;
import org.jfaster.mango.util.reflect.TypeToken;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import javax.annotation.Nullable;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
/**
* @author ash
*/
public class FunctionalGetterInvokerTest {
public static class IntegerToStringFunction implements GetterFunction<Integer, String> {
@Nullable
@Override
public String apply(@Nullable Integer input) {
return "string" + input;
}
}
static class A {
private int x;
private int y;
int getX() {
return x;
}
void setX(int x) {
this.x = x;
}
@Getter(IntegerToStringFunction.class)
int getY() {
return y;
}
void setY(int y) {
this.y = y;
}
}
@Test
public void testIntToString() throws Exception {
Method method = A.class.getDeclaredMethod("getX");
A a = new A();
a.setX(100);
GetterInvoker invoker = FunctionalGetterInvoker.create("x", method);
assertThat(invoker.getName(), is("x"));
assertThat(int.class.equals(invoker.getReturnType()), is(true));
assertThat(int.class.equals(invoker.getReturnRawType()), is(true));
assertThat((Integer) invoker.invoke(a), is(100));
method = A.class.getDeclaredMethod("getY");
a = new A();
a.setY(100);
invoker = FunctionalGetterInvoker.create("y", method);
assertThat(invoker.getName(), is("y"));
assertThat(String.class.equals(invoker.getReturnType()), is(true));
assertThat(String.class.equals(invoker.getReturnRawType()), is(true));
assertThat((String) invoker.invoke(a), is("string100"));
}
static class B {
private Integer x;
private Integer y;
Integer getX() {
return x;
}
void setX(Integer x) {
this.x = x;
}
@Getter(IntegerToStringFunction.class)
Integer getY() {
return y;
}
void setY(Integer y) {
this.y = y;
}
}
@Test
public void testIntegerToString() throws Exception {
Method method = B.class.getDeclaredMethod("getX");
B b = new B();
b.setX(100);
GetterInvoker invoker = FunctionalGetterInvoker.create("x", method);
assertThat(invoker.getName(), is("x"));
assertThat(Integer.class.equals(invoker.getReturnType()), is(true));
assertThat(Integer.class.equals(invoker.getReturnRawType()), is(true));
assertThat((Integer) invoker.invoke(b), is(100));
method = B.class.getDeclaredMethod("getY");
b = new B();
b.setY(100);
invoker = FunctionalGetterInvoker.create("y", method);
assertThat(invoker.getName(), is("y"));
assertThat(String.class.equals(invoker.getReturnType()), is(true));
assertThat(String.class.equals(invoker.getReturnRawType()), is(true));
assertThat((String) invoker.invoke(b), is("string100"));
}
public static class StringToIntegerFunction implements GetterFunction<String, Integer> {
@Nullable
@Override
public Integer apply(@Nullable String input) {
return 100 * Integer.valueOf(input);
}
}
static class C {
private String x;
private String y;
String getX() {
return x;
}
void setX(String x) {
this.x = x;
}
@Getter(StringToIntegerFunction.class)
String getY() {
return y;
}
void setY(String y) {
this.y = y;
}
}
@Test
public void testStringToInteger() throws Exception {
Method method = C.class.getDeclaredMethod("getX");
C c = new C();
c.setX("9527");
GetterInvoker invoker = FunctionalGetterInvoker.create("x", method);
assertThat(invoker.getName(), is("x"));
assertThat(String.class.equals(invoker.getReturnType()), is(true));
assertThat(String.class.equals(invoker.getReturnRawType()), is(true));
assertThat((String) invoker.invoke(c), is("9527"));
method = C.class.getDeclaredMethod("getY");
c = new C();
c.setY("9527");
invoker = FunctionalGetterInvoker.create("y", method);
assertThat(invoker.getName(), is("y"));
assertThat(Integer.class.equals(invoker.getReturnType()), is(true));
assertThat(Integer.class.equals(invoker.getReturnRawType()), is(true));
assertThat((Integer) invoker.invoke(c), is(952700));
}
public static class IntegerListToStringFunction implements GetterFunction<List<Integer>, String> {
@Nullable
@Override
public String apply(@Nullable List<Integer> input) {
return Joiner.on(",").join(input);
}
}
static class D {
private List<Integer> x;
private List<Integer> y;
List<Integer> getX() {
return x;
}
void setX(List<Integer> x) {
this.x = x;
}
@Getter(IntegerListToStringFunction.class)
List<Integer> getY() {
return y;
}
void setY(List<Integer> y) {
this.y = y;
}
}
@SuppressWarnings("unchecked")
@Test
public void testListToString() throws Exception {
Method method = D.class.getDeclaredMethod("getX");
D d = new D();
List<Integer> x = Lists.newArrayList(1, 2);
d.setX(x);
GetterInvoker invoker = FunctionalGetterInvoker.create("x", method);
assertThat(invoker.getName(), is("x"));
Type type = new TypeToken<List<Integer>>() {
}.getType();
assertThat(type.equals(invoker.getReturnType()), is(true));
assertThat(List.class.equals(invoker.getReturnRawType()), is(true));
assertThat(invoker.invoke(d).equals(x), is(true));
method = D.class.getDeclaredMethod("getY");
d = new D();
List<Integer> y = Lists.newArrayList(1, 2);
d.setY(y);
invoker = FunctionalGetterInvoker.create("y", method);
assertThat(invoker.getName(), is("y"));
assertThat(String.class.equals(invoker.getReturnType()), is(true));
assertThat(String.class.equals(invoker.getReturnRawType()), is(true));
assertThat((String) invoker.invoke(d), is("1,2"));
}
static class E {
private String x;
@Getter(IntegerToStringFunction.class)
String getX() {
return x;
}
void setX(String x) {
this.x = x;
}
}
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void testException() throws Exception {
thrown.expect(ClassCastException.class);
thrown.expectMessage("function[class org.jfaster.mango.invoker.FunctionalGetterInvokerTest$IntegerToStringFunction] on method[java.lang.String org.jfaster.mango.invoker.FunctionalGetterInvokerTest$E.getX()] error, function's inputType[class java.lang.Integer] must be assignable from method's returnType[class java.lang.String]");
Method method = E.class.getDeclaredMethod("getX");
E e = new E();
e.setX("9527");
FunctionalGetterInvoker.create("x", method);
}
static class F {
private List<String> x;
@Getter(IntegerListToStringFunction.class)
List<String> getX() {
return x;
}
void setX(List<String> x) {
this.x = x;
}
}
@Test
public void testException2() throws Exception {
thrown.expect(ClassCastException.class);
thrown.expectMessage("function[class org.jfaster.mango.invoker.FunctionalGetterInvokerTest$IntegerListToStringFunction] on method[java.util.List org.jfaster.mango.invoker.FunctionalGetterInvokerTest$F.getX()] error, function's inputType[java.util.List<java.lang.Integer>] must be assignable from method's returnType[java.util.List<java.lang.String>]");
Method method = F.class.getDeclaredMethod("getX");
F e = new F();
ArrayList<String> x = Lists.newArrayList("xxx");
e.setX(x);
FunctionalGetterInvoker.create("x", method);
}
public static class IntArrayToStringFunction implements GetterFunction<int[], String> {
@Nullable
@Override
public String apply(@Nullable int[] input) {
return Ints.join(",", input);
}
}
static class G {
private int[] x;
private int[] y;
int[] getX() {
return x;
}
void setX(int[] x) {
this.x = x;
}
@Getter(IntArrayToStringFunction.class)
int[] getY() {
return y;
}
void setY(int[] y) {
this.y = y;
}
}
@Test
public void testIntArrayToString() throws Exception {
Method method = G.class.getDeclaredMethod("getX");
G g = new G();
int[] x = new int[]{1, 2, 3};
g.setX(x);
GetterInvoker invoker = FunctionalGetterInvoker.create("x", method);
assertThat(invoker.getName(), is("x"));
assertThat(int[].class.equals(invoker.getReturnType()), is(true));
assertThat(int[].class.equals(invoker.getReturnRawType()), is(true));
assertThat(Arrays.toString((int[]) invoker.invoke(g)).equals(Arrays.toString(x)), is(true));
method = G.class.getDeclaredMethod("getY");
g = new G();
int[] y = new int[]{1, 2, 3};
g.setY(y);
invoker = FunctionalGetterInvoker.create("y", method);
assertThat(invoker.getName(), is("y"));
assertThat(String.class.equals(invoker.getReturnType()), is(true));
assertThat(String.class.equals(invoker.getReturnRawType()), is(true));
assertThat((String) invoker.invoke(g), is("1,2,3"));
}
static class H {
private String x;
String getX() {
return x;
}
@Getter(LongListToStringFunction.class)
void setX(String x) {
this.x = x;
}
}
}