/**
* Copyright 2013-2014 Recruit Technologies Co., Ltd. and contributors
* (see CONTRIBUTORS.md)
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. A copy of the
* License is distributed with this work in the LICENSE.md file. You may
* also obtain a copy of the License from
*
* 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.gennai.gungnir;
import static org.gennai.gungnir.ql.QueryOperations.*;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.storm.guava.collect.Lists;
import org.gennai.gungnir.ql.FunctionValidateException;
import org.gennai.gungnir.tuple.GungnirTuple;
import org.gennai.gungnir.tuple.Struct;
import org.gennai.gungnir.tuple.schema.TupleSchema;
import org.junit.Test;
import com.google.common.collect.Maps;
public class TestFunction {
public static class TestFunc {
public String evaluate(int v1) {
return "i:" + v1;
}
public String evaluate(Object v1) {
return "O:" + v1;
}
public String evaluate(Integer v1) {
return "I:" + v1;
}
}
public static class TestFunc2 {
public String evaluate(int v1) {
return "i:" + v1;
}
public String evaluate(Object v1) {
return "O:" + v1;
}
}
public static class TestFunc3 {
public String evaluate(Object v1) {
return "O:" + v1;
}
}
public static class TestFunc4 {
private String evaluate(int v1) {
return "i:" + v1;
}
public String dummy(int v1) {
return evaluate(v1);
}
}
public static class TestFunc5 {
public Object evaluate(Object v1, StringBuilder v2) {
return v1 + v2.toString();
}
}
public static class TestFunc6 {
public SimpleDateFormat evaluate(Object v1, String v2) {
return null;
}
}
public static class TestFunc7 {
public Map<String, Integer> evaluate(Boolean v1, String v2, long v3) {
return null;
}
public List<String> evaluate(Date v1, boolean v2, short v3) {
return null;
}
public Boolean evaluate(Map<String, Double> v1, List<Long> v2, Struct v3) {
return false;
}
}
public static class TestFunc8 {
public String evaluate(int v1) {
return "i:" + v1;
}
public String evaluate(Object v1) {
return "O:" + v1;
}
public String evaluate(Integer v1) {
return "I:" + v1;
}
public String evaluate(Object v1, int v2) {
return "Oi:" + v1 + "-" + v2;
}
public String evaluate(String v1, int v2) {
return "Si:" + v1 + "-" + v2;
}
public String evaluate(String v1, Integer v2) {
return "SI:" + v1 + "-" + v2;
}
}
public static class TestFunc9 {
private long total = 0;
public Long evaluate(Integer v1) {
total += v1;
return total;
}
public Long exclude(Integer v1) {
total -= v1;
return total;
}
public void clear() {
total = 0;
}
}
public static class TestFunc10 {
private long total = 0;
public Long evaluate(Integer v1) {
total += v1;
return total;
}
public void clear() {
total = 0;
}
}
public static class TestFunc11 {
private long total = 0;
public Long evaluate(Integer v1) {
total += v1;
return total;
}
public Long exclude(Integer v1) {
total -= v1;
return total;
}
}
public static class TestFunc12 {
private long count = 0;
public Long evaluate() {
count++;
return count;
}
public Long exclude() {
count--;
return count;
}
public void clear() {
count = 0;
}
}
public static class TestFunc13 {
private long total = 0;
public Long evaluate(Integer v1) {
total += v1;
return total;
}
public Long evaluate(Object v1) {
return total;
}
public Long exclude(Object v1) {
return total;
}
public Long exclude(String v1) {
return total;
}
public void clear() {
total = 0;
}
}
public static class TestFunc14 {
public String evaluate(String v1) {
return null;
}
public String exclude(StringBuilder v1) {
return null;
}
public void clear() {
}
}
public static class TestFunc15 {
public String evaluate(String v1) {
return null;
}
public String exclude(String v1) {
return null;
}
public void clear(String v1) {
}
}
public static class TestFunc16 {
public String evaluate(String v1) {
return null;
}
public BitSet exclude(String v1) {
return null;
}
public void clear() {
}
}
public static class TestFunc17 {
public String evaluate(String v1) {
return null;
}
public String exclude(String v1) {
return null;
}
public String clear() {
return null;
}
}
public static class TestFunc18 {
public Map<String, Integer> evaluate(Boolean v1, String v2, long v3) {
return null;
}
public List<String> evaluate(Date v1, boolean v2, short v3) {
return null;
}
public Boolean evaluate(Map<String, Double> v1, List<Long> v2, Struct v3) {
return false;
}
public Map<String, Integer> exclude(Boolean v1, String v2, long v3) {
return null;
}
public List<String> exclude(Date v1, boolean v2, short v3) {
return null;
}
public Boolean exclude(Map<String, Double> v1, List<Long> v2, Struct v3) {
return false;
}
public void clear() {
}
}
public static class TestFunc19 {
private long cnt;
public Long evaluate() {
cnt++;
return cnt;
}
public Long exclude() {
cnt--;
return cnt;
}
public Long evaluate(Integer... v) {
cnt += v.length;
return cnt;
}
public Long exclude(Integer... v) {
cnt -= v.length;
return cnt;
}
public void clear() {
cnt = 0;
}
}
public static class TestFunc20 {
public String evaluate(Integer v) {
return "I:" + v;
}
public String evaluate(int v) {
return "i:" + v;
}
public String evaluate(Object v) {
return "O:" + v;
}
public String evaluate(Integer... v) {
return "I:" + Arrays.toString(v);
}
public String evaluate(int... v) {
return "i:" + Arrays.toString(v);
}
public String evaluate(Object... v) {
return "O:" + Arrays.toString(v);
}
public String evaluate(long v) {
return "l:" + v;
}
public String evaluate(Long... v) {
return "L:" + Arrays.toString(v);
}
public String evaluate(long... v) {
return "l:" + Arrays.toString(v);
}
public String evaluate(Double... v) {
return "D:" + Arrays.toString(v);
}
public String evaluate(double... v) {
return "d:" + Arrays.toString(v);
}
public String evaluate(float... v) {
return "f:" + Arrays.toString(v);
}
public String evaluate(String... v) {
return "S:" + Arrays.toString(v);
}
}
public static class TestFunc21 {
public String evaluate(String... vs) {
return Arrays.toString(vs);
}
public String evaluate(Integer v, String... vs) {
return "S:" + v + "-" + Arrays.toString(vs);
}
public String evaluate(Integer v, Object... vs) {
return "O:" + v + "-" + Arrays.toString(vs);
}
}
public static class TestFunc22 {
private LinkedList<String> stack = Lists.newLinkedList();
public List<String> evaluate(String... vs) {
for (String v : vs) {
stack.add(v);
}
return Lists.newArrayList(stack);
}
public List<String> exclude(String... vs) {
for (String v : vs) {
stack.remove(v);
}
return Lists.newArrayList(stack);
}
public void clear() {
}
}
public static class TestFunc23 {
public Object evaluate(Integer v) {
return "I:" + v;
}
public Object evaluate(Long v) {
return "L:" + v;
}
public Object evaluate(Double v) {
return "D:" + v;
}
public Object evaluate(Object v) {
return "O:" + v;
}
public Object exclude(Integer v) {
return "I:" + v;
}
public Object exclude(Long v) {
return "L:" + v;
}
public Object exclude(Double v) {
return "D:" + v;
}
public Object exclude(Object v) {
return "O:" + v;
}
public void clear() {
}
}
public static class TestFunc24 {
public Object evaluate(Integer v) {
return "I:" + v;
}
public Object exclude(Integer v) {
return "I:" + v;
}
public Object evaluate(Long... vs) {
return "L:" + Arrays.toString(vs);
}
public Object exclude(Long... vs) {
return "L:" + Arrays.toString(vs);
}
public void clear() {
}
}
public static class TestFunc25 {
public Object evaluate(List<String> v) {
return v;
}
public Object evaluate(Map<String, String> v) {
return v;
}
}
public static class TestFunc26 {
public Object evaluate(String... v) {
return Arrays.toString(v);
}
}
@Test
public void testInvoke() throws Exception {
TupleSchema schema = new TupleSchema("tuple1").field("f1").field("f2");
GungnirTuple tuple = GungnirTuple.builder(schema).put("f1", "test").put("f2", 123).build();
assertThat((String) FunctionInvoker.create(TestFunc.class, field("f2")).evaluate(tuple),
is("I:123"));
assertThat((String) FunctionInvoker.create(TestFunc2.class, field("f2")).evaluate(tuple),
is("i:123"));
assertThat((String) FunctionInvoker.create(TestFunc3.class, field("f2")).evaluate(tuple),
is("O:123"));
}
@Test(expected = FunctionValidateException.class)
public void testNoMethod() throws Exception {
FunctionInvoker.validate(TestFunc4.class);
}
@Test(expected = FunctionValidateException.class)
public void testInvalidParams() throws Exception {
FunctionInvoker.validate(TestFunc5.class);
}
@Test(expected = FunctionValidateException.class)
public void testInvalidReturnType() throws Exception {
FunctionInvoker.validate(TestFunc6.class);
}
@Test
public void testValidate() throws Exception {
FunctionInvoker.validate(TestFunc7.class);
}
@Test
public void testInvokeMultipleArgs() throws Exception {
TupleSchema schema = new TupleSchema("tuple1").field("f1").field("f2");
GungnirTuple tuple = GungnirTuple.builder(schema).put("f1", "test").put("f2", 123).build();
assertThat(
(String) FunctionInvoker.create(TestFunc8.class, field("f1"), field("f2")).evaluate(tuple),
is("SI:test-123"));
}
@Test
public void testInvokeUDAF() throws Exception {
TupleSchema schema = new TupleSchema("tuple1").field("f1").field("f2");
GungnirTuple tuple = GungnirTuple.builder(schema).put("f1", "test").put("f2", 123).build();
FunctionInvoker invoker = FunctionInvoker.create(TestFunc9.class, field("f2"));
assertThat((Long) invoker.evaluate(tuple), is(123L));
assertThat((Long) invoker.evaluate(tuple), is(246L));
assertThat((Long) invoker.evaluate(tuple), is(369L));
assertThat((Long) invoker.exclude(tuple), is(246L));
invoker.clear();
assertThat((Long) invoker.evaluate(tuple), is(123L));
}
@Test(expected = FunctionValidateException.class)
public void testNoMethodUDAF() throws Exception {
FunctionInvoker.validate(TestFunc10.class);
}
@Test(expected = FunctionValidateException.class)
public void testNoMethodUDAF2() throws Exception {
FunctionInvoker.validate(TestFunc11.class);
}
@Test
public void testNoParamUDAF() throws Exception {
FunctionInvoker.validate(TestFunc12.class);
}
@Test
public void testValidateParamsUDAF() throws Exception {
FunctionInvoker.validate(TestFunc13.class);
}
@Test(expected = FunctionValidateException.class)
public void testInvalidParamsUDAF2() throws Exception {
FunctionInvoker.validate(TestFunc14.class);
}
@Test(expected = FunctionValidateException.class)
public void testInvalidParamsUDAF3() throws Exception {
FunctionInvoker.validate(TestFunc15.class);
}
@Test(expected = FunctionValidateException.class)
public void testInvalidReturnTypeUDAF() throws Exception {
FunctionInvoker.validate(TestFunc16.class);
}
@Test(expected = FunctionValidateException.class)
public void testInvalidReturnTypeUDAF2() throws Exception {
FunctionInvoker.validate(TestFunc17.class);
}
@Test
public void testInvalidUDAF() throws Exception {
FunctionInvoker.validate(TestFunc18.class);
}
@Test
public void testInvokeNoArgUDAF() throws Exception {
TupleSchema schema = new TupleSchema("tuple1").field("f1").field("f2").field("f3");
GungnirTuple tuple = GungnirTuple.builder(schema).put("f1", "test").put("f2", 123)
.put("f3", 456).build();
FunctionInvoker invoker = FunctionInvoker.create(TestFunc19.class);
assertThat((Long) invoker.evaluate(tuple), is(1L));
assertThat((Long) invoker.evaluate(tuple), is(2L));
assertThat((Long) invoker.evaluate(tuple), is(3L));
assertThat((Long) invoker.exclude(tuple), is(2L));
invoker.clear();
assertThat((Long) invoker.evaluate(tuple), is(1L));
invoker = FunctionInvoker.create(TestFunc19.class, field("f2"), field("f2"));
assertThat((Long) invoker.evaluate(tuple), is(2L));
assertThat((Long) invoker.exclude(tuple), is(0L));
}
@Test
public void testInvokeVarArgs() throws Exception {
TupleSchema schema = new TupleSchema("tuple1").field("f1").field("f2").field("f3").field("f4")
.field("f5").field("f6");
GungnirTuple tuple = GungnirTuple.builder(schema).put("f1", 10L).put("f2", 10).put("f3", 10.0)
.put("f4", 10.0F).put("f5", "test").put("f6", null).build();
assertThat((String) FunctionInvoker.create(TestFunc20.class, field("f2")).evaluate(tuple),
is("I:10"));
assertThat((String) FunctionInvoker.create(TestFunc20.class, field("f1")).evaluate(tuple),
is("l:10"));
assertThat((String) FunctionInvoker.create(TestFunc20.class, field("f3")).evaluate(tuple),
is("D:[10.0]"));
assertThat((String) FunctionInvoker.create(TestFunc20.class, field("f4")).evaluate(tuple),
is("f:[10.0]"));
assertThat((String) FunctionInvoker.create(TestFunc20.class, field("f5")).evaluate(tuple),
is("S:[test]"));
assertThat((String) FunctionInvoker.create(TestFunc20.class, field("f1"), field("f2"))
.evaluate(tuple), is("O:[10, 10]"));
assertThat((String) FunctionInvoker.create(TestFunc20.class, field("f5"), field("f6"), null)
.evaluate(tuple), is("S:[test, null, null]"));
assertThat((String) FunctionInvoker.create(TestFunc20.class, null, field("f6"))
.evaluate(tuple), is("O:[null, null]"));
assertThat((String) FunctionInvoker.create(TestFunc20.class, field("f2"), null)
.evaluate(tuple), is("I:[10, null]"));
}
@Test
public void testInvokeVarArgs2() throws Exception {
TupleSchema schema = new TupleSchema("tuple1").field("f1").field("f2").field("f3").field("f4");
GungnirTuple tuple = GungnirTuple.builder(schema).put("f1", "test").put("f2", 123)
.put("f3", "yyy").put("f4", 10L).build();
assertThat((String) FunctionInvoker.create(TestFunc21.class, field("f1"), field("f3"), "xxx")
.evaluate(tuple), is("[test, yyy, xxx]"));
assertThat((String) FunctionInvoker.create(TestFunc21.class, field("f2"), field("f3"), "xxx")
.evaluate(tuple), is("S:123-[yyy, xxx]"));
assertThat(
(String) FunctionInvoker.create(TestFunc21.class, field("f2"), field("f4"), field("f3"),
"xxx").evaluate(tuple),
is("O:123-[10, yyy, xxx]"));
}
@SuppressWarnings("unchecked")
@Test
public void testInvokeVarArgsUDAF() throws Exception {
TupleSchema schema = new TupleSchema("tuple1").field("f1").field("f2");
GungnirTuple tuple = GungnirTuple.builder(schema).put("f1", "test").put("f2", "123").build();
GungnirTuple tuple2 = GungnirTuple.builder(schema).put("f1", "test2").put("f2", "1234").build();
FunctionInvoker invoker =
FunctionInvoker.create(TestFunc22.class, field("f1"), field("f2"), "xxx");
assertThat((List<String>) invoker.evaluate(tuple),
is((List<String>) Lists.newArrayList("test", "123", "xxx")));
assertThat((List<String>) invoker.evaluate(tuple2),
is((List<String>) Lists.newArrayList("test", "123", "xxx", "test2", "1234", "xxx")));
assertThat((List<String>) invoker.exclude(tuple),
is((List<String>) Lists.newArrayList("test2", "1234", "xxx")));
}
@Test
public void testInvokeNullArgUDAF() throws Exception {
TupleSchema schema = new TupleSchema("tuple1").field("f1").field("f2").field("f3").field("f4")
.field("f5");
GungnirTuple tuple = GungnirTuple.builder(schema).put("f1", 10L).put("f2", 10).put("f3", 10.0)
.put("f4", null).put("f5", 10F).build();
assertThat((String) FunctionInvoker.create(TestFunc23.class, field("f1")).evaluate(tuple),
is("L:10"));
assertThat((String) FunctionInvoker.create(TestFunc23.class, field("f2")).evaluate(tuple),
is("I:10"));
assertThat((String) FunctionInvoker.create(TestFunc23.class, field("f3")).evaluate(tuple),
is("D:10.0"));
assertThat((String) FunctionInvoker.create(TestFunc23.class, field("f4")).evaluate(tuple),
is("O:null"));
assertThat((String) FunctionInvoker.create(TestFunc23.class, field("f5")).evaluate(tuple),
is("O:10.0"));
assertThat((String) FunctionInvoker.create(TestFunc23.class, field("f1")).exclude(tuple),
is("L:10"));
assertThat((String) FunctionInvoker.create(TestFunc23.class, field("f2")).exclude(tuple),
is("I:10"));
assertThat((String) FunctionInvoker.create(TestFunc23.class, field("f3")).exclude(tuple),
is("D:10.0"));
assertThat((String) FunctionInvoker.create(TestFunc23.class, field("f4")).exclude(tuple),
is("O:null"));
assertThat((String) FunctionInvoker.create(TestFunc23.class, field("f5")).exclude(tuple),
is("O:10.0"));
}
@Test
public void testInvokeNullArgUDAF2() throws Exception {
TupleSchema schema = new TupleSchema("tuple1").field("f1").field("f2").field("f3");
GungnirTuple tuple = GungnirTuple.builder(schema).put("f1", 10).put("f2", null).put("f3", 20L)
.build();
assertThat((String) FunctionInvoker.create(TestFunc24.class, field("f1")).evaluate(tuple),
is("I:10"));
assertThat((String) FunctionInvoker.create(TestFunc24.class, field("f2")).evaluate(tuple),
is("I:null"));
assertThat((String) FunctionInvoker.create(TestFunc24.class, field("f3")).evaluate(tuple),
is("L:[20]"));
assertThat((String) FunctionInvoker.create(TestFunc24.class, field("f1")).exclude(tuple),
is("I:10"));
assertThat((String) FunctionInvoker.create(TestFunc24.class, field("f2")).exclude(tuple),
is("I:null"));
assertThat((String) FunctionInvoker.create(TestFunc24.class, field("f3")).exclude(tuple),
is("L:[20]"));
}
@Test
@SuppressWarnings("unchecked")
public void testInvokeCollectionArg() throws Exception {
Map<String, Integer> map = Maps.newHashMap();
map.put("xxx", 12);
map.put("yyy", 34);
TupleSchema schema = new TupleSchema("tuple1").field("f1").field("f2").field("f3");
GungnirTuple tuple = GungnirTuple.builder(schema).put("f1", Lists.newArrayList("abc", "def"))
.put("f2", Lists.newArrayList(123, 456)).put("f3", map).build();
assertThat((ArrayList<String>) FunctionInvoker.create(TestFunc25.class, field("f1"))
.evaluate(tuple), is(Lists.newArrayList("abc", "def")));
assertThat((ArrayList<Integer>) FunctionInvoker.create(TestFunc25.class, field("f2"))
.evaluate(tuple), is(Lists.newArrayList(123, 456)));
assertThat((HashMap<String, Integer>) FunctionInvoker.create(TestFunc25.class, field("f3"))
.evaluate(tuple), is(Maps.newHashMap(map)));
}
@Test
public void testInvokeNullVarArg() throws Exception {
TupleSchema schema = new TupleSchema("tuple1").field("f1").field("f2");
GungnirTuple tuple = GungnirTuple.builder(schema).put("f1", null).put("f2", null).build();
assertThat((String) FunctionInvoker.create(TestFunc26.class, field("f1")).evaluate(tuple),
is("[null]"));
assertThat((String) FunctionInvoker.create(TestFunc26.class, field("f1"), field("f2"))
.evaluate(tuple), is("[null, null]"));
}
}