/*
* Copyright 2013 headius.
*
* 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 com.headius.invokebinder;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.List;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author headius
*/
public class SignatureTest {
public SignatureTest() {
}
@BeforeClass
public static void setUpClass() {
}
@AfterClass
public static void tearDownClass() {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
/**
* Test of toString method, of class Signature.
*/
@Test
public void testToString() {
assertEquals("(Object obj, int num)String", stringObjectInt.toString());
}
/**
* Test of returning method, of class Signature.
*/
@Test
public void testReturning() {
Signature sig = Signature.returning(String.class);
assertEquals(String.class, sig.type().returnType());
}
/**
* Test of asFold method, of class Signature.
*/
@Test
public void testAsFold() {
Signature sig = Signature
.returning(String.class)
.asFold(Object.class);
assertEquals(Object.class, sig.type().returnType());
}
/**
* Test of appendArg method, of class Signature.
*/
@Test
public void testAppendArg() {
Signature sig = Signature
.returning(String.class)
.appendArg("obj", Object.class);
assertEquals("(Object obj)String", sig.toString());
sig = sig
.appendArg("num", int.class);
assertEquals("(Object obj, int num)String", sig.toString());
}
/**
* Test of prependArg method, of class Signature.
*/
@Test
public void testPrependArg() {
Signature sig = Signature
.returning(String.class)
.appendArg("num", int.class);
assertEquals("(int num)String", sig.toString());
sig = sig
.prependArg("obj", Object.class);
assertEquals("(Object obj, int num)String", sig.toString());
}
/**
* Test of insertArg method, of class Signature.
*/
@Test
public void testInsertArg() {
Signature sig = Signature
.returning(String.class)
.appendArg("obj", Object.class)
.appendArg("num", int.class)
.insertArg(1, "flo", float.class);
assertEquals("(Object obj, float flo, int num)String", sig.toString());
}
@Test
public void testInsertArgBefore() {
Signature sig = Signature
.returning(String.class)
.appendArg("obj", Object.class)
.appendArg("num", int.class)
.insertArg("num", "flo", float.class);
assertEquals("(Object obj, float flo, int num)String", sig.toString());
}
/**
* Test of insertArgs method, of class Signature.
*/
@Test
public void testInsertArgs() {
Signature sig = Signature
.returning(String.class)
.appendArg("obj", Object.class)
.appendArg("num", int.class)
.insertArgs(1, new String[]{"flo", "dub"}, new Class[] {float.class, double.class});
assertEquals("(Object obj, float flo, double dub, int num)String", sig.toString());
}
@Test
public void testInsertArgsBefore() {
Signature sig = Signature
.returning(String.class)
.appendArg("obj", Object.class)
.appendArg("num", int.class)
.insertArgs("num", new String[]{"flo", "dub"}, new Class[] {float.class, double.class});
assertEquals("(Object obj, float flo, double dub, int num)String", sig.toString());
}
/**
* Test of methodType method, of class Signature.
*/
@Test
public void testMethodType() {
assertEquals(MethodType.methodType(String.class, Object.class, int.class), stringObjectInt.type());
}
/**
* Test of argNames method, of class Signature.
*/
@Test
public void testArgNames() {
assertArrayEquals(new String[] {"obj", "num"}, stringObjectInt.argNames());
}
@Test
public void testArgName() {
assertEquals("num", stringObjectInt.appendArg("flo", float.class).argName(1));
Signature oldSig = stringObjectInt;
Signature newSig = oldSig.argName(0, "str");
assertEquals("str", newSig.argName(0));
}
@Test
public void testLastArgName() {
assertEquals("flo", stringObjectInt.appendArg("flo", float.class).lastArgName());
}
@Test
public void testFirstArgName() {
assertEquals("obj", stringObjectInt.appendArg("flo", float.class).firstArgName());
}
@Test
public void testArgOffset() {
assertEquals(1, stringObjectInt.argOffset("num"));
assertEquals(-1, stringObjectInt.argOffset("flo"));
}
@Test
public void testArgOffsets() {
assertEquals(1, stringObjectInt.argOffsets("nu*"));
assertEquals(-1, stringObjectInt.argOffsets("fl."));
}
@Test
public void testArgType() {
assertEquals(int.class, stringObjectInt.appendArg("flo", float.class).argType(1));
Signature oldSig = stringObjectInt;
Signature newSig = oldSig.argType(0, String.class);
assertEquals(String.class, newSig.argType(0));
}
@Test
public void testFirstArgType() {
assertEquals(Object.class, stringObjectInt.appendArg("flo", float.class).firstArgType());
}
@Test
public void testLastArgType() {
assertEquals(float.class, stringObjectInt.appendArg("flo", float.class).lastArgType());
}
/**
* Test of permute method, of class Signature.
*/
@Test
public void testPermute() {
Signature sig = stringObjectInt
.appendArg("flo", float.class)
.appendArg("dub", double.class)
.permute("obj", "dub");
assertEquals("(Object obj, double dub)String", sig.toString());
}
@Test
public void testExclude() {
Signature sig = stringObjectInt
.appendArg("flo", float.class)
.appendArg("dub", double.class)
.exclude("obj", "dub");
assertEquals("(int num, float flo)String", sig.toString());
}
/**
* Test of permuteTo method, of class Signature.
*/
@Test
public void testPermuteWith() throws Throwable {
MethodHandle handle = stringObjectInt
.appendArg("flo", float.class)
.appendArg("dub", double.class)
.permuteWith(stringObjectIntTarget, "obj", "num");
assertEquals(MethodType.methodType(String.class, Object.class, int.class, float.class, double.class), handle.type());
assertEquals("foo1", (String)handle.invokeExact((Object)"foo", 1, 1.0f, 1.0));
}
@Test
public void testPermuteWithSmartHandle() throws Throwable {
SmartHandle target = new SmartHandle(stringObjectInt, stringObjectIntTarget);
SmartHandle permuted = stringObjectInt
.appendArg("flo", float.class)
.appendArg("dub", double.class)
.permuteWith(target);
assertEquals("(Object obj, int num, float flo, double dub)String", permuted.signature().toString());
assertEquals("foo1", permuted.handle().invokeWithArguments("foo", 1, 1.0f, 1.0));
}
@Test
public void testSpreadNamesAndTypes() throws Throwable {
Signature sig = stringObjectAry
.spread(new String[]{"int", "flo"}, Integer.class, Float.class);
assertEquals("(Integer int, Float flo)String", sig.toString());
}
@Test
public void testSpreadNames() throws Throwable {
Signature sig = stringObjectAry
.spread("obj0", "obj1");
assertEquals("(Object obj0, Object obj1)String", sig.toString());
}
@Test
public void testSpreadNameAndCount() throws Throwable {
Signature sig = stringObjectAry
.spread("obj", 2);
assertEquals("(Object obj0, Object obj1)String", sig.toString());
}
/**
* Test of to method, of class Signature.
*/
@Test
public void testTo_Signature() {
int[] permuteInts = stringObjectInt
.appendArg("flo", float.class)
.appendArg("dub", double.class)
.to(stringObjectInt);
assertArrayEquals(new int[] {0, 1}, permuteInts);
}
/**
* Test of to method, of class Signature.
*/
@Test
public void testTo_StringArr() {
int[] permuteInts = stringObjectInt
.appendArg("flo", float.class)
.appendArg("dub", double.class)
.to(".*o.*");
assertArrayEquals(new int[] {0, 2}, permuteInts);
permuteInts = stringObjectInt
.appendArg("flo", float.class)
.appendArg("dub", double.class)
.to("num", "dub");
assertArrayEquals(new int[] {1, 3}, permuteInts);
}
@Test
public void testDropArg() {
Signature newSig = stringObjectInt
.appendArg("flo", float.class)
.dropArg("num");
assertEquals("(Object obj, float flo)String", newSig.toString());
}
@Test
public void testDropArgIndex() {
Signature newSig = stringObjectInt
.appendArg("flo", float.class)
.dropArg(1);
assertEquals("(Object obj, float flo)String", newSig.toString());
}
@Test
public void testDropLast() {
Signature newSig = stringObjectInt
.dropLast();
assertEquals("(Object obj)String", newSig.toString());
newSig = stringObjectInt
.dropLast(2);
assertEquals("()String", newSig.toString());
}
@Test
public void testDropFirst() {
Signature newSig = stringObjectInt
.dropFirst();
assertEquals("(int num)String", newSig.toString());
newSig = stringObjectInt
.dropFirst(2);
assertEquals("()String", newSig.toString());
}
@Test
public void testReplaceArg() {
Signature newSig = stringObjectInt
.replaceArg("obj", "list", List.class);
assertEquals("(List list, int num)String", newSig.toString());
}
@Test
public void testCollect() {
Signature oldSig = Subjects.StringIntegerIntegerIntegerString;
Signature newSig = oldSig.collect("bs", "b.*");
assertEquals(Integer[].class, newSig.argType(1));
assertEquals("bs", newSig.argName(1));
assertEquals(3, newSig.argCount());
assertEquals("c", newSig.argName(2));
oldSig = Subjects.StringIntegerIntegerInteger;
newSig = oldSig.collect("bs", "b.*");
assertEquals(Integer[].class, newSig.argType(1));
assertEquals("bs", newSig.argName(1));
assertEquals(2, newSig.argCount());
}
private static final Signature stringObjectInt = Signature
.returning(String.class)
.appendArg("obj", Object.class)
.appendArg("num", int.class);
private static final Signature stringObjectAry = Signature
.returning(String.class)
.appendArg("objs", Object[].class);
private static final MethodHandle stringObjectIntTarget = Binder
.from(String.class, Object.class, int.class)
.invokeStaticQuiet(MethodHandles.lookup(), SignatureTest.class, "stringObjectIntMethod");
private static String stringObjectIntMethod(Object obj, int num) {
return obj.toString() + num;
}
}