diff --git a/jOOL-java-8/src/test/java/org/jooq/lambda/ExtraMagicTest.java b/jOOL-java-8/src/test/java/org/jooq/lambda/ExtraMagicTest.java new file mode 100644 index 00000000..39b68965 --- /dev/null +++ b/jOOL-java-8/src/test/java/org/jooq/lambda/ExtraMagicTest.java @@ -0,0 +1,352 @@ +package org.jooq.lambda; + +import org.jooq.lambda.function.Consumer3; +import org.junit.Test; + +import java.io.IOError; +import java.io.IOException; +import java.lang.invoke.CallSite; +import java.lang.invoke.LambdaMetafactory; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Objects; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Consumer; +import java.util.function.LongSupplier; + +import static org.jooq.lambda.LambdaLogFacade.printToStdErr; +import static org.jooq.lambda.Loops.loop; +import static org.junit.Assert.*; + +/* +https://www.jmix.io/cuba-blog/think-twice-before-using-reflection/ + +https://github.com/cuba-rnd/entity-lambda-accessors-benchmark/blob/master/src/jmh/java/utils/MethodHandleCache.java + +https://www.mail-archive.com/mlvm-dev@openjdk.java.net/msg06747.html + +https://www.optaplanner.org/blog/2018/01/09/JavaReflectionButMuchFaster.html + +https://wttech.blog/blog/2020/method-handles-and-lambda-metafactory/ + +https://forum.image.sc/t/performance-profiling-ways-of-invoking-a-method-dynamically/27471 + +!!! +private static final System.Logger log = System.getLogger("c.f.b.DefaultLogger"); ++ +clsLoader = Thread.currentThread().getContextClassLoader(); +clsLoader = Wrap.class.getClassLoader(); +clsLoader = ClassLoader.getPlatformClassLoader(); +clsLoader = ClassLoader.getSystemClassLoader(); + */ +public class ExtraMagicTest { + static volatile Throwable FAILED; + static final Method winner; + static { + Thread.setDefaultUncaughtExceptionHandler((Thread t, Throwable e) -> + { + FAILED = e; + loop(9, ()-> System.err.println("{{{{{ DefaultUncaughtExceptionHandler @ "+t)); + e.printStackTrace(); + loop(9, ()-> System.err.println("}}}}} DefaultUncaughtExceptionHandler @ "+t)); + }); + + //1. on/off → lambdaLogFacadeLoggerTest + System.setProperty("org.jooq.logger", "org.jooq.lambda.ExtraMagicTest$LoggerOverride"); + final Method winner0 = LambdaLogFacade.findLoggerFactoryGetLogger("org.jooq.lambda.ExtraMagicTest$LoggerOverride"); + + //2. slf4j +// final Method winner0 = LambdaLogFacade.findLoggerFactoryGetLogger("org.slf4j.LoggerFactory"); + + //3. log4j +// System.setProperty("org.jooq.logger.0", "-"); +// final Method winner0 = LambdaLogFacade.findLoggerFactoryGetLogger("org.apache.logging.log4j.LogManager"); +// //4. ×JUL: no slf4j/log4j +// System.setProperty("org.jooq.logger.0", "-"); +// System.setProperty("org.jooq.logger.1", "-"); +// final Method winner0 = null; + + if (Objects.equals(winner0, LambdaLogFacade.staticLoggerFactoryGetLoggerMethod)) { + // good! We are the first UnitTest, we have initialized LambdaLogFacade with our wishes + winner = winner0; + } else if (LambdaLogFacade.staticLoggerFactoryGetLoggerMethod == null) { + printToStdErr(ExtraMagicTest.class, + "Other UnitTest was faster and have already initialized LambdaLogFacade with null (slf4j and log4j were not found)", null); + winner = null; + } else { + printToStdErr(ExtraMagicTest.class, + "Other UnitTest was faster and have already initialized LambdaLogFacade with "+LambdaLogFacade.staticLoggerFactoryGetLoggerMethod, null); + winner = LambdaLogFacade.staticLoggerFactoryGetLoggerMethod; + } + } + + @Test(expected = IOError.class) + public void andThen () { + Error e1 = new Error("test1: → ERROR is OK here!!!"); + Unchecked.PRINT_STACK_TRACE.accept(e1); + + IOError e2 = new IOError(e1); + Consumer c = Unchecked.SILENT_IGNORE + .andThen((t) -> fail("unreachable. But: " + t)); + c.accept(e2); + + fail("unreachable"); + } + + + @Test public void modulesHackJUL () { + Object jul = getActualLogger("java.util.logging.Logger", ExtraMagicTest.class); + assertEquals("class java.util.logging.Logger", jul.getClass().toString()); + assertTrue(jul.toString().startsWith("java.util.logging.Logger@")); + } + + @Test public void modulesHackSlf4j () { + Object slf4j = getActualLogger("org.slf4j.LoggerFactory", ExtraMagicTest.class); + assertEquals("class org.slf4j.simple.SimpleLogger", slf4j.getClass().toString());// class org.slf4j.helpers.NOPLogger + assertTrue(slf4j.toString().startsWith("org.slf4j.simple.SimpleLogger@"));// org.slf4j.helpers.NOPLogger(NOP) + } + + @Test public void modulesHackLog4j () { + Object log4j = getActualLogger("org.apache.logging.log4j.LogManager", ExtraMagicTest.class); + assertEquals("class org.apache.logging.log4j.core.Logger", log4j.getClass().toString()); + assertTrue(log4j.toString().startsWith("org.jooq.lambda.ExtraMagicTest:ERROR in ")); + } + + public static class FakeLogger extends LambdaLogFacade implements LongSupplier, Runnable { + public FakeLogger () { + super(null); + } + + final AtomicLong cnt = new AtomicLong(); + + public static FakeLogger getLogger (String notUsed) { + return new FakeLogger(); + } + @Override public void warn (String msg, Throwable t) { + assertNotNull(t); + cnt.incrementAndGet(); + if (cnt.get() == MAX_LOOP) { + new Exception("[INFO] Almost there! "+msg+"\t\t"+this).printStackTrace(); + } + } + @Override public long getAsLong () { + return cnt.get(); + } + @Override public void run () {} + } + + static /*NOT final!*/ Throwable LOG_EXCEPTION = new Exception("fake");//MethodHandle.invokeExact check type of variable (not ref object) + static final long MAX_LOOP = 10_000_000; + static final long MAX_LOOP_WARM = 10_050_000; + + @Test public void speedDirect () { + FakeLogger fl = new FakeLogger() { + @Override public void run () { + warn("message-to-log: Direct", LOG_EXCEPTION); + } + }; + String st = Loops.loopMeasuredWarm(MAX_LOOP, fl).toString(); + System.out.println("*** speedDirect →\t\t"+st); + assertEquals(MAX_LOOP_WARM, fl.getAsLong()); + } + + @Test public void speedLambda () { + FakeLogger fl = new FakeLogger(); + + String st = Loops.loopMeasuredWarm(MAX_LOOP, Wrap.runnable(() -> + fl.warn("message-to-log: Lambda", LOG_EXCEPTION))).toString(); + System.out.println("*** speedLambda →\t\t"+st); + assertEquals(MAX_LOOP_WARM, fl.getAsLong()); + } + @Test public void speedLambdaMethodRef () { + FakeLogger fl = new FakeLogger(){ + @Override public void run () { + warn("message-to-log: LambdaMethodRef", LOG_EXCEPTION); + } + }; + + String st = Loops.loopMeasuredWarm(MAX_LOOP, Wrap.runnable(fl::run)).toString(); + System.out.println("*** speedLambdaMethodRef →\t\t"+st); + assertEquals(MAX_LOOP_WARM, fl.getAsLong()); + } + + private static final MethodHandle staticMethodHandle; + static {// Static MethodHandle setup ^ + try { + Object fl = getActualLogger("org.jooq.lambda.ExtraMagicTest$FakeLogger", ExtraMagicTest.class); + + MethodHandles.Lookup lookup = MethodHandles.lookup(); + //1. method → MethodHandle + //m = LambdaLogFacade.getWarnMethod(fl); + //staticMethodHandle = lookup.unreflect(m); + //2. .asType for invokeExact (vs invoke) + staticMethodHandle = lookup.findVirtual(fl.getClass(), "warn", + MethodType.methodType(Void.TYPE, String.class, Throwable.class)) + .asType(MethodType.methodType(Void.TYPE, LongSupplier.class/*this*/, + /*args:*/ String.class, Throwable.class)); + } catch (IllegalAccessException | NoSuchMethodException e) { + throw new IllegalStateException(e); + } + } + + @Test public void speedStaticMethodHandle () throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { + Class cls = Class.forName("org.jooq.lambda.ExtraMagicTest$FakeLogger"); + final LongSupplier fl = (LongSupplier) cls.getConstructor().newInstance(); + + String st = Loops.loopMeasuredWarm(MAX_LOOP, Unchecked.runnable(() -> { + staticMethodHandle.invokeExact(fl, "message-to-log: MH", LOG_EXCEPTION);//vs invoke (ivoke is slower, but w/o .asType↑) + //invokeExact→java.lang.invoke.WrongMethodTypeException: expected (FakeLogger,String,Throwable)void but found (LongSupplier,String,Exception)void + })).toString(); + System.out.println("*** speedStaticMethodHandle →\t\t"+st); + assertEquals(MAX_LOOP_WARM, fl.getAsLong()); + } + + + private static final Method staticMethod; + static { + Object fl = getActualLogger("org.jooq.lambda.ExtraMagicTest$FakeLogger", ExtraMagicTest.class); + staticMethod = LambdaLogFacade.getWarnMethod(fl); + } + @Test public void speedStaticReflection () throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { + Class cls = Class.forName("org.jooq.lambda.ExtraMagicTest$FakeLogger"); + final LongSupplier fl = (LongSupplier) cls.getConstructor().newInstance(); + + String st = Loops.loopMeasuredWarm(MAX_LOOP, Unchecked.runnable(() -> + staticMethod.invoke(fl, "message-to-log: Reflection", LOG_EXCEPTION))).toString(); + System.out.println("*** speedStaticReflection →\t\t"+st); + assertEquals(MAX_LOOP_WARM, fl.getAsLong()); + } + + + private static final Consumer3 staticLambda; + static {// Static Lambda setup ^ + try { + Object fl = getActualLogger("org.jooq.lambda.ExtraMagicTest$FakeLogger", ExtraMagicTest.class); + + MethodHandles.Lookup lookup = MethodHandles.lookup(); + //1. method → MethodHandle + Method m = LambdaLogFacade.getWarnMethod(fl); + MethodHandle mhLogWarn = lookup.unreflect(m); + + MethodType genericMethodType = MethodType.methodType(Void.TYPE, fl.getClass()/*logger*/, String.class, Throwable.class); + + CallSite callSite = LambdaMetafactory.metafactory( + lookup,// method handle lookup + "accept",//Interface Method Name: name of the method defined in the target functional interface: Consumer::accept + + // type to be implemented and captured objects + // e.g. String instance to be trimmed is captured: MethodType.methodType(Supplier.class, String.class) + MethodType.methodType(Consumer3.class), + + // type erasure, Consumer3 will accept 3 Object NOT Void.TYPE, Object.class/*logger*/, String.class, Throwable.class + MethodType.methodType(Void.TYPE, Object.class/*logger*/, Object.class, Object.class), + + mhLogWarn,// method handle to transform + + // Consumer3 method real signature (reified) + // e.g. Supplier=trim accepts no parameters and returns String: MethodType.methodType(String.class) + genericMethodType); + + //noinspection unchecked + staticLambda = (Consumer3) callSite.getTarget() + /*.bindTo(contextObject e.g. "str")*/ + .invokeExact();// or invoke + + } catch (Throwable invokeExactEx) { + invokeExactEx.printStackTrace(); + throw new IllegalStateException(invokeExactEx); + } + } + @Test public void speedStaticLambda () { + Object fl = getActualLogger("org.jooq.lambda.ExtraMagicTest$FakeLogger", ExtraMagicTest.class); + + String st = Loops.loopMeasuredWarm(MAX_LOOP, Unchecked.runnable(() -> + staticLambda.accept(fl, "message-to-log: StaticLambda", LOG_EXCEPTION))).toString(); + System.out.println("*** speedStaticLambda →\t\t"+st); + assertEquals(MAX_LOOP_WARM, ((LongSupplier) fl).getAsLong()); + } + + /** Get slf4j.Logger, JUL Logger, or log4j Logger */ + static Object getActualLogger (String loggerFactoryClassName, Class clazzWhereLogger) { + Method loggerFactoryGetLogger = LambdaLogFacade.findLoggerFactoryGetLogger(loggerFactoryClassName); + if (loggerFactoryGetLogger == null) { return null;}// LoggerFactory not found in classpath + return LambdaLogFacade.invokeGetLogger(loggerFactoryGetLogger, clazzWhereLogger); + } + + + @Test public void lambdaLogFacadeLoggerTest () throws InterruptedException { + LambdaLogFacade log = LambdaLogFacade.getLogger(ExtraMagicTest.class); + assertSame(ExtraMagicTest.class, log.loggerAppClassName);// ^^^ + + printToStdErr(null, "#1 staticLoggerFactoryGetLoggerMethod= "+LambdaLogFacade.staticLoggerFactoryGetLoggerMethod, null); + printToStdErr(null, "#2 staticWarnMethodHandle= "+LambdaLogFacade.staticWarnMethodHandle, null); + assertEquals(winner, LambdaLogFacade.staticLoggerFactoryGetLoggerMethod); + + log.warn("lambdaLogFacade #1", null); + log.warn("lambdaLogFacade #2", new Throwable("#2 Test Throwable")); + log.warn("lambdaLogFacade #3", new Error("#3 Test Error")); + String msg = "lambdaLogFacade #4"; + Exception t = new Exception("#4 Test Error"); + log.warn(msg, t); + if (winner != null && winner.toString().contains("LoggerOverride")) { + assertEquals(4, LoggerOverride.CNT.get()); + assertSame(msg, LoggerOverride.lastMessage); + assertSame(t, LoggerOverride.lastThrowable); + } else { + System.err.println("WINNER is not LoggerOverride, so no checks"); + } + + final int THREADS = 100; + final CountDownLatch startSignal = new CountDownLatch(1); + final CountDownLatch doneSignal = new CountDownLatch(THREADS); + loop(THREADS, (num) -> new Thread(()->{ + Wrap.run(startSignal::await); + log.warn("Hello from thread "+num, new Exception("Thread "+num)); + loop(999, () -> log.warn("Hello from thread "+num, null)); + + Wrap.run(doneSignal::countDown); + }, "lambdaLogFacade-"+num).start()); + startSignal.countDown();// let's go! + doneSignal.await(); + assertNull(FAILED); + + if (winner != null && winner.toString().contains("LoggerOverride")) { + assertEquals(THREADS * 1000 + 4, LoggerOverride.CNT.get()); + } + } + + public static class LoggerOverride extends LambdaLogFacade { + public LoggerOverride () { + super(null); + }//new + + static final AtomicLong CNT = new AtomicLong(); + static String lastMessage; + static Throwable lastThrowable; + + public static LoggerOverride getLogger (String notUsed) { + return new LoggerOverride(); + } + @Override public void warn (String msg, Throwable t) { + CNT.incrementAndGet(); + lastMessage = msg; + lastThrowable = t; + if (t != null || msg.startsWith("lambda")) { + System.out.println("LoggerOverride.warn >>> "+msg+"\t>>> "+t+" # "+Thread.currentThread()); + } + } + }//LoggerOverride + + @Test public void lambdaLogFacadeToStdErr () { + LambdaLogFacade.LambdaLogFacadeStdErr log = new LambdaLogFacade.LambdaLogFacadeStdErr(ExtraMagicTest.class); + assertSame(ExtraMagicTest.class, log.loggerAppClassName);// ^^^ + log.warn("Test message to System.err #1", null); + log.warn("Test message to System.err #2 'with Throwable/Exception'", + new IOException("#2 Test Throwable/Exception to System.err")); + } + +} \ No newline at end of file diff --git a/jOOL-java-8/src/test/java/org/jooq/lambda/LoopsTest.java b/jOOL-java-8/src/test/java/org/jooq/lambda/LoopsTest.java new file mode 100644 index 00000000..584616f7 --- /dev/null +++ b/jOOL-java-8/src/test/java/org/jooq/lambda/LoopsTest.java @@ -0,0 +1,266 @@ +package org.jooq.lambda; + +import org.jooq.lambda.tuple.Tuple4; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.LongSummaryStatistics; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.LongConsumer; +import java.util.function.LongPredicate; +import java.util.function.Predicate; + +import static org.jooq.lambda.Loops.loop; +import static org.jooq.lambda.Loops.loopMeasured; +import static org.jooq.lambda.Loops.loopMeasuredWarm; +import static org.jooq.lambda.Loops.loopWhile; +import static org.junit.Assert.*; + +public class LoopsTest { + + static class LongSummaryStatisticsP extends LongSummaryStatistics implements LongPredicate { + int stopAt; + + public LongSummaryStatisticsP (int min) { stopAt = min; }//new + public LongSummaryStatisticsP () {}//new + + @Override public boolean test (long value) { + if (value < stopAt) return false;//stop + accept(value); + return true; + } + } + + @Test public void testLoopRunnable () { + loop(0, (Runnable) null); + loop(-2, (Runnable) null); + AtomicLong counter = new AtomicLong(); + Runnable r = counter::incrementAndGet; + + loop(0, r); + assertEquals(0, counter.get()); + + loop(-1, r); + assertEquals(0, counter.get()); + + loop(1, r); + assertEquals(1, counter.get()); + + loop(10_123, r); + assertEquals(10_124, counter.get()); + } + + @Test public void testLoopConsumer () { + loop(0, (LongConsumer) null); + loop(-2, (LongConsumer) null); + final LongSummaryStatistics stat = new LongSummaryStatistics(); + + loop(0, stat); + assertEquals(0, stat.getCount()); + + loop(-1, stat); + assertEquals(0, stat.getCount()); + + loop(1, stat); + assertEquals(1, stat.getCount()); + + loop(10_123, stat); + assertEquals(10_124, stat.getCount()); + assertEquals(10_122, stat.getMax());// 10_123 = 10_122..0 + assertEquals(0, stat.getMin()); + } + + @Test public void testLoopPredicate () { + loopWhile(0, null); + loopWhile(-2, null); + final LongSummaryStatisticsP s = new LongSummaryStatisticsP(); + + loopWhile(0, s); + assertEquals(0, s.getCount()); + + loopWhile(-1, s); + assertEquals(0, s.getCount()); + + loopWhile(1, s); + assertEquals(1, s.getCount()); + + loopWhile(10_123, s); + assertEquals(10_124, s.getCount()); + assertEquals(10_122, s.getMax());// 10_123 = 10_122..0 + assertEquals(0, s.getMin()); + } + + @Test public void testLoopPredicateDoWhile () { + final LongSummaryStatisticsP s = new LongSummaryStatisticsP(10); + + loopWhile(0, s); + assertEquals(0, s.getCount()); + + loopWhile(-1, s); + assertEquals(0, s.getCount()); + + loopWhile(1, s); + assertEquals(0, s.getCount()); + + loopWhile(10_123, s); + assertEquals(10_123-10, s.getCount());//10 = 0..9 + assertEquals(10_122, s.getMax());// 10_123 is max, starting with 10_122 + assertEquals(10, s.getMin()); + } + + + @Test public void testLoopMeasured () { + Tuple4 st = loopMeasured(0, null); + System.out.println(st); + assertEquals("LongSummaryStatistics{count=0, sum=0, min=9223372036854775807, average=0,000000, max=-9223372036854775808}", st.v2.toString()); + st = loopMeasured(0, null); + assertEquals(0, st.v2.getCount()); + st = loopMeasured(-2, null); + assertEquals(0, st.v2.getCount()); + + st = loopMeasured(1, null); + assertTrue(st.v3.toString().startsWith("java.lang.NullPointerException: Cannot invoke \"java.lang.Runnable.run()\" because \"body\" is null")); + assertEquals(1, st.v2.getCount()); + + final AtomicLong counter = new AtomicLong(); + final Runnable r = counter::incrementAndGet; + + st = loopMeasured(0, r); + System.out.println(st); + assertEquals(0, counter.get()); + assertEquals(0, st.v2.getCount()); + + st = loopMeasured(-1, r); + assertEquals(0, counter.get()); + assertEquals(0, st.v2.getCount()); + + st = loopMeasured(1, r); + System.out.println(st); + assertEquals(1, counter.get()); + assertEquals(1, st.v2.getCount()); + + st = loopMeasured(10_123, r); + System.out.println(st); + assertEquals(10_124, counter.get()); + assertEquals(10_123, st.v2.getCount()); + } + + + @Test public void testLoopMeasuredWarm () { + final AtomicLong counter = new AtomicLong(); + Tuple4 st = loopMeasuredWarm(10_000_000, counter::incrementAndGet); + System.out.println(st); + assertEquals(10_000_000, st.v2.getCount()); + assertEquals(10_050_000, counter.get()); + } + + + @Test public void testIncrement () { + Loops.Incrementer x = new Loops.Incrementer(3, 100); + assertEquals(3, x.degree()); + for (int i=0; i<100; i++) { + for (int j=0; j<100; j++) { + for (int k=0; k<100; k++) { + assertEquals(i, x.indexes[2]); + assertEquals(j, x.indexes[1]); + assertEquals(k, x.indexAt(0)); + boolean overflow = x.incrementIndexVector(); + assertEquals(i==99 && j==99 && k==99, overflow); + } + } + } + + x = new Loops.Incrementer(16, 2); + assertEquals(16, x.degree()); + for (int i=0; i<0x1_00_00; i++) { + int tmp = i; + for (int j=0; j<16; j++) { + assertEquals(tmp & 1, x.indexes[j]); + tmp = tmp >> 1; + } + boolean overflow = x.incrementIndexVector();// 0..1 + assertEquals(i==0xFF_FF, overflow); + } + + x = new Loops.Incrementer(5000, 1); + assertEquals(5000, x.degree()); + assertTrue(x.incrementIndexVector());//only one valid state 0,0,0,0,... + } + + @Test public void testIncrement2 () { + int[] max = {200,50,10}; + Loops.Incrementer x = new Loops.Incrementer(max); + assertEquals(3, x.degree()); + for (int i=0; i<10; i++) { + for (int j=0; j<50; j++) { + for (int k=0; k<200; k++) { + assertEquals(i, x.indexes[2]); + assertEquals(j, x.indexes[1]); + assertEquals(k, x.indexes[0]); + boolean overflow = x.incrementIndexVector(); + assertEquals(i==9 && j==49 && k==199, overflow); + } + } + } + assertEquals("Incrementer[0, 0, 0]", x.toString()); + assertEquals(200, x.maxAt(0)); + assertEquals(50, x.maxAt(1)); + max[2] = 42; + assertEquals(42, x.maxAt(2)); + + max = new int[16]; + Arrays.fill(max, 2); + x = new Loops.Incrementer(max); + assertEquals(16, x.degree()); + for (int i=0; i<0x1_00_00; i++) { + int tmp = i; + for (int j=0; j<16; j++) { + assertEquals(tmp & 1, x.indexes[j]); + tmp = tmp >> 1; + } + boolean overflow = x.incrementIndexVector();// 0..1 + assertEquals(i==0xFF_FF, overflow); + } + + max = new int[1000]; + Arrays.fill(max, 1); + x = new Loops.Incrementer(max); + assertEquals(1000, x.degree()); + assertTrue(x.incrementIndexVector()); + } + + + @Test public void testForLoop () { + int[] arr = new int[11]; + Loops.forLoop(arr.length, (i)->{arr[i]=i;}); + assertEquals("[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]", Arrays.toString(arr)); + + List list = new ArrayList<>(100); + + Predicate gen = (inc)->{ + list.add(inc.indexAt(1)+"*"+inc.indexAt(0)+"="+inc.indexAt(1)*inc.indexAt(0)); + return list.size()>=100; + }; + + Loops.Incrementer x = new Loops.Incrementer(2, 10); + assertTrue(x.forLoop(gen)); + for (int i=0; i<10; i++) { + for (int j=0; j<10; j++) { + assertEquals(i+"*"+j+"="+i*j, list.get(i*10+j)); + } + } + + list.clear(); + x = new Loops.Incrementer(new int[]{10,10}); + assertTrue(x.forLoop(gen)); + for (int i=0; i<10; i++) { + for (int j=0; j<10; j++) { + assertEquals(i+"*"+j+"="+i*j, list.get(i*10+j)); + } + } + } + + +} \ No newline at end of file diff --git a/jOOL-java-8/src/test/java/org/jooq/lambda/WrapTest.java b/jOOL-java-8/src/test/java/org/jooq/lambda/WrapTest.java new file mode 100644 index 00000000..b6b7cdde --- /dev/null +++ b/jOOL-java-8/src/test/java/org/jooq/lambda/WrapTest.java @@ -0,0 +1,857 @@ +package org.jooq.lambda; + +import org.jooq.lambda.fi.util.concurrent.SafeCallable; +import org.jooq.lambda.fi.util.function.CheckedBiFunction; +import org.jooq.lambda.fi.util.function.CheckedToDoubleBiFunction; +import org.jooq.lambda.tuple.Tuple2; +import org.junit.Test; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.ArrayList; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Optional; +import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Supplier; +import java.util.stream.Stream; + +import static org.jooq.lambda.Wrap.predicate; +import static org.jooq.lambda.Wrap.predicateDef; +import static org.junit.Assert.*; + +public class WrapTest { + + @Test(expected = ClassCastException.class) + public void testCastUnsafe () { + //java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Integer (java.lang.String and java.lang.Integer are in module java.base of loader 'bootstrap') + Integer x = Wrap.castUnsafe("1"); + System.err.println(x); + } + @Test(expected = ClassCastException.class) + public void testCast () { + //java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Integer (java.lang.String and java.lang.Integer are in module java.base of loader 'bootstrap') + Integer x = Wrap.cast(Integer.class, "1"); + System.err.println(x); + } + + @Test public void castUnsafe () { + Number o = 42L; + long v = Wrap.castUnsafe(o); + assertEquals(42, v); + + Object x = new ArrayList(); + List y = Wrap.castUnsafe(x); + y.add("test"); + + List l1 = new ArrayList<>(); + List l2 = Wrap.castUnsafe(l1);// dangerous! Don't use for this! + l2.add("test");// → add "test" to List l1 + Object boom1 = l1.get(0); + Object boom2 = l2.get(0); + assertSame(boom1, boom2); + assertEquals("test", boom1); + } + @Test public void cast () { + Number o = 42L; + long v = Wrap.cast(Long.class, o); + assertEquals(42, v); + + Object x = new ArrayList(); + List y = Wrap.cast(List.class, x); + y.add("test"); + + List l1 = new ArrayList<>(); + List l2 = Wrap.cast(List.class, l1);// dangerous! Don't use for this! + l2.add("test");// → add "test" to List l1 + Object boom1 = l1.get(0); + Object boom2 = l2.get(0); + assertSame(boom1, boom2); + assertEquals("test", boom1); + assertEquals(1, l1.size()); + } + + @Test(expected = NullPointerException.class) + public void castUnsafeNullToPrimitive () { + Boolean b1 = null; + try { + Boolean b2 = Wrap.castUnsafe(b1); + assertNull(b2); + } catch (Throwable e) { + fail("(Boolean) null must be just fine "+e); + } + + boolean b3 = Wrap.castUnsafe(b1); + fail("^^^ NPE!"); + } + @Test(expected = NullPointerException.class) + public void castNullToPrimitive () { + Boolean b1 = null; + try { + Boolean b2 = Wrap.cast(boolean.class, b1); + assertNull(b2); + } catch (Throwable e) { + fail("(Boolean) null must be just fine "+e); + } + + boolean b3 = Wrap.cast(boolean.class, b1); + fail("^^^ NPE!"); + } + + + + @Test public void testCallable () throws Throwable { + { + Callable callable = Wrap.callableDef(() -> { + throw new IOException("log me"); + }, "");//with default value + assertTrue(callable instanceof SafeCallable.Generated); + assertEquals("", callable.call()); + assertEquals("", ((Supplier) callable).get()); + ((SafeCallable) callable).execute(); + assertNull(((SafeCallable) callable).handleThrowable(null)); + } + { + SafeCallable> c2 = Wrap.callable(" xxx "::trim); + assertTrue(c2 instanceof SafeCallable.Generated); + assertEquals("Either(xxx)", c2.call().toString()); + assertEquals("xxx", c2.get().v1); + assertEquals("xxx", c2.call().call()); + assertEquals("xxx", c2.execute().optValue().orElse(null)); + assertNull(c2.handleThrowable(null)); + + System.err.println("*** NullPointerException with Either"); + + c2 = Wrap.callable(() -> new String((char[]) null)); + assertTrue(c2 instanceof SafeCallable.Generated); + assertTrue(c2.get().v2 instanceof NullPointerException); + assertFalse(c2.call().optValue().isPresent()); + assertFalse(c2.execute().isPresent()); + assertTrue(c2.call().isFailure()); + assertTrue(c2.call().isEmpty()); + assertNull(c2.handleThrowable(null)); + } + { + SafeCallable.Generated c = Wrap.cast(SafeCallable.Generated.class, + Wrap.callable(WrapTest::divZero, (Throwable t)-> + { + assertTrue(t.toString(), t instanceof ArithmeticException); + return 42; + })); + assertEquals(42, c.get().intValue()); + assertEquals(42, c.call().intValue()); + assertEquals(42, c.execute().intValue()); + assertNull(c.handleThrowable(new Information("not used in Generated"))); + } + } + + static class Information extends IOException { + static final long serialVersionUID = 1;// make javac and error-prone happy + public Information (Object message) { super(message.toString());} + @Override public synchronized Throwable fillInStackTrace () { return this;} + } + + + @Test public void testPredicate () { + Object[] arr = {1,2,3, null, "str", 3.14, true, (byte)42}; + + long len = Stream.of(arr).filter( + predicate((value) -> ((Integer) value) > 0) + ).count(); + assertEquals(3, len); + + len = Seq.of(arr).filter( + predicateDef((v)->Double.parseDouble(v.toString())>0, true) + ).count(); + assertEquals(arr.length, len); + + len = Seq.of(arr).filter( + predicateDef((v)->Double.parseDouble(v.toString())>0, false) + ).count(); + assertEquals(5, len);// false only for 3: null, "str", true + + // NullPointerException: Cannot invoke "java.lang.Number.intValue()" because "v" is null + // ClassCastException: String, Boolean cannot be cast to Number + len = Seq.of(arr).filter( + predicate((v)->((Number) v).intValue() > 0, (a,t)-> + { + if (a == null) { + assertTrue(t instanceof NullPointerException); + return true; + } + return false; + }) + ).count(); + assertEquals(6, len);// 5 +1 null + } + + + @Test public void eitherNull () throws Exception { + Either zzz = Either.success(null); + assertEquals(zzz, zzz); + assertEquals(zzz, Either.empty()); + assertEquals(Either.success(null), Either.success(null)); + assertEquals(zzz, Optional.empty()); + + Either ei = Either.success(null); + assertEquals(new Tuple2(null,null), ei); + assertNull(ei.call()); + assertTrue(ei.isSuccess()); + assertFalse(ei.isFailure()); + assertFalse(ei.isPresent()); + assertTrue(ei.isEmpty()); + assertTrue(ei.isNull()); + assertEquals(0, ei.stream().count()); + assertEquals(31*31, ei.hashCode()); + assertEquals("Either.Empty", ei.toString()); + + ei.ifPresent((value)->fail("null==empty==!present")); + assertNull(ei.v2); + assertEquals(Optional.empty(), ei.optThrowable()); + ei.throwIfFailure(); + + AtomicInteger cnt = new AtomicInteger(); + ei.ifEmpty((Throwable t) -> { + assertNull(t); + cnt.incrementAndGet(); + }); + assertEquals(1, cnt.get()); + ei.ifNull(cnt::incrementAndGet); + assertEquals(2, cnt.get()); + ei.ifFailure((t)->fail("null==success==!failure")); + ei.ifSuccess((Integer v) -> { + assertNull(v); + cnt.incrementAndGet(); + }); + assertEquals(3, cnt.get()); + try { + ei.throwIfEmpty(); + fail("unreachable: null value == !present"); + } catch (NoSuchElementException e) { + assertEquals("java.util.NoSuchElementException: No value present", e.toString()); + } + try { + ei.throwIfNull(); + fail("unreachable: null value == !present"); + } catch (NoSuchElementException e) { + assertEquals("java.util.NoSuchElementException: No value present", e.toString()); + } + } + + @Test public void eitherValue () throws Exception { + Either zzz = Either.success(9); + assertEquals(zzz, zzz); + assertEquals(zzz, Either.success(9)); + assertEquals(zzz, 9); + assertEquals(9, zzz.v1.intValue()); + assertEquals(9, zzz.optValue().get().intValue()); + assertNull(zzz.v2); + + Either ei = Either.success(9); + assertEquals(new Tuple2(9,null), ei); + assertEquals(9, ei.call().intValue()); + assertTrue(ei.isSuccess()); + assertFalse(ei.isFailure()); + assertTrue(ei.isPresent()); + assertFalse(ei.isEmpty()); + assertFalse(ei.isNull()); + assertEquals(1, ei.stream().count()); + assertEquals(9, ei.stream().toArray()[0]); + assertEquals((31+9)*31, ei.hashCode()); + assertEquals("Either(9)", ei.toString()); + assertNull(ei.v2); + assertEquals(Optional.empty(), ei.optThrowable()); + ei.throwIfFailure().throwIfNull().throwIfEmpty(); + + AtomicInteger cnt = new AtomicInteger(); + ei.ifPresent((Integer v)->cnt.incrementAndGet()); + assertEquals(1, cnt.get()); + + ei.ifEmpty((Throwable t)->fail("!empty")); + ei.ifNull(()->fail("!null")); + ei.ifFailure((Throwable t)->fail("null==success==!failure")); + ei.ifSuccess((Integer v) -> { + assertEquals(9, v.intValue()); + cnt.incrementAndGet(); + }); + assertEquals(2, cnt.get()); + assertEquals(9, ei.call().intValue()); + assertEquals(9, ei.v1.intValue()); + assertEquals(9, ei.optValue().get().intValue()); + assertEquals(ei, Optional.of(9)); + } + + @Test public void eitherThrowable () throws Exception { + Information ex = new Information("I am Either.Failure!"); + Either zzz = Either.failure(ex); + assertEquals(zzz, zzz); + assertNotEquals(zzz, null); + assertEquals(zzz, Either.failure(ex)); + //assertEquals(Either.failure(ex), Optional.empty()); + assertEquals(Either.failure(ex), ex); + + Either ei = Either.failure(ex); + assertEquals(new Tuple2(null,ex), ei); + + try { + ei.call(); + fail("unracahble: ^ throws ex"); + } catch (Information ex2) { + assertSame(ex, ex2); + } + assertFalse(ei.isSuccess()); + assertTrue(ei.isFailure()); + assertFalse(ei.isPresent()); + assertTrue(ei.isEmpty()); + assertFalse(ei.isNull()); + assertEquals(0, ei.stream().count()); + assertTrue(ei.hashCode() != 0); + assertEquals("Either.Failure(org.jooq.lambda.WrapTest$Information: I am Either.Failure!)", ei.toString()); + + ei.ifPresent((value)->fail("null==empty==!present")); + assertSame(ex, ei.v2); + assertSame(ex, ei.optThrowable().get()); + assertNull(ei.v1); + assertEquals(Optional.empty(), ei.optValue()); + try { + ei.throwIfFailure(); + fail("unracahble: ^ throws"); + } catch (IllegalStateException x) { + assertSame(ex, x.getCause()); + assertEquals("java.lang.IllegalStateException: Throwable instead of value", x.toString()); + } + + AtomicInteger cnt = new AtomicInteger(); + ei.ifEmpty((Throwable t) -> { + assertSame(ex, t); + cnt.incrementAndGet(); + }); + assertEquals(1, cnt.get()); + ei.ifNull(()->fail("failure != null")); + ei.ifFailure((Throwable t) -> { + assertSame(ex, t); + cnt.incrementAndGet(); + }); + assertEquals(2, cnt.get()); + + ei.ifSuccess((Integer v)->fail("failure!")); + try { + ei.throwIfEmpty(); + fail("unreachable: isFailure"); + } catch (IllegalStateException e) { + assertEquals("java.lang.IllegalStateException: Throwable instead of value", e.toString()); + } + ei.throwIfNull(); + } + + + @Test public void eitherMix () { + Either z = Either.success(null); + z.consume((v,t)->{ + assertNull(v); + assertNull(t); + }); + assertEquals("Either.Empty", z.toString()); + assertNull(z.either()); + + z = Either.success(""); + z.consume((v,t)->{ + assertEquals("", v); + assertNull(t); + }); + assertEquals("Either()", z.toString()); + assertEquals("", z.either()); + + Information ex = new Information("{x}"); + z = Either.failure(ex); + z.consume((v,t)->{ + assertNull(v); + assertSame(ex, t); + }); + assertEquals("Either.Failure(org.jooq.lambda.WrapTest$Information: {x})", z.toString()); + assertEquals(ex, z.either()); + } + + + @Test public void directRunAndCall () { + assertTrue(Wrap.run(()->{})); + assertTrue(Wrap.runStd(()->{})); + assertFalse(Wrap.run(()->{throw new Information("#1");})); + assertFalse(Wrap.runStd(()->{throw new RuntimeException("#2");})); + + assertEquals(Either.empty(), Wrap.call(()->null)); + assertEquals(Either.empty(), Wrap.callStd(()->null)); + assertEquals(42, Wrap.call(()->42).v1.intValue()); + assertEquals(3.14, (Object) Wrap.callStd(()->3.14).v1); + assertEquals("Either.Failure(org.jooq.lambda.WrapTest$Information: Hi!)", + Wrap.call(()->{throw new Information("Hi!");}).toString()); + assertEquals("Either.Failure(java.lang.ArithmeticException: / by zero)", + Wrap.callStd(()->1/0).toString()); + } + + + @Test public void testRunnable () { + Wrap.runnable(()->{}).run(); + + AtomicInteger cnt = new AtomicInteger(); + Wrap.runnable(cnt::incrementAndGet).run(); + assertEquals(1, cnt.get()); + + Wrap.runnable(null).run(); + } + + + @Test public void safeThrows () { + Exception e = new Exception("Checked!"); + IOException io = new IOException(); + InterruptedException ie = new InterruptedException(); + Wrap.throwIfError(e); + Wrap.throwIfError(new RuntimeException()); + Wrap.throwIfError(io); + Thread.interrupted(); + Wrap.throwIfError(ie); + assertTrue(Thread.interrupted()); + + Wrap.throwIfErrorOrRuntime(e); + Wrap.throwIfErrorOrRuntime(io); + Wrap.throwIfErrorOrRuntime(ie); + assertTrue(Thread.interrupted()); + + Wrap.throwIfErrorOrRuntimeOrIo(e); + Wrap.throwIfErrorOrRuntimeOrIo(ie); + assertTrue(Thread.interrupted()); + assertFalse(Thread.interrupted()); + + Wrap.handleInterruptedException(ie); + assertTrue(Thread.interrupted()); + assertFalse(Thread.interrupted()); + + Wrap.handleInterruptedException((Throwable)ie); + assertTrue(Thread.interrupted()); + assertFalse(Thread.interrupted()); + } + + + @Test(expected = Error.class) + public void throw1 () { + Wrap.throwIfError(new Error()); + } + + @Test(expected = RuntimeException.class) + public void throw2 () { + Wrap.throwIfErrorOrRuntime(new RuntimeException()); + } + + @Test(expected = UncheckedIOException.class) + public void throw3 () { + Wrap.throwIfErrorOrRuntimeOrIo(new Information(1)); + // java.io.UncheckedIOException: org.jooq.lambda.WrapTest$Information: 1 + } + + + @Test public void testPredicates () { + assertTrue(Wrap.predicate((Boolean v)->v).test(true)); + assertFalse(Wrap.predicate((Boolean v)->v).test(false)); + assertFalse(Wrap.predicate((Boolean v)->v).test(null)); + + assertTrue(Wrap.predicateDef((Boolean v)->v, true).test(true)); + assertFalse(Wrap.predicateDef((Boolean v)->v, true).test(false)); + assertTrue(Wrap.predicateDef((Boolean v)->v, true).test(null)); + + assertTrue(Wrap.predicate((Boolean v)->v, (Boolean v,Throwable t)->{ + throw new AssertionError("unreachable");}).test(true)); + assertFalse(Wrap.predicate((Boolean v)->v, (Boolean v,Throwable t)->{ + throw new AssertionError("unreachable");}).test(false)); + assertTrue(Wrap.predicate((Boolean v)->v, (Boolean v,Throwable t)->{ + assertNull(v); + assertTrue(t instanceof NullPointerException); + return true;}).test(null)); + } + + @Test public void testBiPredicates () { + assertTrue(Wrap.biPredicate((Byte x,Byte y)->xxxxxxx{ + throw new AssertionError("unreachable");}).test((byte)1,(byte)2)); + assertFalse(Wrap.biPredicate((Byte x,Byte y)->x{ + throw new AssertionError("unreachable");}).test((byte)1,(byte)1)); + assertTrue(Wrap.biPredicate((Byte x,Byte y)->x{ + assertNull(x); + assertEquals((byte)2,(Object)y); + assertTrue(t instanceof NullPointerException); + return true;}).test(null,(byte)2)); + } + + @Test public void testDoublePredicates () { + assertTrue(Wrap.doublePredicate((double v)->v>0).test(1)); + assertFalse(Wrap.doublePredicate((double v)->v>0).test(-1)); + assertFalse(Wrap.doublePredicate((double v)->{throw new Exception();}).test(1)); + + assertTrue(Wrap.doublePredicateDef((double v)->v>0, true).test(1)); + assertFalse(Wrap.doublePredicateDef((double v)->v>0, true).test(-1)); + assertTrue(Wrap.doublePredicateDef((double v)->{throw new Exception();}, true).test(0)); + + assertTrue(Wrap.doublePredicate((double v)->v>0, (Double v,Throwable t)->{ + throw new AssertionError("unreachable");}).test(1)); + assertFalse(Wrap.doublePredicate((double v)->v>1, (Double v,Throwable t)->{ + throw new AssertionError("unreachable");}).test(0)); + assertTrue(Wrap.doublePredicate((double v)->{throw new IOException();}, (Double v,Throwable t)->{ + assertEquals(1, v, 0.01); + assertTrue(t instanceof IOException); + return true;}).test(1)); + } + + @Test public void testLongPredicates () { + assertTrue(Wrap.longPredicate((long v)->v>0).test(1)); + assertFalse(Wrap.longPredicate((long v)->v>0).test(-1)); + assertFalse(Wrap.longPredicate((long v)->{throw new Exception();}).test(1)); + + assertTrue(Wrap.longPredicateDef((long v)->v>0, true).test(1)); + assertFalse(Wrap.longPredicateDef((long v)->v>0, true).test(-1)); + assertTrue(Wrap.longPredicateDef((long v)->{throw new Exception();}, true).test(0)); + + assertTrue(Wrap.longPredicate((long v)->v>0, (Long v,Throwable t)->{ + throw new AssertionError("unreachable");}).test(1)); + assertFalse(Wrap.longPredicate((long v)->v>1, (Long v,Throwable t)->{ + throw new AssertionError("unreachable");}).test(0)); + assertTrue(Wrap.longPredicate((long v)->{throw new IOException();}, (Long v,Throwable t)->{ + assertEquals(1, v.longValue()); + assertTrue(t instanceof IOException); + return true;}).test(1)); + } + + @Test public void testIntPredicates () { + assertTrue(Wrap.intPredicate((int v)->v>0).test(1)); + assertFalse(Wrap.intPredicate((int v)->v>0).test(-1)); + assertFalse(Wrap.intPredicate((int v)->{throw new Exception();}).test(1)); + + assertTrue(Wrap.intPredicateDef((int v)->v>0, true).test(1)); + assertFalse(Wrap.intPredicateDef((int v)->v>0, true).test(-1)); + assertTrue(Wrap.intPredicateDef((int v)->{throw new Exception();}, true).test(0)); + + assertTrue(Wrap.intPredicate((int v)->v>0, (Integer v,Throwable t)->{ + throw new AssertionError("unreachable");}).test(1)); + assertFalse(Wrap.intPredicate((int v)->v>1, (Integer v,Throwable t)->{ + throw new AssertionError("unreachable");}).test(0)); + assertTrue(Wrap.intPredicate((int v)->{throw new IOException();}, (Integer v,Throwable t)->{ + assertEquals(1, v, 0.01); + assertTrue(t instanceof IOException); + return true;}).test(1)); + } + + + @Test public void predicateWithLogHandler () { + assertTrue(Wrap.predicate((v)->{throw new IOException();}, + (Object v, Throwable t)->{ + assertEquals(1, v); + assertTrue(t instanceof IOException); + return true; + }).test(1)); + assertTrue(Wrap.predicate((v)->{throw new IOException();}, + Wrap.P1_LOG_WARN_TRUE + ).test(1)); + assertTrue(Wrap.predicate((v)->{throw new IOException();}, + Wrap.P1_SILENT_IGNORE_ALL_TRUE + ).test(1)); + assertFalse(Wrap.predicate((v)->{throw new IOException();}, + Wrap.P1_SILENT_IGNORE_ALL_FALSE + ).test(1)); + } + + + @Test public void testFunctions () { + assertEquals("Either(9)", Wrap.function((i)->""+i).apply(9).toString()); + assertEquals("9", Wrap.function((i)->""+i, (i,t)->{ + assertEquals(9, i); + assertNull(t); + return null; + }).apply(9)); + assertEquals("9", Wrap.functionDef((i)->""+i, "x").apply(9)); + + assertEquals("Either.Failure(org.jooq.lambda.WrapTest$Information: f1.1)", + Wrap.function((i)->{throw new Information("f1.1");}).apply(9).toString()); + assertEquals("H", Wrap.function((i)->{throw new Information("f1.2");}, (i,t)->{ + assertEquals(9, i); + assertTrue(t instanceof Information); + return "H"; + }).apply(9)); + assertEquals("x", Wrap.functionDef((i)->{throw new Information("f1.3");}, "x").apply(9)); + // + CheckedBiFunction cbif = (a,b)->""+a+b; + assertEquals("Either(12)", Wrap.biFunction(cbif).apply(1,2).toString()); + assertEquals("12", Wrap.biFunction(cbif, (a,b,t)->{ + assertEquals((Integer)1, a); + assertEquals((Integer)2, b); + assertNull(t); + return null; + }).apply(1,2)); + assertEquals("12", Wrap.biFunctionDef(cbif, "x").apply(1,2)); + + assertEquals("Either.Failure(org.jooq.lambda.WrapTest$Information: f2.1)", + Wrap.biFunction((a,b)->{throw new Information("f2.1");}).apply(1,2).toString()); + assertEquals("H", Wrap.biFunction((a,b)->{throw new Information("f2.2");}, (a,b,t)->{ + assertEquals(1, a); + assertEquals(2, b); + assertTrue(t instanceof Information); + return "H"; + }).apply(1,2)); + assertEquals("x", Wrap.biFunctionDef((a,b)->{throw new Information("f2.3");}, "x").apply(1,2)); + // + assertEquals("Either(9.1)", Wrap.doubleFunction((d)->""+d).apply(9.1).toString()); + assertEquals("9.1", Wrap.doubleFunction((d)->""+d, (d,t)->{ + assertEquals(9.1, d, 0.01); + assertNull(t); + return null; + }).apply(9.1)); + assertEquals("9.1", Wrap.doubleFunctionDef((d)->""+d, "x").apply(9.1)); + + assertEquals("Either.Failure(org.jooq.lambda.WrapTest$Information: f1.1)", + Wrap.doubleFunction((i)->{throw new Information("f1.1");}).apply(9.1).toString()); + assertEquals("H", Wrap.doubleFunction((d)->{throw new Information("f1.2");}, (d,t)->{ + assertEquals(9.1, d, 0.01); + assertTrue(t instanceof Information); + return "H"; + }).apply(9.1)); + assertEquals("x", Wrap.doubleFunctionDef((i)->{throw new Information("f1.3");}, "x").apply(9.1)); + + // intFunction + assertEquals("Either(9)", Wrap.intFunction((d)->""+d).apply(9).toString()); + assertEquals("9", Wrap.intFunction((d)->""+d, (d,t)->{ + assertEquals((Integer)9, d); + assertNull(t); + return null; + }).apply(9)); + assertEquals("9", Wrap.intFunctionDef((d)->""+d, "x").apply(9)); + + assertEquals("Either.Failure(org.jooq.lambda.WrapTest$Information: fI.1)", + Wrap.intFunction((i)->{throw new Information("fI.1");}).apply(9).toString()); + assertEquals("H", Wrap.intFunction((d)->{throw new Information("fI.2");}, (d,t)->{ + assertEquals((Integer)9, d); + assertTrue(t instanceof Information); + return "H"; + }).apply(9)); + assertEquals("x", Wrap.intFunctionDef((i)->{throw new Information("fI.3");}, "x").apply(9)); + + // longFunction + assertEquals("Either(9)", Wrap.longFunction((d)->""+d).apply(9L).toString()); + assertEquals("9", Wrap.longFunction((d)->""+d, (d,t)->{ + assertEquals((Long)9L, d); + assertNull(t); + return null; + }).apply(9L)); + assertEquals("9", Wrap.longFunctionDef((d)->""+d, "x").apply(9L)); + + assertEquals("Either.Failure(org.jooq.lambda.WrapTest$Information: fL.1)", + Wrap.longFunction((i)->{throw new Information("fL.1");}).apply(9L).toString()); + assertEquals("H", Wrap.longFunction((d)->{throw new Information("fL.2");}, (d,t)->{ + assertEquals((Long)9L, d); + assertTrue(t instanceof Information); + return "H"; + }).apply(9L)); + assertEquals("x", Wrap.longFunctionDef((i)->{throw new Information("fL.3");}, "x").apply(9L)); + } + + @Test public void testFunctions2 () { + assertEquals(9, Wrap.doubleToIntFunction((d)->(int)d, (d,t)->{ + assertEquals(9.1, d, 0.01); + assertNull(t); + return null; + }).applyAsInt(9.1)); + assertEquals(9, Wrap.doubleToIntFunctionDef((d)->(int)d, -1).applyAsInt(9.1)); + + assertEquals(-5, Wrap.doubleToIntFunction((d)-> 1/0, (d,t)->{ + assertEquals(9.1, d, 0.01); + assertTrue(t.toString(), t instanceof ArithmeticException); + return -5; + }).applyAsInt(9.1)); + assertEquals(-5, Wrap.doubleToIntFunctionDef((i)->{throw new Information("f1.3");}, -5).applyAsInt(9.1)); + // + assertEquals(9L, Wrap.doubleToLongFunction((d)->(int)d, (d,t)->{ + assertEquals(9.1, d, 0.01); + assertNull(t); + return null; + }).applyAsLong(9.1)); + assertEquals(9L, Wrap.doubleToLongFunctionDef((d)->(int)d, -1).applyAsLong(9.1)); + + assertEquals(-5L, Wrap.doubleToLongFunction((d)-> 1/0, (d,t)->{ + assertEquals(9.1, d, 0.01); + assertTrue(t.toString(), t instanceof ArithmeticException); + return -5L; + }).applyAsLong(9.1)); + assertEquals(-5L, Wrap.doubleToLongFunctionDef((i)->{throw new Information("f1.3");}, -5).applyAsLong(9.1)); + + // intToDoubleFunction + assertEquals(9.9, Wrap.intToDoubleFunction((d)->d*1.1, (d,t)->{ + assertEquals(9, d, 0.01); + assertNull(t); + return null; + }).applyAsDouble(9), 0.01); + assertEquals(9.9, Wrap.intToDoubleFunctionDef((d)->d*1.1,-1).applyAsDouble(9), 0.01); + + assertEquals(-5.1, Wrap.intToDoubleFunction((d)-> 1/0, (d,t)->{ + assertEquals((Integer)9, d); + assertTrue(t.toString(), t instanceof ArithmeticException); + return -5.1; + }).applyAsDouble(9), 0.01); + assertEquals(-5.1, Wrap.intToDoubleFunctionDef((i)->{throw new Information("f1.3");}, -5.1).applyAsDouble(9), 0.01); + + // intToLongFunction + assertEquals(90L, Wrap.intToLongFunction((d)->d*10L, (d,t)->{ + assertEquals((Integer)9, d); + assertNull(t); + return null; + }).applyAsLong(9)); + assertEquals(90L, Wrap.intToLongFunctionDef((d)->d*10L,-1L).applyAsLong(9)); + + assertEquals(-5L, Wrap.intToLongFunction((d)-> 1/0, (d,t)->{ + assertEquals((Integer)9, d); + assertTrue(t.toString(), t instanceof ArithmeticException); + return -5L; + }).applyAsLong(9)); + assertEquals(-5L, Wrap.intToLongFunctionDef((i)->{throw new Information("f1.3");}, -5L).applyAsLong(9)); + + // longToDoubleFunction + assertEquals(9.9, Wrap.longToDoubleFunction((d)->d*1.1, (d,t)->{ + assertEquals((Long)9L, d); + assertNull(t); + return -1.1; + }).applyAsDouble(9L), 0.01); + assertEquals(9.9, Wrap.longToDoubleFunctionDef((d)->d*1.1,-1.1).applyAsDouble(9L), 0.01); + + assertEquals(-5.1, Wrap.longToDoubleFunction((d)-> 1/0, (d,t)->{ + assertEquals((Long)9L, d); + assertTrue(t.toString(), t instanceof ArithmeticException); + return -5.1; + }).applyAsDouble(9L), 0.01); + assertEquals(-5.1, Wrap.longToDoubleFunctionDef((i)->1/0, -5.1).applyAsDouble(9L), 0.01); + + // longToIntFunction + assertEquals(8, Wrap.longToIntFunction((d)->(int)d-1, (d,t)->{ + assertEquals((Long)9L, d); + assertNull(t); + return -5; + }).applyAsInt(9L)); + assertEquals(8, Wrap.longToIntFunctionDef((d)->(int)d-1,-1).applyAsInt(9L)); + + assertEquals(-5, Wrap.longToIntFunction((d)-> 1/0, (d,t)->{ + assertEquals((Long)9L, d); + assertTrue(t.toString(), t instanceof ArithmeticException); + return -5; + }).applyAsInt(9L)); + assertEquals(-5, Wrap.longToIntFunctionDef((i)->divZero(), -5).applyAsInt(9L)); + } + + + @Test + public void testFunctionToPrimitive () { + // toDoubleBiFunction + CheckedToDoubleBiFunction cbif = (a,b)->a*1.1+b; + assertEquals(1.1+2, Wrap.toDoubleBiFunction(cbif, (a,b,t)->{ + assertEquals((Integer)1, a); + assertEquals((Integer)2, b); + assertNull(t); + return null; + }).applyAsDouble(1,2), 0.01); + assertEquals(1.1+2, Wrap.toDoubleBiFunctionDef(cbif, -9.1).applyAsDouble(1,2), 0.01); + + assertEquals(-5.7, Wrap.toDoubleBiFunction((Integer a, Integer b)->1/0, (a,b,t)->{ + assertEquals((Integer)1, a); + assertEquals((Integer)2, b); + assertTrue(t instanceof ArithmeticException); + return -5.7; + }).applyAsDouble(1,2), 0.01); + assertEquals(-1.5, Wrap.toDoubleBiFunctionDef((Integer a, Integer b)->{throw new Information("D");}, -1.5).applyAsDouble(1,2), 0.01); + + // toDoubleFunction + assertEquals(9.1, Wrap.toDoubleFunction(Double::parseDouble, (v,t)->{ + assertEquals("9.1", v); + assertNull(t); + return null; + }).applyAsDouble("9.1"), 0.01); + assertEquals(9.1, Wrap.toDoubleFunctionDef(Double::parseDouble, -9.1).applyAsDouble("9.1"), 0.01); + + assertEquals(-5.7, Wrap.toDoubleFunction((v)->(int)v, (v,t)->{ + assertEquals("9.1", v); + assertTrue(t.toString(), t instanceof ClassCastException); + return -5.7; + }).applyAsDouble("9.1"), 0.01); + assertEquals(-1.5, Wrap.toDoubleFunctionDef((v)->{throw new Information("D");}, -1.5).applyAsDouble("9.1"), 0.01); + + // toIntBiFunction + assertEquals(12, Wrap.toIntBiFunction((Long a, Long b)->(int)(a*10+b), (a,b,t)->{ + assertEquals((Long)1L, a); + assertEquals((Long)2L, b); + assertNull(t); + return null; + }).applyAsInt(1L,2L)); + assertEquals(12, Wrap.toIntBiFunctionDef((Long a, Long b)->(int)(a*10+b), -1).applyAsInt(1L,2L)); + + assertEquals(-5, Wrap.toIntBiFunction((Integer a, Long b)->1/0, (a,b,t)->{ + assertEquals((Integer)1, a); + assertEquals((Long)2L, b); + assertTrue(t instanceof ArithmeticException); + return -5; + }).applyAsInt(1,2L)); + assertEquals(-1, Wrap.toIntBiFunctionDef((Integer a, Long b)->{throw new Information("D");}, -1).applyAsInt(1,2L)); + + // toIntFunction + assertEquals(10, Wrap.toIntFunction((Long v)->(int)(v*10), (v,t)->{ + assertEquals((Long)1L, v); + assertNull(t); + return null; + }).applyAsInt(1L)); + assertEquals(10, Wrap.toIntFunctionDef((Long v)->(int)(v*10), -1).applyAsInt(1L)); + + assertEquals(-5, Wrap.toIntFunction((Integer v)->1/0, (v,t)->{ + assertEquals((Integer)1, v); + assertTrue(t instanceof ArithmeticException); + return -5; + }).applyAsInt(1)); + assertEquals(-1, Wrap.toIntFunctionDef((Integer a)->{throw new Information("D");}, -1).applyAsInt(1)); + + // toLongBiFunction + assertEquals(12L, Wrap.toLongBiFunction((Integer a, Byte b)->a*10L+b, (a,b,t)->{ + assertEquals((Integer)1, a); + assertEquals((byte)2, b.byteValue()); + assertNull(t); + return null; + }).applyAsLong(1,(byte)2)); + assertEquals(12L, Wrap.toLongBiFunctionDef((Integer a, Short b)->a*10L+b, -1).applyAsLong(1,(short)2)); + + assertEquals(-5L, Wrap.toLongBiFunction((Double a, Long b)->1/0, (a,b,t)->{ + assertEquals(1.1, a, 0.01); + assertEquals((Long)2L, b); + assertTrue(t instanceof ArithmeticException); + return -5L; + }).applyAsLong(1.1,2L)); + assertEquals(-1L, Wrap.toLongBiFunctionDef((Integer a, Long b)->{throw new Information("D");}, -1L).applyAsLong(1,2L)); + + // toLongFunction + assertEquals(10L, Wrap.toLongFunction(Double::longValue, (v,t)->{ + assertEquals(10.1, v, 0.01); + assertNull(t); + return null; + }).applyAsLong(10.1)); + assertEquals(10L, Wrap.toLongFunctionDef((Integer v)->v*10L, -1).applyAsLong(1)); + + assertEquals(-5L, Wrap.toLongFunction((Integer v)->1/0, (v,t)->{ + assertEquals((Integer)1, v); + assertTrue(t instanceof ArithmeticException); + return -5L; + }).applyAsLong(1)); + assertEquals(-1L, Wrap.toLongFunctionDef((Integer a)->{throw new Information("D");}, -1L).applyAsLong(1)); + + } + + + static T divZero () { + return Wrap.castUnsafe(1/0); + } +} \ No newline at end of file diff --git a/jOOL-java-8/src/test/java/org/jooq/lambda/function/GenericPredicateTest.java b/jOOL-java-8/src/test/java/org/jooq/lambda/function/GenericPredicateTest.java new file mode 100644 index 00000000..6181939b --- /dev/null +++ b/jOOL-java-8/src/test/java/org/jooq/lambda/function/GenericPredicateTest.java @@ -0,0 +1,650 @@ +package org.jooq.lambda.function; + +import org.jooq.lambda.Loops; +import org.jooq.lambda.Wrap; +import org.jooq.lambda.tuple.Tuple; +import org.jooq.lambda.tuple.Tuple0; +import org.jooq.lambda.tuple.Tuple1; +import org.jooq.lambda.tuple.Tuple10; +import org.jooq.lambda.tuple.Tuple11; +import org.jooq.lambda.tuple.Tuple12; +import org.jooq.lambda.tuple.Tuple13; +import org.jooq.lambda.tuple.Tuple14; +import org.jooq.lambda.tuple.Tuple15; +import org.jooq.lambda.tuple.Tuple16; +import org.jooq.lambda.tuple.Tuple2; +import org.jooq.lambda.tuple.Tuple3; +import org.jooq.lambda.tuple.Tuple4; +import org.jooq.lambda.tuple.Tuple5; +import org.jooq.lambda.tuple.Tuple6; +import org.jooq.lambda.tuple.Tuple7; +import org.jooq.lambda.tuple.Tuple8; +import org.jooq.lambda.tuple.Tuple9; +import org.junit.Test; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Proxy; + +import static org.junit.Assert.*; + +public class GenericPredicateTest { + + @Test public void dynamic () throws ClassNotFoundException { + assertTrue(GenericPredicate.testDynamicPredicateVarArgs((Predicate0)()->true, null)); + assertFalse(GenericPredicate.testDynamicPredicateVarArgs((Predicate0)()->false)); + + assertTrue(GenericPredicate.testDynamicArgCntToPredicate((Predicate0)()->true, null)); + assertFalse(GenericPredicate.testDynamicArgCntToPredicate((Predicate0)()->false)); + + for (int i=0; i<=16; i++) { + final int len = i; + String ifaceClassName = "org.jooq.lambda.function.Predicate"+i; + Class ifaceClass = Wrap.castUnsafe(Class.forName(ifaceClassName)); + GenericPredicate p = (GenericPredicate) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), + new Class[]{ifaceClass}, (proxy, method, args) -> { + assertEquals("test", method.getName()); + + if (len == 0) { + assertNull(args); + } else { + assertEquals(len, args.length); + for (int j = 0; j < len; j++) { + assertEquals(j + 11, args[j]); + } + } + return len % 2 == 0; + }); + + Object[] args = new Integer[len]; + for (int j=0; j true; + + assertTrue(p.test()); + assertTrue(p.test(new Tuple0())); + assertTrue(p.get()); + assertTrue(p.call()); + assertTrue(p.apply()); + assertSame(p, p.toSupplier()); + + p = Predicate0.from(()->false); + assertFalse(p.call()); + } + + + static boolean logic (Integer... a) { + int prev = 1; + for (int i : a) { + assertTrue("prev < i: "+prev+" ? "+i, prev < i); + prev = i; + } + return a.length % 2 == 0; + } + + @SuppressWarnings("unchecked") + static T tuple (int size) { + try { + final Class cls = Class.forName("org.jooq.lambda.tuple.Tuple" + size); + + final Object[] args = new Object[size]; + Loops.forLoop(size, (i) -> {args[i] = i + 10;}); + + for (Constructor ctor : cls.getConstructors()) { + if (ctor.getParameterCount() == size) { + + return (T) ctor.newInstance(args); + } + } + } catch (Exception e) { + throw new IllegalStateException("Can't create Tuple"+size, e); + } + throw new IllegalArgumentException("Wrong size="+size+". Can't create Tuple"+size); + } + + @Test public void testPredicate1 () { + Predicate1 p = Predicate1.from(GenericPredicateTest::logic); + assertSame(p, p.toPredicate()); + assertFalse(p.test(10));// arg.len==1→false + assertFalse(p.applyPartially(10).test()); + Tuple1 tuple = tuple(1); + assertFalse(p.test(tuple)); + assertFalse(p.toFunction().apply(tuple)); + assertFalse(p.applyPartially(tuple).test()); + + p = Predicate1.fromFunction((i)->true); + assertTrue(p.test(0)); + } + + + @Test public void testLogic1 () { + Predicate16 p = GenericPredicateTest::logic; + + assertTrue(p.test(10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25)); + } + @Test(expected = AssertionError.class) + public void testLogic2 () { + Predicate16 p = GenericPredicateTest::logic; + assertTrue(p.test(10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25)); + + p.test(0,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25); + fail("unreachable: ^^^ 0 < 1"); + } + @Test(expected = AssertionError.class) + public void testLogic3 () { + Predicate16 p = GenericPredicateTest::logic; + assertTrue(p.test(10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25)); + + p.test(10,11,12,13,14,15,16,17,18,19,20, 22,21, 23,24,25); + fail("unreachable: ^^^ AssertionError: prev < i: 22 ? 21"); + } + + + @Test public void testPredicate2 () { + Predicate2 p = Predicate2.from(GenericPredicateTest::logic); + assertSame(p, p.toBiPredicate()); + assertTrue(p.test(10,11)); + assertTrue(p.applyPartially(10).test(11)); + assertTrue(p.applyPartially(10, 11).test()); + + Tuple2 tuple = tuple(2); + assertTrue(p.test(tuple)); + assertTrue(p.toFunction().apply(tuple)); + assertTrue(p.applyPartially(tuple).test()); + + Tuple1 tuple1 = tuple(1); + assertTrue(p.applyPartially(tuple1).test(11)); + + p = Predicate2.fromFunction((a,b)->false); + assertFalse(p.test(10,11)); + } + + + @Test public void testPredicate3 () { + Predicate3 p = GenericPredicateTest::logic; + Tuple3 tuple = tuple(3); + // 3 % 2 != 0 + assertFalse(p.toFunction().apply(tuple)); + assertFalse(p.test(tuple)); + assertFalse(p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertFalse(p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertFalse(p.applyPartially(tuple.limit3()).test(tuple.skip3())); + + + assertFalse(p.test(10,11,12)); + assertFalse(p.applyPartially(10).test(11,12)); + assertFalse(p.applyPartially(10, 11).test(12)); + assertFalse(p.applyPartially(10, 11, 12).test()); + } + + @Test public void testPredicate4 () { + Predicate4 p = GenericPredicateTest::logic; + Tuple4 tuple = tuple(4); + boolean pv = tuple.degree() % 2 == 0; + + assertEquals(pv, p.toFunction().apply(tuple)); + assertEquals(pv, p.test(tuple)); + assertEquals(pv, p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertEquals(pv, p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertEquals(pv, p.applyPartially(tuple.limit3()).test(tuple.skip3())); + assertEquals(pv, p.applyPartially(tuple.limit4()).test(tuple.skip4())); + + assertEquals(pv, p.test(10,11,12,13)); + assertEquals(pv, p.applyPartially(10).test(11,12,13)); + assertEquals(pv, p.applyPartially(10,11).test(12,13)); + assertEquals(pv, p.applyPartially(10,11,12).test(13)); + assertEquals(pv, p.applyPartially(10,11,12,13).test()); + } + + @Test public void testPredicate5 () { + Predicate5 p = GenericPredicateTest::logic; + Tuple5 tuple = tuple(5); + boolean pv = tuple.degree() % 2 == 0; + + assertEquals(pv, p.toFunction().apply(tuple)); + assertEquals(pv, p.test(tuple)); + assertEquals(pv, p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertEquals(pv, p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertEquals(pv, p.applyPartially(tuple.limit3()).test(tuple.skip3())); + assertEquals(pv, p.applyPartially(tuple.limit4()).test(tuple.skip4())); + assertEquals(pv, p.applyPartially(tuple.limit5()).test(tuple.skip5())); + + assertEquals(pv, p.test(10,11,12,13,14)); + assertEquals(pv, p.applyPartially(10).test(11,12,13,14)); + assertEquals(pv, p.applyPartially(10,11).test(12,13,14)); + assertEquals(pv, p.applyPartially(10,11,12).test(13,14)); + assertEquals(pv, p.applyPartially(10,11,12,13).test(14)); + assertEquals(pv, p.applyPartially(10,11,12,13,14).test()); + } + + @Test public void testPredicate6 () { + Predicate6 p = GenericPredicateTest::logic; + Tuple6 tuple = tuple(6); + boolean pv = tuple.degree() % 2 == 0; + + assertEquals(pv, p.toFunction().apply(tuple)); + assertEquals(pv, p.test(tuple)); + assertEquals(pv, p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertEquals(pv, p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertEquals(pv, p.applyPartially(tuple.limit3()).test(tuple.skip3())); + assertEquals(pv, p.applyPartially(tuple.limit4()).test(tuple.skip4())); + assertEquals(pv, p.applyPartially(tuple.limit5()).test(tuple.skip5())); + assertEquals(pv, p.applyPartially(tuple.limit6()).test(tuple.skip6())); + + assertEquals(pv, p.test(10,11,12,13,14,15)); + assertEquals(pv, p.applyPartially(10).test(11,12,13,14,15)); + assertEquals(pv, p.applyPartially(10,11).test(12,13,14,15)); + assertEquals(pv, p.applyPartially(10,11,12).test(13,14,15)); + assertEquals(pv, p.applyPartially(10,11,12,13).test(14,15)); + assertEquals(pv, p.applyPartially(10,11,12,13,14).test(15)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15).test()); + } + + @Test public void testPredicate7 () { + Predicate7 p = GenericPredicateTest::logic; + Tuple7 tuple = tuple(7); + boolean pv = tuple.degree() % 2 == 0; + + assertEquals(pv, p.toFunction().apply(tuple)); + assertEquals(pv, p.test(tuple)); + assertEquals(pv, p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertEquals(pv, p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertEquals(pv, p.applyPartially(tuple.limit3()).test(tuple.skip3())); + assertEquals(pv, p.applyPartially(tuple.limit4()).test(tuple.skip4())); + assertEquals(pv, p.applyPartially(tuple.limit5()).test(tuple.skip5())); + assertEquals(pv, p.applyPartially(tuple.limit6()).test(tuple.skip6())); + assertEquals(pv, p.applyPartially(tuple.limit7()).test(tuple.skip7())); + + assertEquals(pv, p.test(10,11,12,13,14,15,16)); + assertEquals(pv, p.applyPartially(10).test(11,12,13,14,15,16)); + assertEquals(pv, p.applyPartially(10,11).test(12,13,14,15,16)); + assertEquals(pv, p.applyPartially(10,11,12).test(13,14,15,16)); + assertEquals(pv, p.applyPartially(10,11,12,13).test(14,15,16)); + assertEquals(pv, p.applyPartially(10,11,12,13,14).test(15,16)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15).test(16)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16).test()); + } + + @Test public void testPredicate8 () { + Predicate8 p = GenericPredicateTest::logic; + Tuple8 tuple = tuple(8); + boolean pv = tuple.degree() % 2 == 0; + + assertEquals(pv, p.toFunction().apply(tuple)); + assertEquals(pv, p.test(tuple)); + assertEquals(pv, p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertEquals(pv, p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertEquals(pv, p.applyPartially(tuple.limit3()).test(tuple.skip3())); + assertEquals(pv, p.applyPartially(tuple.limit4()).test(tuple.skip4())); + assertEquals(pv, p.applyPartially(tuple.limit5()).test(tuple.skip5())); + assertEquals(pv, p.applyPartially(tuple.limit6()).test(tuple.skip6())); + assertEquals(pv, p.applyPartially(tuple.limit7()).test(tuple.skip7())); + assertEquals(pv, p.applyPartially(tuple.limit8()).test(tuple.skip8())); + + assertEquals(pv, p.test(10,11,12,13,14,15,16,17)); + assertEquals(pv, p.applyPartially(10).test(11,12,13,14,15,16,17)); + assertEquals(pv, p.applyPartially(10,11).test(12,13,14,15,16,17)); + assertEquals(pv, p.applyPartially(10,11,12).test(13,14,15,16,17)); + assertEquals(pv, p.applyPartially(10,11,12,13).test(14,15,16,17)); + assertEquals(pv, p.applyPartially(10,11,12,13,14).test(15,16,17)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15).test(16,17)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16).test(17)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17).test()); + } + + @Test public void testPredicate9 () { + Predicate9 p = GenericPredicateTest::logic; + Tuple9 tuple = tuple(9); + boolean pv = tuple.degree() % 2 == 0; + + assertEquals(pv, p.toFunction().apply(tuple)); + assertEquals(pv, p.test(tuple)); + assertEquals(pv, p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertEquals(pv, p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertEquals(pv, p.applyPartially(tuple.limit3()).test(tuple.skip3())); + assertEquals(pv, p.applyPartially(tuple.limit4()).test(tuple.skip4())); + assertEquals(pv, p.applyPartially(tuple.limit5()).test(tuple.skip5())); + assertEquals(pv, p.applyPartially(tuple.limit6()).test(tuple.skip6())); + assertEquals(pv, p.applyPartially(tuple.limit7()).test(tuple.skip7())); + assertEquals(pv, p.applyPartially(tuple.limit8()).test(tuple.skip8())); + assertEquals(pv, p.applyPartially(tuple.limit9()).test(tuple.skip9())); + + assertEquals(pv, p.test(10,11,12,13,14,15,16,17,18)); + assertEquals(pv, p.applyPartially(10).test(11,12,13,14,15,16,17,18)); + assertEquals(pv, p.applyPartially(10,11).test(12,13,14,15,16,17,18)); + assertEquals(pv, p.applyPartially(10,11,12).test(13,14,15,16,17,18)); + assertEquals(pv, p.applyPartially(10,11,12,13).test(14,15,16,17,18)); + assertEquals(pv, p.applyPartially(10,11,12,13,14).test(15,16,17,18)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15).test(16,17,18)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16).test(17,18)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17).test(18)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18).test()); + } + + @Test public void testPredicate10 () { + Predicate10 p = GenericPredicateTest::logic; + Tuple10 tuple = tuple(10); + boolean pv = tuple.degree() % 2 == 0; + + assertEquals(pv, p.toFunction().apply(tuple)); + assertEquals(pv, p.test(tuple)); + assertEquals(pv, p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertEquals(pv, p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertEquals(pv, p.applyPartially(tuple.limit3()).test(tuple.skip3())); + assertEquals(pv, p.applyPartially(tuple.limit4()).test(tuple.skip4())); + assertEquals(pv, p.applyPartially(tuple.limit5()).test(tuple.skip5())); + assertEquals(pv, p.applyPartially(tuple.limit6()).test(tuple.skip6())); + assertEquals(pv, p.applyPartially(tuple.limit7()).test(tuple.skip7())); + assertEquals(pv, p.applyPartially(tuple.limit8()).test(tuple.skip8())); + assertEquals(pv, p.applyPartially(tuple.limit9()).test(tuple.skip9())); + assertEquals(pv, p.applyPartially(tuple.limit10()).test(tuple.skip10())); + + assertEquals(pv, p.test(10,11,12,13,14,15,16,17,18,19)); + assertEquals(pv, p.applyPartially(10).test(11,12,13,14,15,16,17,18,19)); + assertEquals(pv, p.applyPartially(10,11).test(12,13,14,15,16,17,18,19)); + assertEquals(pv, p.applyPartially(10,11,12).test(13,14,15,16,17,18,19)); + assertEquals(pv, p.applyPartially(10,11,12,13).test(14,15,16,17,18,19)); + assertEquals(pv, p.applyPartially(10,11,12,13,14).test(15,16,17,18,19)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15).test(16,17,18,19)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16).test(17,18,19)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17).test(18,19)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18).test(19)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19).test()); + } + + @Test public void testPredicate11 () { + Predicate11 p = GenericPredicateTest::logic; + Tuple11 tuple = tuple(11); + boolean pv = tuple.degree() % 2 == 0; + + assertEquals(pv, p.toFunction().apply(tuple)); + assertEquals(pv, p.test(tuple)); + assertEquals(pv, p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertEquals(pv, p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertEquals(pv, p.applyPartially(tuple.limit3()).test(tuple.skip3())); + assertEquals(pv, p.applyPartially(tuple.limit4()).test(tuple.skip4())); + assertEquals(pv, p.applyPartially(tuple.limit5()).test(tuple.skip5())); + assertEquals(pv, p.applyPartially(tuple.limit6()).test(tuple.skip6())); + assertEquals(pv, p.applyPartially(tuple.limit7()).test(tuple.skip7())); + assertEquals(pv, p.applyPartially(tuple.limit8()).test(tuple.skip8())); + assertEquals(pv, p.applyPartially(tuple.limit9()).test(tuple.skip9())); + assertEquals(pv, p.applyPartially(tuple.limit10()).test(tuple.skip10())); + assertEquals(pv, p.applyPartially(tuple.limit11()).test(tuple.skip11())); + + assertEquals(pv, p.test(10,11,12,13,14,15,16,17,18,19,20)); + assertEquals(pv, p.applyPartially(10).test(11,12,13,14,15,16,17,18,19,20)); + assertEquals(pv, p.applyPartially(10,11).test(12,13,14,15,16,17,18,19,20)); + assertEquals(pv, p.applyPartially(10,11,12).test(13,14,15,16,17,18,19,20)); + assertEquals(pv, p.applyPartially(10,11,12,13).test(14,15,16,17,18,19,20)); + assertEquals(pv, p.applyPartially(10,11,12,13,14).test(15,16,17,18,19,20)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15).test(16,17,18,19,20)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16).test(17,18,19,20)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17).test(18,19,20)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18).test(19,20)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19).test(20)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20).test()); + } + + @Test public void testPredicate12 () { + Predicate12 p = GenericPredicateTest::logic; + Tuple12 tuple = tuple(12); + boolean pv = tuple.degree() % 2 == 0; + + assertEquals(pv, p.toFunction().apply(tuple)); + assertEquals(pv, p.test(tuple)); + assertEquals(pv, p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertEquals(pv, p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertEquals(pv, p.applyPartially(tuple.limit3()).test(tuple.skip3())); + assertEquals(pv, p.applyPartially(tuple.limit4()).test(tuple.skip4())); + assertEquals(pv, p.applyPartially(tuple.limit5()).test(tuple.skip5())); + assertEquals(pv, p.applyPartially(tuple.limit6()).test(tuple.skip6())); + assertEquals(pv, p.applyPartially(tuple.limit7()).test(tuple.skip7())); + assertEquals(pv, p.applyPartially(tuple.limit8()).test(tuple.skip8())); + assertEquals(pv, p.applyPartially(tuple.limit9()).test(tuple.skip9())); + assertEquals(pv, p.applyPartially(tuple.limit10()).test(tuple.skip10())); + assertEquals(pv, p.applyPartially(tuple.limit11()).test(tuple.skip11())); + assertEquals(pv, p.applyPartially(tuple.limit12()).test(tuple.skip12())); + + assertEquals(pv, p.test(10,11,12,13,14,15,16,17,18,19,20,21)); + assertEquals(pv, p.applyPartially(10).test(11,12,13,14,15,16,17,18,19,20,21)); + assertEquals(pv, p.applyPartially(10,11).test(12,13,14,15,16,17,18,19,20,21)); + assertEquals(pv, p.applyPartially(10,11,12).test(13,14,15,16,17,18,19,20,21)); + assertEquals(pv, p.applyPartially(10,11,12,13).test(14,15,16,17,18,19,20,21)); + assertEquals(pv, p.applyPartially(10,11,12,13,14).test(15,16,17,18,19,20,21)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15).test(16,17,18,19,20,21)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16).test(17,18,19,20,21)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17).test(18,19,20,21)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18).test(19,20,21)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19).test(20,21)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20).test(21)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21).test()); + } + + @Test public void testPredicate13 () { + Predicate13 + p = GenericPredicateTest::logic; + Tuple13 + tuple = tuple(13); + boolean pv = tuple.degree() % 2 == 0; + + assertEquals(pv, p.toFunction().apply(tuple)); + assertEquals(pv, p.test(tuple)); + assertEquals(pv, p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertEquals(pv, p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertEquals(pv, p.applyPartially(tuple.limit3()).test(tuple.skip3())); + assertEquals(pv, p.applyPartially(tuple.limit4()).test(tuple.skip4())); + assertEquals(pv, p.applyPartially(tuple.limit5()).test(tuple.skip5())); + assertEquals(pv, p.applyPartially(tuple.limit6()).test(tuple.skip6())); + assertEquals(pv, p.applyPartially(tuple.limit7()).test(tuple.skip7())); + assertEquals(pv, p.applyPartially(tuple.limit8()).test(tuple.skip8())); + assertEquals(pv, p.applyPartially(tuple.limit9()).test(tuple.skip9())); + assertEquals(pv, p.applyPartially(tuple.limit10()).test(tuple.skip10())); + assertEquals(pv, p.applyPartially(tuple.limit11()).test(tuple.skip11())); + assertEquals(pv, p.applyPartially(tuple.limit12()).test(tuple.skip12())); + assertEquals(pv, p.applyPartially(tuple.limit13()).test(tuple.skip13())); + + assertEquals(pv, p.test(10,11,12,13,14,15,16,17,18,19,20,21,22)); + assertEquals(pv, p.applyPartially(10).test(11,12,13,14,15,16,17,18,19,20,21,22)); + assertEquals(pv, p.applyPartially(10,11).test(12,13,14,15,16,17,18,19,20,21,22)); + assertEquals(pv, p.applyPartially(10,11,12).test(13,14,15,16,17,18,19,20,21,22)); + assertEquals(pv, p.applyPartially(10,11,12,13).test(14,15,16,17,18,19,20,21,22)); + assertEquals(pv, p.applyPartially(10,11,12,13,14).test(15,16,17,18,19,20,21,22)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15).test(16,17,18,19,20,21,22)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16).test(17,18,19,20,21,22)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17).test(18,19,20,21,22)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18).test(19,20,21,22)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19).test(20,21,22)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20).test(21,22)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21).test(22)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21,22).test()); + } + + @Test public void testPredicate14 () { + Predicate14 + p = GenericPredicateTest::logic; + Tuple14 + tuple = tuple(14); + boolean pv = tuple.degree() % 2 == 0; + + assertEquals(pv, p.toFunction().apply(tuple)); + assertEquals(pv, p.test(tuple)); + assertEquals(pv, p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertEquals(pv, p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertEquals(pv, p.applyPartially(tuple.limit3()).test(tuple.skip3())); + assertEquals(pv, p.applyPartially(tuple.limit4()).test(tuple.skip4())); + assertEquals(pv, p.applyPartially(tuple.limit5()).test(tuple.skip5())); + assertEquals(pv, p.applyPartially(tuple.limit6()).test(tuple.skip6())); + assertEquals(pv, p.applyPartially(tuple.limit7()).test(tuple.skip7())); + assertEquals(pv, p.applyPartially(tuple.limit8()).test(tuple.skip8())); + assertEquals(pv, p.applyPartially(tuple.limit9()).test(tuple.skip9())); + assertEquals(pv, p.applyPartially(tuple.limit10()).test(tuple.skip10())); + assertEquals(pv, p.applyPartially(tuple.limit11()).test(tuple.skip11())); + assertEquals(pv, p.applyPartially(tuple.limit12()).test(tuple.skip12())); + assertEquals(pv, p.applyPartially(tuple.limit13()).test(tuple.skip13())); + assertEquals(pv, p.applyPartially(tuple.limit14()).test(tuple.skip14())); + + assertEquals(pv, p.test(10,11,12,13,14,15,16,17,18,19,20,21,22,23)); + assertEquals(pv, p.applyPartially(10).test(11,12,13,14,15,16,17,18,19,20,21,22,23)); + assertEquals(pv, p.applyPartially(10,11).test(12,13,14,15,16,17,18,19,20,21,22,23)); + assertEquals(pv, p.applyPartially(10,11,12).test(13,14,15,16,17,18,19,20,21,22,23)); + assertEquals(pv, p.applyPartially(10,11,12,13).test(14,15,16,17,18,19,20,21,22,23)); + assertEquals(pv, p.applyPartially(10,11,12,13,14).test(15,16,17,18,19,20,21,22,23)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15).test(16,17,18,19,20,21,22,23)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16).test(17,18,19,20,21,22,23)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17).test(18,19,20,21,22,23)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18).test(19,20,21,22,23)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19).test(20,21,22,23)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20).test(21,22,23)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21).test(22,23)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21,22).test(23)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21,22,23).test()); + } + + @Test public void testPredicate15 () { + Predicate15 p = GenericPredicateTest::logic; + Tuple15 tuple = tuple(15); + boolean pv = tuple.degree() % 2 == 0; + + assertEquals(pv, p.toFunction().apply(tuple)); + assertEquals(pv, p.test(tuple)); + assertEquals(pv, p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertEquals(pv, p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertEquals(pv, p.applyPartially(tuple.limit3()).test(tuple.skip3())); + assertEquals(pv, p.applyPartially(tuple.limit4()).test(tuple.skip4())); + assertEquals(pv, p.applyPartially(tuple.limit5()).test(tuple.skip5())); + assertEquals(pv, p.applyPartially(tuple.limit6()).test(tuple.skip6())); + assertEquals(pv, p.applyPartially(tuple.limit7()).test(tuple.skip7())); + assertEquals(pv, p.applyPartially(tuple.limit8()).test(tuple.skip8())); + assertEquals(pv, p.applyPartially(tuple.limit9()).test(tuple.skip9())); + assertEquals(pv, p.applyPartially(tuple.limit10()).test(tuple.skip10())); + assertEquals(pv, p.applyPartially(tuple.limit11()).test(tuple.skip11())); + assertEquals(pv, p.applyPartially(tuple.limit12()).test(tuple.skip12())); + assertEquals(pv, p.applyPartially(tuple.limit13()).test(tuple.skip13())); + assertEquals(pv, p.applyPartially(tuple.limit14()).test(tuple.skip14())); + assertEquals(pv, p.applyPartially(tuple.limit15()).test(tuple.skip15())); + + assertEquals(pv, p.test(10,11,12,13,14,15,16,17,18,19,20,21,22,23,24)); + assertEquals(pv, p.applyPartially(10).test(11,12,13,14,15,16,17,18,19,20,21,22,23,24)); + assertEquals(pv, p.applyPartially(10,11).test(12,13,14,15,16,17,18,19,20,21,22,23,24)); + assertEquals(pv, p.applyPartially(10,11,12).test(13,14,15,16,17,18,19,20,21,22,23,24)); + assertEquals(pv, p.applyPartially(10,11,12,13).test(14,15,16,17,18,19,20,21,22,23,24)); + assertEquals(pv, p.applyPartially(10,11,12,13,14).test(15,16,17,18,19,20,21,22,23,24)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15).test(16,17,18,19,20,21,22,23,24)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16).test(17,18,19,20,21,22,23,24)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17).test(18,19,20,21,22,23,24)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18).test(19,20,21,22,23,24)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19).test(20,21,22,23,24)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20).test(21,22,23,24)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21).test(22,23,24)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21,22).test(23,24)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21,22,23).test(24)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21,22,23,24).test()); + } + + @Test public void testPredicate16 () { + Predicate16 p = GenericPredicateTest::logic; + Tuple16 tuple = tuple(16); + boolean pv = tuple.degree() % 2 == 0; + + assertEquals(pv, p.toFunction().apply(tuple)); + assertEquals(pv, p.test(tuple)); + assertEquals(pv, p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertEquals(pv, p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertEquals(pv, p.applyPartially(tuple.limit3()).test(tuple.skip3())); + assertEquals(pv, p.applyPartially(tuple.limit4()).test(tuple.skip4())); + assertEquals(pv, p.applyPartially(tuple.limit5()).test(tuple.skip5())); + assertEquals(pv, p.applyPartially(tuple.limit6()).test(tuple.skip6())); + assertEquals(pv, p.applyPartially(tuple.limit7()).test(tuple.skip7())); + assertEquals(pv, p.applyPartially(tuple.limit8()).test(tuple.skip8())); + assertEquals(pv, p.applyPartially(tuple.limit9()).test(tuple.skip9())); + assertEquals(pv, p.applyPartially(tuple.limit10()).test(tuple.skip10())); + assertEquals(pv, p.applyPartially(tuple.limit11()).test(tuple.skip11())); + assertEquals(pv, p.applyPartially(tuple.limit12()).test(tuple.skip12())); + assertEquals(pv, p.applyPartially(tuple.limit13()).test(tuple.skip13())); + assertEquals(pv, p.applyPartially(tuple.limit14()).test(tuple.skip14())); + assertEquals(pv, p.applyPartially(tuple.limit15()).test(tuple.skip15())); + assertEquals(pv, p.applyPartially(tuple.limit16()).test(tuple.skip16())); + + assertEquals(pv, p.test(10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25)); + assertEquals(pv, p.applyPartially(10).test(11,12,13,14,15,16,17,18,19,20,21,22,23,24,25)); + assertEquals(pv, p.applyPartially(10,11).test(12,13,14,15,16,17,18,19,20,21,22,23,24,25)); + assertEquals(pv, p.applyPartially(10,11,12).test(13,14,15,16,17,18,19,20,21,22,23,24,25)); + assertEquals(pv, p.applyPartially(10,11,12,13).test(14,15,16,17,18,19,20,21,22,23,24,25)); + assertEquals(pv, p.applyPartially(10,11,12,13,14).test(15,16,17,18,19,20,21,22,23,24,25)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15).test(16,17,18,19,20,21,22,23,24,25)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16).test(17,18,19,20,21,22,23,24,25)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17).test(18,19,20,21,22,23,24,25)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18).test(19,20,21,22,23,24,25)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19).test(20,21,22,23,24,25)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20).test(21,22,23,24,25)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21).test(22,23,24,25)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21,22).test(23,24,25)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21,22,23).test(24,25)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21,22,23,24).test(25)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25).test()); + } +} \ No newline at end of file diff --git a/jOOL/src/test/java/org/jooq/lambda/ExtraMagicTest.java b/jOOL/src/test/java/org/jooq/lambda/ExtraMagicTest.java new file mode 100644 index 00000000..39b68965 --- /dev/null +++ b/jOOL/src/test/java/org/jooq/lambda/ExtraMagicTest.java @@ -0,0 +1,352 @@ +package org.jooq.lambda; + +import org.jooq.lambda.function.Consumer3; +import org.junit.Test; + +import java.io.IOError; +import java.io.IOException; +import java.lang.invoke.CallSite; +import java.lang.invoke.LambdaMetafactory; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Objects; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Consumer; +import java.util.function.LongSupplier; + +import static org.jooq.lambda.LambdaLogFacade.printToStdErr; +import static org.jooq.lambda.Loops.loop; +import static org.junit.Assert.*; + +/* +https://www.jmix.io/cuba-blog/think-twice-before-using-reflection/ + +https://github.com/cuba-rnd/entity-lambda-accessors-benchmark/blob/master/src/jmh/java/utils/MethodHandleCache.java + +https://www.mail-archive.com/mlvm-dev@openjdk.java.net/msg06747.html + +https://www.optaplanner.org/blog/2018/01/09/JavaReflectionButMuchFaster.html + +https://wttech.blog/blog/2020/method-handles-and-lambda-metafactory/ + +https://forum.image.sc/t/performance-profiling-ways-of-invoking-a-method-dynamically/27471 + +!!! +private static final System.Logger log = System.getLogger("c.f.b.DefaultLogger"); ++ +clsLoader = Thread.currentThread().getContextClassLoader(); +clsLoader = Wrap.class.getClassLoader(); +clsLoader = ClassLoader.getPlatformClassLoader(); +clsLoader = ClassLoader.getSystemClassLoader(); + */ +public class ExtraMagicTest { + static volatile Throwable FAILED; + static final Method winner; + static { + Thread.setDefaultUncaughtExceptionHandler((Thread t, Throwable e) -> + { + FAILED = e; + loop(9, ()-> System.err.println("{{{{{ DefaultUncaughtExceptionHandler @ "+t)); + e.printStackTrace(); + loop(9, ()-> System.err.println("}}}}} DefaultUncaughtExceptionHandler @ "+t)); + }); + + //1. on/off → lambdaLogFacadeLoggerTest + System.setProperty("org.jooq.logger", "org.jooq.lambda.ExtraMagicTest$LoggerOverride"); + final Method winner0 = LambdaLogFacade.findLoggerFactoryGetLogger("org.jooq.lambda.ExtraMagicTest$LoggerOverride"); + + //2. slf4j +// final Method winner0 = LambdaLogFacade.findLoggerFactoryGetLogger("org.slf4j.LoggerFactory"); + + //3. log4j +// System.setProperty("org.jooq.logger.0", "-"); +// final Method winner0 = LambdaLogFacade.findLoggerFactoryGetLogger("org.apache.logging.log4j.LogManager"); +// //4. ×JUL: no slf4j/log4j +// System.setProperty("org.jooq.logger.0", "-"); +// System.setProperty("org.jooq.logger.1", "-"); +// final Method winner0 = null; + + if (Objects.equals(winner0, LambdaLogFacade.staticLoggerFactoryGetLoggerMethod)) { + // good! We are the first UnitTest, we have initialized LambdaLogFacade with our wishes + winner = winner0; + } else if (LambdaLogFacade.staticLoggerFactoryGetLoggerMethod == null) { + printToStdErr(ExtraMagicTest.class, + "Other UnitTest was faster and have already initialized LambdaLogFacade with null (slf4j and log4j were not found)", null); + winner = null; + } else { + printToStdErr(ExtraMagicTest.class, + "Other UnitTest was faster and have already initialized LambdaLogFacade with "+LambdaLogFacade.staticLoggerFactoryGetLoggerMethod, null); + winner = LambdaLogFacade.staticLoggerFactoryGetLoggerMethod; + } + } + + @Test(expected = IOError.class) + public void andThen () { + Error e1 = new Error("test1: → ERROR is OK here!!!"); + Unchecked.PRINT_STACK_TRACE.accept(e1); + + IOError e2 = new IOError(e1); + Consumer c = Unchecked.SILENT_IGNORE + .andThen((t) -> fail("unreachable. But: " + t)); + c.accept(e2); + + fail("unreachable"); + } + + + @Test public void modulesHackJUL () { + Object jul = getActualLogger("java.util.logging.Logger", ExtraMagicTest.class); + assertEquals("class java.util.logging.Logger", jul.getClass().toString()); + assertTrue(jul.toString().startsWith("java.util.logging.Logger@")); + } + + @Test public void modulesHackSlf4j () { + Object slf4j = getActualLogger("org.slf4j.LoggerFactory", ExtraMagicTest.class); + assertEquals("class org.slf4j.simple.SimpleLogger", slf4j.getClass().toString());// class org.slf4j.helpers.NOPLogger + assertTrue(slf4j.toString().startsWith("org.slf4j.simple.SimpleLogger@"));// org.slf4j.helpers.NOPLogger(NOP) + } + + @Test public void modulesHackLog4j () { + Object log4j = getActualLogger("org.apache.logging.log4j.LogManager", ExtraMagicTest.class); + assertEquals("class org.apache.logging.log4j.core.Logger", log4j.getClass().toString()); + assertTrue(log4j.toString().startsWith("org.jooq.lambda.ExtraMagicTest:ERROR in ")); + } + + public static class FakeLogger extends LambdaLogFacade implements LongSupplier, Runnable { + public FakeLogger () { + super(null); + } + + final AtomicLong cnt = new AtomicLong(); + + public static FakeLogger getLogger (String notUsed) { + return new FakeLogger(); + } + @Override public void warn (String msg, Throwable t) { + assertNotNull(t); + cnt.incrementAndGet(); + if (cnt.get() == MAX_LOOP) { + new Exception("[INFO] Almost there! "+msg+"\t\t"+this).printStackTrace(); + } + } + @Override public long getAsLong () { + return cnt.get(); + } + @Override public void run () {} + } + + static /*NOT final!*/ Throwable LOG_EXCEPTION = new Exception("fake");//MethodHandle.invokeExact check type of variable (not ref object) + static final long MAX_LOOP = 10_000_000; + static final long MAX_LOOP_WARM = 10_050_000; + + @Test public void speedDirect () { + FakeLogger fl = new FakeLogger() { + @Override public void run () { + warn("message-to-log: Direct", LOG_EXCEPTION); + } + }; + String st = Loops.loopMeasuredWarm(MAX_LOOP, fl).toString(); + System.out.println("*** speedDirect →\t\t"+st); + assertEquals(MAX_LOOP_WARM, fl.getAsLong()); + } + + @Test public void speedLambda () { + FakeLogger fl = new FakeLogger(); + + String st = Loops.loopMeasuredWarm(MAX_LOOP, Wrap.runnable(() -> + fl.warn("message-to-log: Lambda", LOG_EXCEPTION))).toString(); + System.out.println("*** speedLambda →\t\t"+st); + assertEquals(MAX_LOOP_WARM, fl.getAsLong()); + } + @Test public void speedLambdaMethodRef () { + FakeLogger fl = new FakeLogger(){ + @Override public void run () { + warn("message-to-log: LambdaMethodRef", LOG_EXCEPTION); + } + }; + + String st = Loops.loopMeasuredWarm(MAX_LOOP, Wrap.runnable(fl::run)).toString(); + System.out.println("*** speedLambdaMethodRef →\t\t"+st); + assertEquals(MAX_LOOP_WARM, fl.getAsLong()); + } + + private static final MethodHandle staticMethodHandle; + static {// Static MethodHandle setup ^ + try { + Object fl = getActualLogger("org.jooq.lambda.ExtraMagicTest$FakeLogger", ExtraMagicTest.class); + + MethodHandles.Lookup lookup = MethodHandles.lookup(); + //1. method → MethodHandle + //m = LambdaLogFacade.getWarnMethod(fl); + //staticMethodHandle = lookup.unreflect(m); + //2. .asType for invokeExact (vs invoke) + staticMethodHandle = lookup.findVirtual(fl.getClass(), "warn", + MethodType.methodType(Void.TYPE, String.class, Throwable.class)) + .asType(MethodType.methodType(Void.TYPE, LongSupplier.class/*this*/, + /*args:*/ String.class, Throwable.class)); + } catch (IllegalAccessException | NoSuchMethodException e) { + throw new IllegalStateException(e); + } + } + + @Test public void speedStaticMethodHandle () throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { + Class cls = Class.forName("org.jooq.lambda.ExtraMagicTest$FakeLogger"); + final LongSupplier fl = (LongSupplier) cls.getConstructor().newInstance(); + + String st = Loops.loopMeasuredWarm(MAX_LOOP, Unchecked.runnable(() -> { + staticMethodHandle.invokeExact(fl, "message-to-log: MH", LOG_EXCEPTION);//vs invoke (ivoke is slower, but w/o .asType↑) + //invokeExact→java.lang.invoke.WrongMethodTypeException: expected (FakeLogger,String,Throwable)void but found (LongSupplier,String,Exception)void + })).toString(); + System.out.println("*** speedStaticMethodHandle →\t\t"+st); + assertEquals(MAX_LOOP_WARM, fl.getAsLong()); + } + + + private static final Method staticMethod; + static { + Object fl = getActualLogger("org.jooq.lambda.ExtraMagicTest$FakeLogger", ExtraMagicTest.class); + staticMethod = LambdaLogFacade.getWarnMethod(fl); + } + @Test public void speedStaticReflection () throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { + Class cls = Class.forName("org.jooq.lambda.ExtraMagicTest$FakeLogger"); + final LongSupplier fl = (LongSupplier) cls.getConstructor().newInstance(); + + String st = Loops.loopMeasuredWarm(MAX_LOOP, Unchecked.runnable(() -> + staticMethod.invoke(fl, "message-to-log: Reflection", LOG_EXCEPTION))).toString(); + System.out.println("*** speedStaticReflection →\t\t"+st); + assertEquals(MAX_LOOP_WARM, fl.getAsLong()); + } + + + private static final Consumer3 staticLambda; + static {// Static Lambda setup ^ + try { + Object fl = getActualLogger("org.jooq.lambda.ExtraMagicTest$FakeLogger", ExtraMagicTest.class); + + MethodHandles.Lookup lookup = MethodHandles.lookup(); + //1. method → MethodHandle + Method m = LambdaLogFacade.getWarnMethod(fl); + MethodHandle mhLogWarn = lookup.unreflect(m); + + MethodType genericMethodType = MethodType.methodType(Void.TYPE, fl.getClass()/*logger*/, String.class, Throwable.class); + + CallSite callSite = LambdaMetafactory.metafactory( + lookup,// method handle lookup + "accept",//Interface Method Name: name of the method defined in the target functional interface: Consumer::accept + + // type to be implemented and captured objects + // e.g. String instance to be trimmed is captured: MethodType.methodType(Supplier.class, String.class) + MethodType.methodType(Consumer3.class), + + // type erasure, Consumer3 will accept 3 Object NOT Void.TYPE, Object.class/*logger*/, String.class, Throwable.class + MethodType.methodType(Void.TYPE, Object.class/*logger*/, Object.class, Object.class), + + mhLogWarn,// method handle to transform + + // Consumer3 method real signature (reified) + // e.g. Supplier=trim accepts no parameters and returns String: MethodType.methodType(String.class) + genericMethodType); + + //noinspection unchecked + staticLambda = (Consumer3) callSite.getTarget() + /*.bindTo(contextObject e.g. "str")*/ + .invokeExact();// or invoke + + } catch (Throwable invokeExactEx) { + invokeExactEx.printStackTrace(); + throw new IllegalStateException(invokeExactEx); + } + } + @Test public void speedStaticLambda () { + Object fl = getActualLogger("org.jooq.lambda.ExtraMagicTest$FakeLogger", ExtraMagicTest.class); + + String st = Loops.loopMeasuredWarm(MAX_LOOP, Unchecked.runnable(() -> + staticLambda.accept(fl, "message-to-log: StaticLambda", LOG_EXCEPTION))).toString(); + System.out.println("*** speedStaticLambda →\t\t"+st); + assertEquals(MAX_LOOP_WARM, ((LongSupplier) fl).getAsLong()); + } + + /** Get slf4j.Logger, JUL Logger, or log4j Logger */ + static Object getActualLogger (String loggerFactoryClassName, Class clazzWhereLogger) { + Method loggerFactoryGetLogger = LambdaLogFacade.findLoggerFactoryGetLogger(loggerFactoryClassName); + if (loggerFactoryGetLogger == null) { return null;}// LoggerFactory not found in classpath + return LambdaLogFacade.invokeGetLogger(loggerFactoryGetLogger, clazzWhereLogger); + } + + + @Test public void lambdaLogFacadeLoggerTest () throws InterruptedException { + LambdaLogFacade log = LambdaLogFacade.getLogger(ExtraMagicTest.class); + assertSame(ExtraMagicTest.class, log.loggerAppClassName);// ^^^ + + printToStdErr(null, "#1 staticLoggerFactoryGetLoggerMethod= "+LambdaLogFacade.staticLoggerFactoryGetLoggerMethod, null); + printToStdErr(null, "#2 staticWarnMethodHandle= "+LambdaLogFacade.staticWarnMethodHandle, null); + assertEquals(winner, LambdaLogFacade.staticLoggerFactoryGetLoggerMethod); + + log.warn("lambdaLogFacade #1", null); + log.warn("lambdaLogFacade #2", new Throwable("#2 Test Throwable")); + log.warn("lambdaLogFacade #3", new Error("#3 Test Error")); + String msg = "lambdaLogFacade #4"; + Exception t = new Exception("#4 Test Error"); + log.warn(msg, t); + if (winner != null && winner.toString().contains("LoggerOverride")) { + assertEquals(4, LoggerOverride.CNT.get()); + assertSame(msg, LoggerOverride.lastMessage); + assertSame(t, LoggerOverride.lastThrowable); + } else { + System.err.println("WINNER is not LoggerOverride, so no checks"); + } + + final int THREADS = 100; + final CountDownLatch startSignal = new CountDownLatch(1); + final CountDownLatch doneSignal = new CountDownLatch(THREADS); + loop(THREADS, (num) -> new Thread(()->{ + Wrap.run(startSignal::await); + log.warn("Hello from thread "+num, new Exception("Thread "+num)); + loop(999, () -> log.warn("Hello from thread "+num, null)); + + Wrap.run(doneSignal::countDown); + }, "lambdaLogFacade-"+num).start()); + startSignal.countDown();// let's go! + doneSignal.await(); + assertNull(FAILED); + + if (winner != null && winner.toString().contains("LoggerOverride")) { + assertEquals(THREADS * 1000 + 4, LoggerOverride.CNT.get()); + } + } + + public static class LoggerOverride extends LambdaLogFacade { + public LoggerOverride () { + super(null); + }//new + + static final AtomicLong CNT = new AtomicLong(); + static String lastMessage; + static Throwable lastThrowable; + + public static LoggerOverride getLogger (String notUsed) { + return new LoggerOverride(); + } + @Override public void warn (String msg, Throwable t) { + CNT.incrementAndGet(); + lastMessage = msg; + lastThrowable = t; + if (t != null || msg.startsWith("lambda")) { + System.out.println("LoggerOverride.warn >>> "+msg+"\t>>> "+t+" # "+Thread.currentThread()); + } + } + }//LoggerOverride + + @Test public void lambdaLogFacadeToStdErr () { + LambdaLogFacade.LambdaLogFacadeStdErr log = new LambdaLogFacade.LambdaLogFacadeStdErr(ExtraMagicTest.class); + assertSame(ExtraMagicTest.class, log.loggerAppClassName);// ^^^ + log.warn("Test message to System.err #1", null); + log.warn("Test message to System.err #2 'with Throwable/Exception'", + new IOException("#2 Test Throwable/Exception to System.err")); + } + +} \ No newline at end of file diff --git a/jOOL/src/test/java/org/jooq/lambda/LoopsTest.java b/jOOL/src/test/java/org/jooq/lambda/LoopsTest.java new file mode 100644 index 00000000..584616f7 --- /dev/null +++ b/jOOL/src/test/java/org/jooq/lambda/LoopsTest.java @@ -0,0 +1,266 @@ +package org.jooq.lambda; + +import org.jooq.lambda.tuple.Tuple4; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.LongSummaryStatistics; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.LongConsumer; +import java.util.function.LongPredicate; +import java.util.function.Predicate; + +import static org.jooq.lambda.Loops.loop; +import static org.jooq.lambda.Loops.loopMeasured; +import static org.jooq.lambda.Loops.loopMeasuredWarm; +import static org.jooq.lambda.Loops.loopWhile; +import static org.junit.Assert.*; + +public class LoopsTest { + + static class LongSummaryStatisticsP extends LongSummaryStatistics implements LongPredicate { + int stopAt; + + public LongSummaryStatisticsP (int min) { stopAt = min; }//new + public LongSummaryStatisticsP () {}//new + + @Override public boolean test (long value) { + if (value < stopAt) return false;//stop + accept(value); + return true; + } + } + + @Test public void testLoopRunnable () { + loop(0, (Runnable) null); + loop(-2, (Runnable) null); + AtomicLong counter = new AtomicLong(); + Runnable r = counter::incrementAndGet; + + loop(0, r); + assertEquals(0, counter.get()); + + loop(-1, r); + assertEquals(0, counter.get()); + + loop(1, r); + assertEquals(1, counter.get()); + + loop(10_123, r); + assertEquals(10_124, counter.get()); + } + + @Test public void testLoopConsumer () { + loop(0, (LongConsumer) null); + loop(-2, (LongConsumer) null); + final LongSummaryStatistics stat = new LongSummaryStatistics(); + + loop(0, stat); + assertEquals(0, stat.getCount()); + + loop(-1, stat); + assertEquals(0, stat.getCount()); + + loop(1, stat); + assertEquals(1, stat.getCount()); + + loop(10_123, stat); + assertEquals(10_124, stat.getCount()); + assertEquals(10_122, stat.getMax());// 10_123 = 10_122..0 + assertEquals(0, stat.getMin()); + } + + @Test public void testLoopPredicate () { + loopWhile(0, null); + loopWhile(-2, null); + final LongSummaryStatisticsP s = new LongSummaryStatisticsP(); + + loopWhile(0, s); + assertEquals(0, s.getCount()); + + loopWhile(-1, s); + assertEquals(0, s.getCount()); + + loopWhile(1, s); + assertEquals(1, s.getCount()); + + loopWhile(10_123, s); + assertEquals(10_124, s.getCount()); + assertEquals(10_122, s.getMax());// 10_123 = 10_122..0 + assertEquals(0, s.getMin()); + } + + @Test public void testLoopPredicateDoWhile () { + final LongSummaryStatisticsP s = new LongSummaryStatisticsP(10); + + loopWhile(0, s); + assertEquals(0, s.getCount()); + + loopWhile(-1, s); + assertEquals(0, s.getCount()); + + loopWhile(1, s); + assertEquals(0, s.getCount()); + + loopWhile(10_123, s); + assertEquals(10_123-10, s.getCount());//10 = 0..9 + assertEquals(10_122, s.getMax());// 10_123 is max, starting with 10_122 + assertEquals(10, s.getMin()); + } + + + @Test public void testLoopMeasured () { + Tuple4 st = loopMeasured(0, null); + System.out.println(st); + assertEquals("LongSummaryStatistics{count=0, sum=0, min=9223372036854775807, average=0,000000, max=-9223372036854775808}", st.v2.toString()); + st = loopMeasured(0, null); + assertEquals(0, st.v2.getCount()); + st = loopMeasured(-2, null); + assertEquals(0, st.v2.getCount()); + + st = loopMeasured(1, null); + assertTrue(st.v3.toString().startsWith("java.lang.NullPointerException: Cannot invoke \"java.lang.Runnable.run()\" because \"body\" is null")); + assertEquals(1, st.v2.getCount()); + + final AtomicLong counter = new AtomicLong(); + final Runnable r = counter::incrementAndGet; + + st = loopMeasured(0, r); + System.out.println(st); + assertEquals(0, counter.get()); + assertEquals(0, st.v2.getCount()); + + st = loopMeasured(-1, r); + assertEquals(0, counter.get()); + assertEquals(0, st.v2.getCount()); + + st = loopMeasured(1, r); + System.out.println(st); + assertEquals(1, counter.get()); + assertEquals(1, st.v2.getCount()); + + st = loopMeasured(10_123, r); + System.out.println(st); + assertEquals(10_124, counter.get()); + assertEquals(10_123, st.v2.getCount()); + } + + + @Test public void testLoopMeasuredWarm () { + final AtomicLong counter = new AtomicLong(); + Tuple4 st = loopMeasuredWarm(10_000_000, counter::incrementAndGet); + System.out.println(st); + assertEquals(10_000_000, st.v2.getCount()); + assertEquals(10_050_000, counter.get()); + } + + + @Test public void testIncrement () { + Loops.Incrementer x = new Loops.Incrementer(3, 100); + assertEquals(3, x.degree()); + for (int i=0; i<100; i++) { + for (int j=0; j<100; j++) { + for (int k=0; k<100; k++) { + assertEquals(i, x.indexes[2]); + assertEquals(j, x.indexes[1]); + assertEquals(k, x.indexAt(0)); + boolean overflow = x.incrementIndexVector(); + assertEquals(i==99 && j==99 && k==99, overflow); + } + } + } + + x = new Loops.Incrementer(16, 2); + assertEquals(16, x.degree()); + for (int i=0; i<0x1_00_00; i++) { + int tmp = i; + for (int j=0; j<16; j++) { + assertEquals(tmp & 1, x.indexes[j]); + tmp = tmp >> 1; + } + boolean overflow = x.incrementIndexVector();// 0..1 + assertEquals(i==0xFF_FF, overflow); + } + + x = new Loops.Incrementer(5000, 1); + assertEquals(5000, x.degree()); + assertTrue(x.incrementIndexVector());//only one valid state 0,0,0,0,... + } + + @Test public void testIncrement2 () { + int[] max = {200,50,10}; + Loops.Incrementer x = new Loops.Incrementer(max); + assertEquals(3, x.degree()); + for (int i=0; i<10; i++) { + for (int j=0; j<50; j++) { + for (int k=0; k<200; k++) { + assertEquals(i, x.indexes[2]); + assertEquals(j, x.indexes[1]); + assertEquals(k, x.indexes[0]); + boolean overflow = x.incrementIndexVector(); + assertEquals(i==9 && j==49 && k==199, overflow); + } + } + } + assertEquals("Incrementer[0, 0, 0]", x.toString()); + assertEquals(200, x.maxAt(0)); + assertEquals(50, x.maxAt(1)); + max[2] = 42; + assertEquals(42, x.maxAt(2)); + + max = new int[16]; + Arrays.fill(max, 2); + x = new Loops.Incrementer(max); + assertEquals(16, x.degree()); + for (int i=0; i<0x1_00_00; i++) { + int tmp = i; + for (int j=0; j<16; j++) { + assertEquals(tmp & 1, x.indexes[j]); + tmp = tmp >> 1; + } + boolean overflow = x.incrementIndexVector();// 0..1 + assertEquals(i==0xFF_FF, overflow); + } + + max = new int[1000]; + Arrays.fill(max, 1); + x = new Loops.Incrementer(max); + assertEquals(1000, x.degree()); + assertTrue(x.incrementIndexVector()); + } + + + @Test public void testForLoop () { + int[] arr = new int[11]; + Loops.forLoop(arr.length, (i)->{arr[i]=i;}); + assertEquals("[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]", Arrays.toString(arr)); + + List list = new ArrayList<>(100); + + Predicate gen = (inc)->{ + list.add(inc.indexAt(1)+"*"+inc.indexAt(0)+"="+inc.indexAt(1)*inc.indexAt(0)); + return list.size()>=100; + }; + + Loops.Incrementer x = new Loops.Incrementer(2, 10); + assertTrue(x.forLoop(gen)); + for (int i=0; i<10; i++) { + for (int j=0; j<10; j++) { + assertEquals(i+"*"+j+"="+i*j, list.get(i*10+j)); + } + } + + list.clear(); + x = new Loops.Incrementer(new int[]{10,10}); + assertTrue(x.forLoop(gen)); + for (int i=0; i<10; i++) { + for (int j=0; j<10; j++) { + assertEquals(i+"*"+j+"="+i*j, list.get(i*10+j)); + } + } + } + + +} \ No newline at end of file diff --git a/jOOL/src/test/java/org/jooq/lambda/WrapTest.java b/jOOL/src/test/java/org/jooq/lambda/WrapTest.java new file mode 100644 index 00000000..b6b7cdde --- /dev/null +++ b/jOOL/src/test/java/org/jooq/lambda/WrapTest.java @@ -0,0 +1,857 @@ +package org.jooq.lambda; + +import org.jooq.lambda.fi.util.concurrent.SafeCallable; +import org.jooq.lambda.fi.util.function.CheckedBiFunction; +import org.jooq.lambda.fi.util.function.CheckedToDoubleBiFunction; +import org.jooq.lambda.tuple.Tuple2; +import org.junit.Test; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.ArrayList; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Optional; +import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Supplier; +import java.util.stream.Stream; + +import static org.jooq.lambda.Wrap.predicate; +import static org.jooq.lambda.Wrap.predicateDef; +import static org.junit.Assert.*; + +public class WrapTest { + + @Test(expected = ClassCastException.class) + public void testCastUnsafe () { + //java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Integer (java.lang.String and java.lang.Integer are in module java.base of loader 'bootstrap') + Integer x = Wrap.castUnsafe("1"); + System.err.println(x); + } + @Test(expected = ClassCastException.class) + public void testCast () { + //java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Integer (java.lang.String and java.lang.Integer are in module java.base of loader 'bootstrap') + Integer x = Wrap.cast(Integer.class, "1"); + System.err.println(x); + } + + @Test public void castUnsafe () { + Number o = 42L; + long v = Wrap.castUnsafe(o); + assertEquals(42, v); + + Object x = new ArrayList(); + List y = Wrap.castUnsafe(x); + y.add("test"); + + List l1 = new ArrayList<>(); + List l2 = Wrap.castUnsafe(l1);// dangerous! Don't use for this! + l2.add("test");// → add "test" to List l1 + Object boom1 = l1.get(0); + Object boom2 = l2.get(0); + assertSame(boom1, boom2); + assertEquals("test", boom1); + } + @Test public void cast () { + Number o = 42L; + long v = Wrap.cast(Long.class, o); + assertEquals(42, v); + + Object x = new ArrayList(); + List y = Wrap.cast(List.class, x); + y.add("test"); + + List l1 = new ArrayList<>(); + List l2 = Wrap.cast(List.class, l1);// dangerous! Don't use for this! + l2.add("test");// → add "test" to List l1 + Object boom1 = l1.get(0); + Object boom2 = l2.get(0); + assertSame(boom1, boom2); + assertEquals("test", boom1); + assertEquals(1, l1.size()); + } + + @Test(expected = NullPointerException.class) + public void castUnsafeNullToPrimitive () { + Boolean b1 = null; + try { + Boolean b2 = Wrap.castUnsafe(b1); + assertNull(b2); + } catch (Throwable e) { + fail("(Boolean) null must be just fine "+e); + } + + boolean b3 = Wrap.castUnsafe(b1); + fail("^^^ NPE!"); + } + @Test(expected = NullPointerException.class) + public void castNullToPrimitive () { + Boolean b1 = null; + try { + Boolean b2 = Wrap.cast(boolean.class, b1); + assertNull(b2); + } catch (Throwable e) { + fail("(Boolean) null must be just fine "+e); + } + + boolean b3 = Wrap.cast(boolean.class, b1); + fail("^^^ NPE!"); + } + + + + @Test public void testCallable () throws Throwable { + { + Callable callable = Wrap.callableDef(() -> { + throw new IOException("log me"); + }, "");//with default value + assertTrue(callable instanceof SafeCallable.Generated); + assertEquals("", callable.call()); + assertEquals("", ((Supplier) callable).get()); + ((SafeCallable) callable).execute(); + assertNull(((SafeCallable) callable).handleThrowable(null)); + } + { + SafeCallable> c2 = Wrap.callable(" xxx "::trim); + assertTrue(c2 instanceof SafeCallable.Generated); + assertEquals("Either(xxx)", c2.call().toString()); + assertEquals("xxx", c2.get().v1); + assertEquals("xxx", c2.call().call()); + assertEquals("xxx", c2.execute().optValue().orElse(null)); + assertNull(c2.handleThrowable(null)); + + System.err.println("*** NullPointerException with Either"); + + c2 = Wrap.callable(() -> new String((char[]) null)); + assertTrue(c2 instanceof SafeCallable.Generated); + assertTrue(c2.get().v2 instanceof NullPointerException); + assertFalse(c2.call().optValue().isPresent()); + assertFalse(c2.execute().isPresent()); + assertTrue(c2.call().isFailure()); + assertTrue(c2.call().isEmpty()); + assertNull(c2.handleThrowable(null)); + } + { + SafeCallable.Generated c = Wrap.cast(SafeCallable.Generated.class, + Wrap.callable(WrapTest::divZero, (Throwable t)-> + { + assertTrue(t.toString(), t instanceof ArithmeticException); + return 42; + })); + assertEquals(42, c.get().intValue()); + assertEquals(42, c.call().intValue()); + assertEquals(42, c.execute().intValue()); + assertNull(c.handleThrowable(new Information("not used in Generated"))); + } + } + + static class Information extends IOException { + static final long serialVersionUID = 1;// make javac and error-prone happy + public Information (Object message) { super(message.toString());} + @Override public synchronized Throwable fillInStackTrace () { return this;} + } + + + @Test public void testPredicate () { + Object[] arr = {1,2,3, null, "str", 3.14, true, (byte)42}; + + long len = Stream.of(arr).filter( + predicate((value) -> ((Integer) value) > 0) + ).count(); + assertEquals(3, len); + + len = Seq.of(arr).filter( + predicateDef((v)->Double.parseDouble(v.toString())>0, true) + ).count(); + assertEquals(arr.length, len); + + len = Seq.of(arr).filter( + predicateDef((v)->Double.parseDouble(v.toString())>0, false) + ).count(); + assertEquals(5, len);// false only for 3: null, "str", true + + // NullPointerException: Cannot invoke "java.lang.Number.intValue()" because "v" is null + // ClassCastException: String, Boolean cannot be cast to Number + len = Seq.of(arr).filter( + predicate((v)->((Number) v).intValue() > 0, (a,t)-> + { + if (a == null) { + assertTrue(t instanceof NullPointerException); + return true; + } + return false; + }) + ).count(); + assertEquals(6, len);// 5 +1 null + } + + + @Test public void eitherNull () throws Exception { + Either zzz = Either.success(null); + assertEquals(zzz, zzz); + assertEquals(zzz, Either.empty()); + assertEquals(Either.success(null), Either.success(null)); + assertEquals(zzz, Optional.empty()); + + Either ei = Either.success(null); + assertEquals(new Tuple2(null,null), ei); + assertNull(ei.call()); + assertTrue(ei.isSuccess()); + assertFalse(ei.isFailure()); + assertFalse(ei.isPresent()); + assertTrue(ei.isEmpty()); + assertTrue(ei.isNull()); + assertEquals(0, ei.stream().count()); + assertEquals(31*31, ei.hashCode()); + assertEquals("Either.Empty", ei.toString()); + + ei.ifPresent((value)->fail("null==empty==!present")); + assertNull(ei.v2); + assertEquals(Optional.empty(), ei.optThrowable()); + ei.throwIfFailure(); + + AtomicInteger cnt = new AtomicInteger(); + ei.ifEmpty((Throwable t) -> { + assertNull(t); + cnt.incrementAndGet(); + }); + assertEquals(1, cnt.get()); + ei.ifNull(cnt::incrementAndGet); + assertEquals(2, cnt.get()); + ei.ifFailure((t)->fail("null==success==!failure")); + ei.ifSuccess((Integer v) -> { + assertNull(v); + cnt.incrementAndGet(); + }); + assertEquals(3, cnt.get()); + try { + ei.throwIfEmpty(); + fail("unreachable: null value == !present"); + } catch (NoSuchElementException e) { + assertEquals("java.util.NoSuchElementException: No value present", e.toString()); + } + try { + ei.throwIfNull(); + fail("unreachable: null value == !present"); + } catch (NoSuchElementException e) { + assertEquals("java.util.NoSuchElementException: No value present", e.toString()); + } + } + + @Test public void eitherValue () throws Exception { + Either zzz = Either.success(9); + assertEquals(zzz, zzz); + assertEquals(zzz, Either.success(9)); + assertEquals(zzz, 9); + assertEquals(9, zzz.v1.intValue()); + assertEquals(9, zzz.optValue().get().intValue()); + assertNull(zzz.v2); + + Either ei = Either.success(9); + assertEquals(new Tuple2(9,null), ei); + assertEquals(9, ei.call().intValue()); + assertTrue(ei.isSuccess()); + assertFalse(ei.isFailure()); + assertTrue(ei.isPresent()); + assertFalse(ei.isEmpty()); + assertFalse(ei.isNull()); + assertEquals(1, ei.stream().count()); + assertEquals(9, ei.stream().toArray()[0]); + assertEquals((31+9)*31, ei.hashCode()); + assertEquals("Either(9)", ei.toString()); + assertNull(ei.v2); + assertEquals(Optional.empty(), ei.optThrowable()); + ei.throwIfFailure().throwIfNull().throwIfEmpty(); + + AtomicInteger cnt = new AtomicInteger(); + ei.ifPresent((Integer v)->cnt.incrementAndGet()); + assertEquals(1, cnt.get()); + + ei.ifEmpty((Throwable t)->fail("!empty")); + ei.ifNull(()->fail("!null")); + ei.ifFailure((Throwable t)->fail("null==success==!failure")); + ei.ifSuccess((Integer v) -> { + assertEquals(9, v.intValue()); + cnt.incrementAndGet(); + }); + assertEquals(2, cnt.get()); + assertEquals(9, ei.call().intValue()); + assertEquals(9, ei.v1.intValue()); + assertEquals(9, ei.optValue().get().intValue()); + assertEquals(ei, Optional.of(9)); + } + + @Test public void eitherThrowable () throws Exception { + Information ex = new Information("I am Either.Failure!"); + Either zzz = Either.failure(ex); + assertEquals(zzz, zzz); + assertNotEquals(zzz, null); + assertEquals(zzz, Either.failure(ex)); + //assertEquals(Either.failure(ex), Optional.empty()); + assertEquals(Either.failure(ex), ex); + + Either ei = Either.failure(ex); + assertEquals(new Tuple2(null,ex), ei); + + try { + ei.call(); + fail("unracahble: ^ throws ex"); + } catch (Information ex2) { + assertSame(ex, ex2); + } + assertFalse(ei.isSuccess()); + assertTrue(ei.isFailure()); + assertFalse(ei.isPresent()); + assertTrue(ei.isEmpty()); + assertFalse(ei.isNull()); + assertEquals(0, ei.stream().count()); + assertTrue(ei.hashCode() != 0); + assertEquals("Either.Failure(org.jooq.lambda.WrapTest$Information: I am Either.Failure!)", ei.toString()); + + ei.ifPresent((value)->fail("null==empty==!present")); + assertSame(ex, ei.v2); + assertSame(ex, ei.optThrowable().get()); + assertNull(ei.v1); + assertEquals(Optional.empty(), ei.optValue()); + try { + ei.throwIfFailure(); + fail("unracahble: ^ throws"); + } catch (IllegalStateException x) { + assertSame(ex, x.getCause()); + assertEquals("java.lang.IllegalStateException: Throwable instead of value", x.toString()); + } + + AtomicInteger cnt = new AtomicInteger(); + ei.ifEmpty((Throwable t) -> { + assertSame(ex, t); + cnt.incrementAndGet(); + }); + assertEquals(1, cnt.get()); + ei.ifNull(()->fail("failure != null")); + ei.ifFailure((Throwable t) -> { + assertSame(ex, t); + cnt.incrementAndGet(); + }); + assertEquals(2, cnt.get()); + + ei.ifSuccess((Integer v)->fail("failure!")); + try { + ei.throwIfEmpty(); + fail("unreachable: isFailure"); + } catch (IllegalStateException e) { + assertEquals("java.lang.IllegalStateException: Throwable instead of value", e.toString()); + } + ei.throwIfNull(); + } + + + @Test public void eitherMix () { + Either z = Either.success(null); + z.consume((v,t)->{ + assertNull(v); + assertNull(t); + }); + assertEquals("Either.Empty", z.toString()); + assertNull(z.either()); + + z = Either.success(""); + z.consume((v,t)->{ + assertEquals("", v); + assertNull(t); + }); + assertEquals("Either()", z.toString()); + assertEquals("", z.either()); + + Information ex = new Information("{x}"); + z = Either.failure(ex); + z.consume((v,t)->{ + assertNull(v); + assertSame(ex, t); + }); + assertEquals("Either.Failure(org.jooq.lambda.WrapTest$Information: {x})", z.toString()); + assertEquals(ex, z.either()); + } + + + @Test public void directRunAndCall () { + assertTrue(Wrap.run(()->{})); + assertTrue(Wrap.runStd(()->{})); + assertFalse(Wrap.run(()->{throw new Information("#1");})); + assertFalse(Wrap.runStd(()->{throw new RuntimeException("#2");})); + + assertEquals(Either.empty(), Wrap.call(()->null)); + assertEquals(Either.empty(), Wrap.callStd(()->null)); + assertEquals(42, Wrap.call(()->42).v1.intValue()); + assertEquals(3.14, (Object) Wrap.callStd(()->3.14).v1); + assertEquals("Either.Failure(org.jooq.lambda.WrapTest$Information: Hi!)", + Wrap.call(()->{throw new Information("Hi!");}).toString()); + assertEquals("Either.Failure(java.lang.ArithmeticException: / by zero)", + Wrap.callStd(()->1/0).toString()); + } + + + @Test public void testRunnable () { + Wrap.runnable(()->{}).run(); + + AtomicInteger cnt = new AtomicInteger(); + Wrap.runnable(cnt::incrementAndGet).run(); + assertEquals(1, cnt.get()); + + Wrap.runnable(null).run(); + } + + + @Test public void safeThrows () { + Exception e = new Exception("Checked!"); + IOException io = new IOException(); + InterruptedException ie = new InterruptedException(); + Wrap.throwIfError(e); + Wrap.throwIfError(new RuntimeException()); + Wrap.throwIfError(io); + Thread.interrupted(); + Wrap.throwIfError(ie); + assertTrue(Thread.interrupted()); + + Wrap.throwIfErrorOrRuntime(e); + Wrap.throwIfErrorOrRuntime(io); + Wrap.throwIfErrorOrRuntime(ie); + assertTrue(Thread.interrupted()); + + Wrap.throwIfErrorOrRuntimeOrIo(e); + Wrap.throwIfErrorOrRuntimeOrIo(ie); + assertTrue(Thread.interrupted()); + assertFalse(Thread.interrupted()); + + Wrap.handleInterruptedException(ie); + assertTrue(Thread.interrupted()); + assertFalse(Thread.interrupted()); + + Wrap.handleInterruptedException((Throwable)ie); + assertTrue(Thread.interrupted()); + assertFalse(Thread.interrupted()); + } + + + @Test(expected = Error.class) + public void throw1 () { + Wrap.throwIfError(new Error()); + } + + @Test(expected = RuntimeException.class) + public void throw2 () { + Wrap.throwIfErrorOrRuntime(new RuntimeException()); + } + + @Test(expected = UncheckedIOException.class) + public void throw3 () { + Wrap.throwIfErrorOrRuntimeOrIo(new Information(1)); + // java.io.UncheckedIOException: org.jooq.lambda.WrapTest$Information: 1 + } + + + @Test public void testPredicates () { + assertTrue(Wrap.predicate((Boolean v)->v).test(true)); + assertFalse(Wrap.predicate((Boolean v)->v).test(false)); + assertFalse(Wrap.predicate((Boolean v)->v).test(null)); + + assertTrue(Wrap.predicateDef((Boolean v)->v, true).test(true)); + assertFalse(Wrap.predicateDef((Boolean v)->v, true).test(false)); + assertTrue(Wrap.predicateDef((Boolean v)->v, true).test(null)); + + assertTrue(Wrap.predicate((Boolean v)->v, (Boolean v,Throwable t)->{ + throw new AssertionError("unreachable");}).test(true)); + assertFalse(Wrap.predicate((Boolean v)->v, (Boolean v,Throwable t)->{ + throw new AssertionError("unreachable");}).test(false)); + assertTrue(Wrap.predicate((Boolean v)->v, (Boolean v,Throwable t)->{ + assertNull(v); + assertTrue(t instanceof NullPointerException); + return true;}).test(null)); + } + + @Test public void testBiPredicates () { + assertTrue(Wrap.biPredicate((Byte x,Byte y)->xxxxxxx{ + throw new AssertionError("unreachable");}).test((byte)1,(byte)2)); + assertFalse(Wrap.biPredicate((Byte x,Byte y)->x{ + throw new AssertionError("unreachable");}).test((byte)1,(byte)1)); + assertTrue(Wrap.biPredicate((Byte x,Byte y)->x{ + assertNull(x); + assertEquals((byte)2,(Object)y); + assertTrue(t instanceof NullPointerException); + return true;}).test(null,(byte)2)); + } + + @Test public void testDoublePredicates () { + assertTrue(Wrap.doublePredicate((double v)->v>0).test(1)); + assertFalse(Wrap.doublePredicate((double v)->v>0).test(-1)); + assertFalse(Wrap.doublePredicate((double v)->{throw new Exception();}).test(1)); + + assertTrue(Wrap.doublePredicateDef((double v)->v>0, true).test(1)); + assertFalse(Wrap.doublePredicateDef((double v)->v>0, true).test(-1)); + assertTrue(Wrap.doublePredicateDef((double v)->{throw new Exception();}, true).test(0)); + + assertTrue(Wrap.doublePredicate((double v)->v>0, (Double v,Throwable t)->{ + throw new AssertionError("unreachable");}).test(1)); + assertFalse(Wrap.doublePredicate((double v)->v>1, (Double v,Throwable t)->{ + throw new AssertionError("unreachable");}).test(0)); + assertTrue(Wrap.doublePredicate((double v)->{throw new IOException();}, (Double v,Throwable t)->{ + assertEquals(1, v, 0.01); + assertTrue(t instanceof IOException); + return true;}).test(1)); + } + + @Test public void testLongPredicates () { + assertTrue(Wrap.longPredicate((long v)->v>0).test(1)); + assertFalse(Wrap.longPredicate((long v)->v>0).test(-1)); + assertFalse(Wrap.longPredicate((long v)->{throw new Exception();}).test(1)); + + assertTrue(Wrap.longPredicateDef((long v)->v>0, true).test(1)); + assertFalse(Wrap.longPredicateDef((long v)->v>0, true).test(-1)); + assertTrue(Wrap.longPredicateDef((long v)->{throw new Exception();}, true).test(0)); + + assertTrue(Wrap.longPredicate((long v)->v>0, (Long v,Throwable t)->{ + throw new AssertionError("unreachable");}).test(1)); + assertFalse(Wrap.longPredicate((long v)->v>1, (Long v,Throwable t)->{ + throw new AssertionError("unreachable");}).test(0)); + assertTrue(Wrap.longPredicate((long v)->{throw new IOException();}, (Long v,Throwable t)->{ + assertEquals(1, v.longValue()); + assertTrue(t instanceof IOException); + return true;}).test(1)); + } + + @Test public void testIntPredicates () { + assertTrue(Wrap.intPredicate((int v)->v>0).test(1)); + assertFalse(Wrap.intPredicate((int v)->v>0).test(-1)); + assertFalse(Wrap.intPredicate((int v)->{throw new Exception();}).test(1)); + + assertTrue(Wrap.intPredicateDef((int v)->v>0, true).test(1)); + assertFalse(Wrap.intPredicateDef((int v)->v>0, true).test(-1)); + assertTrue(Wrap.intPredicateDef((int v)->{throw new Exception();}, true).test(0)); + + assertTrue(Wrap.intPredicate((int v)->v>0, (Integer v,Throwable t)->{ + throw new AssertionError("unreachable");}).test(1)); + assertFalse(Wrap.intPredicate((int v)->v>1, (Integer v,Throwable t)->{ + throw new AssertionError("unreachable");}).test(0)); + assertTrue(Wrap.intPredicate((int v)->{throw new IOException();}, (Integer v,Throwable t)->{ + assertEquals(1, v, 0.01); + assertTrue(t instanceof IOException); + return true;}).test(1)); + } + + + @Test public void predicateWithLogHandler () { + assertTrue(Wrap.predicate((v)->{throw new IOException();}, + (Object v, Throwable t)->{ + assertEquals(1, v); + assertTrue(t instanceof IOException); + return true; + }).test(1)); + assertTrue(Wrap.predicate((v)->{throw new IOException();}, + Wrap.P1_LOG_WARN_TRUE + ).test(1)); + assertTrue(Wrap.predicate((v)->{throw new IOException();}, + Wrap.P1_SILENT_IGNORE_ALL_TRUE + ).test(1)); + assertFalse(Wrap.predicate((v)->{throw new IOException();}, + Wrap.P1_SILENT_IGNORE_ALL_FALSE + ).test(1)); + } + + + @Test public void testFunctions () { + assertEquals("Either(9)", Wrap.function((i)->""+i).apply(9).toString()); + assertEquals("9", Wrap.function((i)->""+i, (i,t)->{ + assertEquals(9, i); + assertNull(t); + return null; + }).apply(9)); + assertEquals("9", Wrap.functionDef((i)->""+i, "x").apply(9)); + + assertEquals("Either.Failure(org.jooq.lambda.WrapTest$Information: f1.1)", + Wrap.function((i)->{throw new Information("f1.1");}).apply(9).toString()); + assertEquals("H", Wrap.function((i)->{throw new Information("f1.2");}, (i,t)->{ + assertEquals(9, i); + assertTrue(t instanceof Information); + return "H"; + }).apply(9)); + assertEquals("x", Wrap.functionDef((i)->{throw new Information("f1.3");}, "x").apply(9)); + // + CheckedBiFunction cbif = (a,b)->""+a+b; + assertEquals("Either(12)", Wrap.biFunction(cbif).apply(1,2).toString()); + assertEquals("12", Wrap.biFunction(cbif, (a,b,t)->{ + assertEquals((Integer)1, a); + assertEquals((Integer)2, b); + assertNull(t); + return null; + }).apply(1,2)); + assertEquals("12", Wrap.biFunctionDef(cbif, "x").apply(1,2)); + + assertEquals("Either.Failure(org.jooq.lambda.WrapTest$Information: f2.1)", + Wrap.biFunction((a,b)->{throw new Information("f2.1");}).apply(1,2).toString()); + assertEquals("H", Wrap.biFunction((a,b)->{throw new Information("f2.2");}, (a,b,t)->{ + assertEquals(1, a); + assertEquals(2, b); + assertTrue(t instanceof Information); + return "H"; + }).apply(1,2)); + assertEquals("x", Wrap.biFunctionDef((a,b)->{throw new Information("f2.3");}, "x").apply(1,2)); + // + assertEquals("Either(9.1)", Wrap.doubleFunction((d)->""+d).apply(9.1).toString()); + assertEquals("9.1", Wrap.doubleFunction((d)->""+d, (d,t)->{ + assertEquals(9.1, d, 0.01); + assertNull(t); + return null; + }).apply(9.1)); + assertEquals("9.1", Wrap.doubleFunctionDef((d)->""+d, "x").apply(9.1)); + + assertEquals("Either.Failure(org.jooq.lambda.WrapTest$Information: f1.1)", + Wrap.doubleFunction((i)->{throw new Information("f1.1");}).apply(9.1).toString()); + assertEquals("H", Wrap.doubleFunction((d)->{throw new Information("f1.2");}, (d,t)->{ + assertEquals(9.1, d, 0.01); + assertTrue(t instanceof Information); + return "H"; + }).apply(9.1)); + assertEquals("x", Wrap.doubleFunctionDef((i)->{throw new Information("f1.3");}, "x").apply(9.1)); + + // intFunction + assertEquals("Either(9)", Wrap.intFunction((d)->""+d).apply(9).toString()); + assertEquals("9", Wrap.intFunction((d)->""+d, (d,t)->{ + assertEquals((Integer)9, d); + assertNull(t); + return null; + }).apply(9)); + assertEquals("9", Wrap.intFunctionDef((d)->""+d, "x").apply(9)); + + assertEquals("Either.Failure(org.jooq.lambda.WrapTest$Information: fI.1)", + Wrap.intFunction((i)->{throw new Information("fI.1");}).apply(9).toString()); + assertEquals("H", Wrap.intFunction((d)->{throw new Information("fI.2");}, (d,t)->{ + assertEquals((Integer)9, d); + assertTrue(t instanceof Information); + return "H"; + }).apply(9)); + assertEquals("x", Wrap.intFunctionDef((i)->{throw new Information("fI.3");}, "x").apply(9)); + + // longFunction + assertEquals("Either(9)", Wrap.longFunction((d)->""+d).apply(9L).toString()); + assertEquals("9", Wrap.longFunction((d)->""+d, (d,t)->{ + assertEquals((Long)9L, d); + assertNull(t); + return null; + }).apply(9L)); + assertEquals("9", Wrap.longFunctionDef((d)->""+d, "x").apply(9L)); + + assertEquals("Either.Failure(org.jooq.lambda.WrapTest$Information: fL.1)", + Wrap.longFunction((i)->{throw new Information("fL.1");}).apply(9L).toString()); + assertEquals("H", Wrap.longFunction((d)->{throw new Information("fL.2");}, (d,t)->{ + assertEquals((Long)9L, d); + assertTrue(t instanceof Information); + return "H"; + }).apply(9L)); + assertEquals("x", Wrap.longFunctionDef((i)->{throw new Information("fL.3");}, "x").apply(9L)); + } + + @Test public void testFunctions2 () { + assertEquals(9, Wrap.doubleToIntFunction((d)->(int)d, (d,t)->{ + assertEquals(9.1, d, 0.01); + assertNull(t); + return null; + }).applyAsInt(9.1)); + assertEquals(9, Wrap.doubleToIntFunctionDef((d)->(int)d, -1).applyAsInt(9.1)); + + assertEquals(-5, Wrap.doubleToIntFunction((d)-> 1/0, (d,t)->{ + assertEquals(9.1, d, 0.01); + assertTrue(t.toString(), t instanceof ArithmeticException); + return -5; + }).applyAsInt(9.1)); + assertEquals(-5, Wrap.doubleToIntFunctionDef((i)->{throw new Information("f1.3");}, -5).applyAsInt(9.1)); + // + assertEquals(9L, Wrap.doubleToLongFunction((d)->(int)d, (d,t)->{ + assertEquals(9.1, d, 0.01); + assertNull(t); + return null; + }).applyAsLong(9.1)); + assertEquals(9L, Wrap.doubleToLongFunctionDef((d)->(int)d, -1).applyAsLong(9.1)); + + assertEquals(-5L, Wrap.doubleToLongFunction((d)-> 1/0, (d,t)->{ + assertEquals(9.1, d, 0.01); + assertTrue(t.toString(), t instanceof ArithmeticException); + return -5L; + }).applyAsLong(9.1)); + assertEquals(-5L, Wrap.doubleToLongFunctionDef((i)->{throw new Information("f1.3");}, -5).applyAsLong(9.1)); + + // intToDoubleFunction + assertEquals(9.9, Wrap.intToDoubleFunction((d)->d*1.1, (d,t)->{ + assertEquals(9, d, 0.01); + assertNull(t); + return null; + }).applyAsDouble(9), 0.01); + assertEquals(9.9, Wrap.intToDoubleFunctionDef((d)->d*1.1,-1).applyAsDouble(9), 0.01); + + assertEquals(-5.1, Wrap.intToDoubleFunction((d)-> 1/0, (d,t)->{ + assertEquals((Integer)9, d); + assertTrue(t.toString(), t instanceof ArithmeticException); + return -5.1; + }).applyAsDouble(9), 0.01); + assertEquals(-5.1, Wrap.intToDoubleFunctionDef((i)->{throw new Information("f1.3");}, -5.1).applyAsDouble(9), 0.01); + + // intToLongFunction + assertEquals(90L, Wrap.intToLongFunction((d)->d*10L, (d,t)->{ + assertEquals((Integer)9, d); + assertNull(t); + return null; + }).applyAsLong(9)); + assertEquals(90L, Wrap.intToLongFunctionDef((d)->d*10L,-1L).applyAsLong(9)); + + assertEquals(-5L, Wrap.intToLongFunction((d)-> 1/0, (d,t)->{ + assertEquals((Integer)9, d); + assertTrue(t.toString(), t instanceof ArithmeticException); + return -5L; + }).applyAsLong(9)); + assertEquals(-5L, Wrap.intToLongFunctionDef((i)->{throw new Information("f1.3");}, -5L).applyAsLong(9)); + + // longToDoubleFunction + assertEquals(9.9, Wrap.longToDoubleFunction((d)->d*1.1, (d,t)->{ + assertEquals((Long)9L, d); + assertNull(t); + return -1.1; + }).applyAsDouble(9L), 0.01); + assertEquals(9.9, Wrap.longToDoubleFunctionDef((d)->d*1.1,-1.1).applyAsDouble(9L), 0.01); + + assertEquals(-5.1, Wrap.longToDoubleFunction((d)-> 1/0, (d,t)->{ + assertEquals((Long)9L, d); + assertTrue(t.toString(), t instanceof ArithmeticException); + return -5.1; + }).applyAsDouble(9L), 0.01); + assertEquals(-5.1, Wrap.longToDoubleFunctionDef((i)->1/0, -5.1).applyAsDouble(9L), 0.01); + + // longToIntFunction + assertEquals(8, Wrap.longToIntFunction((d)->(int)d-1, (d,t)->{ + assertEquals((Long)9L, d); + assertNull(t); + return -5; + }).applyAsInt(9L)); + assertEquals(8, Wrap.longToIntFunctionDef((d)->(int)d-1,-1).applyAsInt(9L)); + + assertEquals(-5, Wrap.longToIntFunction((d)-> 1/0, (d,t)->{ + assertEquals((Long)9L, d); + assertTrue(t.toString(), t instanceof ArithmeticException); + return -5; + }).applyAsInt(9L)); + assertEquals(-5, Wrap.longToIntFunctionDef((i)->divZero(), -5).applyAsInt(9L)); + } + + + @Test + public void testFunctionToPrimitive () { + // toDoubleBiFunction + CheckedToDoubleBiFunction cbif = (a,b)->a*1.1+b; + assertEquals(1.1+2, Wrap.toDoubleBiFunction(cbif, (a,b,t)->{ + assertEquals((Integer)1, a); + assertEquals((Integer)2, b); + assertNull(t); + return null; + }).applyAsDouble(1,2), 0.01); + assertEquals(1.1+2, Wrap.toDoubleBiFunctionDef(cbif, -9.1).applyAsDouble(1,2), 0.01); + + assertEquals(-5.7, Wrap.toDoubleBiFunction((Integer a, Integer b)->1/0, (a,b,t)->{ + assertEquals((Integer)1, a); + assertEquals((Integer)2, b); + assertTrue(t instanceof ArithmeticException); + return -5.7; + }).applyAsDouble(1,2), 0.01); + assertEquals(-1.5, Wrap.toDoubleBiFunctionDef((Integer a, Integer b)->{throw new Information("D");}, -1.5).applyAsDouble(1,2), 0.01); + + // toDoubleFunction + assertEquals(9.1, Wrap.toDoubleFunction(Double::parseDouble, (v,t)->{ + assertEquals("9.1", v); + assertNull(t); + return null; + }).applyAsDouble("9.1"), 0.01); + assertEquals(9.1, Wrap.toDoubleFunctionDef(Double::parseDouble, -9.1).applyAsDouble("9.1"), 0.01); + + assertEquals(-5.7, Wrap.toDoubleFunction((v)->(int)v, (v,t)->{ + assertEquals("9.1", v); + assertTrue(t.toString(), t instanceof ClassCastException); + return -5.7; + }).applyAsDouble("9.1"), 0.01); + assertEquals(-1.5, Wrap.toDoubleFunctionDef((v)->{throw new Information("D");}, -1.5).applyAsDouble("9.1"), 0.01); + + // toIntBiFunction + assertEquals(12, Wrap.toIntBiFunction((Long a, Long b)->(int)(a*10+b), (a,b,t)->{ + assertEquals((Long)1L, a); + assertEquals((Long)2L, b); + assertNull(t); + return null; + }).applyAsInt(1L,2L)); + assertEquals(12, Wrap.toIntBiFunctionDef((Long a, Long b)->(int)(a*10+b), -1).applyAsInt(1L,2L)); + + assertEquals(-5, Wrap.toIntBiFunction((Integer a, Long b)->1/0, (a,b,t)->{ + assertEquals((Integer)1, a); + assertEquals((Long)2L, b); + assertTrue(t instanceof ArithmeticException); + return -5; + }).applyAsInt(1,2L)); + assertEquals(-1, Wrap.toIntBiFunctionDef((Integer a, Long b)->{throw new Information("D");}, -1).applyAsInt(1,2L)); + + // toIntFunction + assertEquals(10, Wrap.toIntFunction((Long v)->(int)(v*10), (v,t)->{ + assertEquals((Long)1L, v); + assertNull(t); + return null; + }).applyAsInt(1L)); + assertEquals(10, Wrap.toIntFunctionDef((Long v)->(int)(v*10), -1).applyAsInt(1L)); + + assertEquals(-5, Wrap.toIntFunction((Integer v)->1/0, (v,t)->{ + assertEquals((Integer)1, v); + assertTrue(t instanceof ArithmeticException); + return -5; + }).applyAsInt(1)); + assertEquals(-1, Wrap.toIntFunctionDef((Integer a)->{throw new Information("D");}, -1).applyAsInt(1)); + + // toLongBiFunction + assertEquals(12L, Wrap.toLongBiFunction((Integer a, Byte b)->a*10L+b, (a,b,t)->{ + assertEquals((Integer)1, a); + assertEquals((byte)2, b.byteValue()); + assertNull(t); + return null; + }).applyAsLong(1,(byte)2)); + assertEquals(12L, Wrap.toLongBiFunctionDef((Integer a, Short b)->a*10L+b, -1).applyAsLong(1,(short)2)); + + assertEquals(-5L, Wrap.toLongBiFunction((Double a, Long b)->1/0, (a,b,t)->{ + assertEquals(1.1, a, 0.01); + assertEquals((Long)2L, b); + assertTrue(t instanceof ArithmeticException); + return -5L; + }).applyAsLong(1.1,2L)); + assertEquals(-1L, Wrap.toLongBiFunctionDef((Integer a, Long b)->{throw new Information("D");}, -1L).applyAsLong(1,2L)); + + // toLongFunction + assertEquals(10L, Wrap.toLongFunction(Double::longValue, (v,t)->{ + assertEquals(10.1, v, 0.01); + assertNull(t); + return null; + }).applyAsLong(10.1)); + assertEquals(10L, Wrap.toLongFunctionDef((Integer v)->v*10L, -1).applyAsLong(1)); + + assertEquals(-5L, Wrap.toLongFunction((Integer v)->1/0, (v,t)->{ + assertEquals((Integer)1, v); + assertTrue(t instanceof ArithmeticException); + return -5L; + }).applyAsLong(1)); + assertEquals(-1L, Wrap.toLongFunctionDef((Integer a)->{throw new Information("D");}, -1L).applyAsLong(1)); + + } + + + static T divZero () { + return Wrap.castUnsafe(1/0); + } +} \ No newline at end of file diff --git a/jOOL/src/test/java/org/jooq/lambda/function/GenericPredicateTest.java b/jOOL/src/test/java/org/jooq/lambda/function/GenericPredicateTest.java new file mode 100644 index 00000000..6181939b --- /dev/null +++ b/jOOL/src/test/java/org/jooq/lambda/function/GenericPredicateTest.java @@ -0,0 +1,650 @@ +package org.jooq.lambda.function; + +import org.jooq.lambda.Loops; +import org.jooq.lambda.Wrap; +import org.jooq.lambda.tuple.Tuple; +import org.jooq.lambda.tuple.Tuple0; +import org.jooq.lambda.tuple.Tuple1; +import org.jooq.lambda.tuple.Tuple10; +import org.jooq.lambda.tuple.Tuple11; +import org.jooq.lambda.tuple.Tuple12; +import org.jooq.lambda.tuple.Tuple13; +import org.jooq.lambda.tuple.Tuple14; +import org.jooq.lambda.tuple.Tuple15; +import org.jooq.lambda.tuple.Tuple16; +import org.jooq.lambda.tuple.Tuple2; +import org.jooq.lambda.tuple.Tuple3; +import org.jooq.lambda.tuple.Tuple4; +import org.jooq.lambda.tuple.Tuple5; +import org.jooq.lambda.tuple.Tuple6; +import org.jooq.lambda.tuple.Tuple7; +import org.jooq.lambda.tuple.Tuple8; +import org.jooq.lambda.tuple.Tuple9; +import org.junit.Test; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Proxy; + +import static org.junit.Assert.*; + +public class GenericPredicateTest { + + @Test public void dynamic () throws ClassNotFoundException { + assertTrue(GenericPredicate.testDynamicPredicateVarArgs((Predicate0)()->true, null)); + assertFalse(GenericPredicate.testDynamicPredicateVarArgs((Predicate0)()->false)); + + assertTrue(GenericPredicate.testDynamicArgCntToPredicate((Predicate0)()->true, null)); + assertFalse(GenericPredicate.testDynamicArgCntToPredicate((Predicate0)()->false)); + + for (int i=0; i<=16; i++) { + final int len = i; + String ifaceClassName = "org.jooq.lambda.function.Predicate"+i; + Class ifaceClass = Wrap.castUnsafe(Class.forName(ifaceClassName)); + GenericPredicate p = (GenericPredicate) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), + new Class[]{ifaceClass}, (proxy, method, args) -> { + assertEquals("test", method.getName()); + + if (len == 0) { + assertNull(args); + } else { + assertEquals(len, args.length); + for (int j = 0; j < len; j++) { + assertEquals(j + 11, args[j]); + } + } + return len % 2 == 0; + }); + + Object[] args = new Integer[len]; + for (int j=0; j true; + + assertTrue(p.test()); + assertTrue(p.test(new Tuple0())); + assertTrue(p.get()); + assertTrue(p.call()); + assertTrue(p.apply()); + assertSame(p, p.toSupplier()); + + p = Predicate0.from(()->false); + assertFalse(p.call()); + } + + + static boolean logic (Integer... a) { + int prev = 1; + for (int i : a) { + assertTrue("prev < i: "+prev+" ? "+i, prev < i); + prev = i; + } + return a.length % 2 == 0; + } + + @SuppressWarnings("unchecked") + static T tuple (int size) { + try { + final Class cls = Class.forName("org.jooq.lambda.tuple.Tuple" + size); + + final Object[] args = new Object[size]; + Loops.forLoop(size, (i) -> {args[i] = i + 10;}); + + for (Constructor ctor : cls.getConstructors()) { + if (ctor.getParameterCount() == size) { + + return (T) ctor.newInstance(args); + } + } + } catch (Exception e) { + throw new IllegalStateException("Can't create Tuple"+size, e); + } + throw new IllegalArgumentException("Wrong size="+size+". Can't create Tuple"+size); + } + + @Test public void testPredicate1 () { + Predicate1 p = Predicate1.from(GenericPredicateTest::logic); + assertSame(p, p.toPredicate()); + assertFalse(p.test(10));// arg.len==1→false + assertFalse(p.applyPartially(10).test()); + Tuple1 tuple = tuple(1); + assertFalse(p.test(tuple)); + assertFalse(p.toFunction().apply(tuple)); + assertFalse(p.applyPartially(tuple).test()); + + p = Predicate1.fromFunction((i)->true); + assertTrue(p.test(0)); + } + + + @Test public void testLogic1 () { + Predicate16 p = GenericPredicateTest::logic; + + assertTrue(p.test(10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25)); + } + @Test(expected = AssertionError.class) + public void testLogic2 () { + Predicate16 p = GenericPredicateTest::logic; + assertTrue(p.test(10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25)); + + p.test(0,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25); + fail("unreachable: ^^^ 0 < 1"); + } + @Test(expected = AssertionError.class) + public void testLogic3 () { + Predicate16 p = GenericPredicateTest::logic; + assertTrue(p.test(10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25)); + + p.test(10,11,12,13,14,15,16,17,18,19,20, 22,21, 23,24,25); + fail("unreachable: ^^^ AssertionError: prev < i: 22 ? 21"); + } + + + @Test public void testPredicate2 () { + Predicate2 p = Predicate2.from(GenericPredicateTest::logic); + assertSame(p, p.toBiPredicate()); + assertTrue(p.test(10,11)); + assertTrue(p.applyPartially(10).test(11)); + assertTrue(p.applyPartially(10, 11).test()); + + Tuple2 tuple = tuple(2); + assertTrue(p.test(tuple)); + assertTrue(p.toFunction().apply(tuple)); + assertTrue(p.applyPartially(tuple).test()); + + Tuple1 tuple1 = tuple(1); + assertTrue(p.applyPartially(tuple1).test(11)); + + p = Predicate2.fromFunction((a,b)->false); + assertFalse(p.test(10,11)); + } + + + @Test public void testPredicate3 () { + Predicate3 p = GenericPredicateTest::logic; + Tuple3 tuple = tuple(3); + // 3 % 2 != 0 + assertFalse(p.toFunction().apply(tuple)); + assertFalse(p.test(tuple)); + assertFalse(p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertFalse(p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertFalse(p.applyPartially(tuple.limit3()).test(tuple.skip3())); + + + assertFalse(p.test(10,11,12)); + assertFalse(p.applyPartially(10).test(11,12)); + assertFalse(p.applyPartially(10, 11).test(12)); + assertFalse(p.applyPartially(10, 11, 12).test()); + } + + @Test public void testPredicate4 () { + Predicate4 p = GenericPredicateTest::logic; + Tuple4 tuple = tuple(4); + boolean pv = tuple.degree() % 2 == 0; + + assertEquals(pv, p.toFunction().apply(tuple)); + assertEquals(pv, p.test(tuple)); + assertEquals(pv, p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertEquals(pv, p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertEquals(pv, p.applyPartially(tuple.limit3()).test(tuple.skip3())); + assertEquals(pv, p.applyPartially(tuple.limit4()).test(tuple.skip4())); + + assertEquals(pv, p.test(10,11,12,13)); + assertEquals(pv, p.applyPartially(10).test(11,12,13)); + assertEquals(pv, p.applyPartially(10,11).test(12,13)); + assertEquals(pv, p.applyPartially(10,11,12).test(13)); + assertEquals(pv, p.applyPartially(10,11,12,13).test()); + } + + @Test public void testPredicate5 () { + Predicate5 p = GenericPredicateTest::logic; + Tuple5 tuple = tuple(5); + boolean pv = tuple.degree() % 2 == 0; + + assertEquals(pv, p.toFunction().apply(tuple)); + assertEquals(pv, p.test(tuple)); + assertEquals(pv, p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertEquals(pv, p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertEquals(pv, p.applyPartially(tuple.limit3()).test(tuple.skip3())); + assertEquals(pv, p.applyPartially(tuple.limit4()).test(tuple.skip4())); + assertEquals(pv, p.applyPartially(tuple.limit5()).test(tuple.skip5())); + + assertEquals(pv, p.test(10,11,12,13,14)); + assertEquals(pv, p.applyPartially(10).test(11,12,13,14)); + assertEquals(pv, p.applyPartially(10,11).test(12,13,14)); + assertEquals(pv, p.applyPartially(10,11,12).test(13,14)); + assertEquals(pv, p.applyPartially(10,11,12,13).test(14)); + assertEquals(pv, p.applyPartially(10,11,12,13,14).test()); + } + + @Test public void testPredicate6 () { + Predicate6 p = GenericPredicateTest::logic; + Tuple6 tuple = tuple(6); + boolean pv = tuple.degree() % 2 == 0; + + assertEquals(pv, p.toFunction().apply(tuple)); + assertEquals(pv, p.test(tuple)); + assertEquals(pv, p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertEquals(pv, p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertEquals(pv, p.applyPartially(tuple.limit3()).test(tuple.skip3())); + assertEquals(pv, p.applyPartially(tuple.limit4()).test(tuple.skip4())); + assertEquals(pv, p.applyPartially(tuple.limit5()).test(tuple.skip5())); + assertEquals(pv, p.applyPartially(tuple.limit6()).test(tuple.skip6())); + + assertEquals(pv, p.test(10,11,12,13,14,15)); + assertEquals(pv, p.applyPartially(10).test(11,12,13,14,15)); + assertEquals(pv, p.applyPartially(10,11).test(12,13,14,15)); + assertEquals(pv, p.applyPartially(10,11,12).test(13,14,15)); + assertEquals(pv, p.applyPartially(10,11,12,13).test(14,15)); + assertEquals(pv, p.applyPartially(10,11,12,13,14).test(15)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15).test()); + } + + @Test public void testPredicate7 () { + Predicate7 p = GenericPredicateTest::logic; + Tuple7 tuple = tuple(7); + boolean pv = tuple.degree() % 2 == 0; + + assertEquals(pv, p.toFunction().apply(tuple)); + assertEquals(pv, p.test(tuple)); + assertEquals(pv, p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertEquals(pv, p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertEquals(pv, p.applyPartially(tuple.limit3()).test(tuple.skip3())); + assertEquals(pv, p.applyPartially(tuple.limit4()).test(tuple.skip4())); + assertEquals(pv, p.applyPartially(tuple.limit5()).test(tuple.skip5())); + assertEquals(pv, p.applyPartially(tuple.limit6()).test(tuple.skip6())); + assertEquals(pv, p.applyPartially(tuple.limit7()).test(tuple.skip7())); + + assertEquals(pv, p.test(10,11,12,13,14,15,16)); + assertEquals(pv, p.applyPartially(10).test(11,12,13,14,15,16)); + assertEquals(pv, p.applyPartially(10,11).test(12,13,14,15,16)); + assertEquals(pv, p.applyPartially(10,11,12).test(13,14,15,16)); + assertEquals(pv, p.applyPartially(10,11,12,13).test(14,15,16)); + assertEquals(pv, p.applyPartially(10,11,12,13,14).test(15,16)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15).test(16)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16).test()); + } + + @Test public void testPredicate8 () { + Predicate8 p = GenericPredicateTest::logic; + Tuple8 tuple = tuple(8); + boolean pv = tuple.degree() % 2 == 0; + + assertEquals(pv, p.toFunction().apply(tuple)); + assertEquals(pv, p.test(tuple)); + assertEquals(pv, p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertEquals(pv, p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertEquals(pv, p.applyPartially(tuple.limit3()).test(tuple.skip3())); + assertEquals(pv, p.applyPartially(tuple.limit4()).test(tuple.skip4())); + assertEquals(pv, p.applyPartially(tuple.limit5()).test(tuple.skip5())); + assertEquals(pv, p.applyPartially(tuple.limit6()).test(tuple.skip6())); + assertEquals(pv, p.applyPartially(tuple.limit7()).test(tuple.skip7())); + assertEquals(pv, p.applyPartially(tuple.limit8()).test(tuple.skip8())); + + assertEquals(pv, p.test(10,11,12,13,14,15,16,17)); + assertEquals(pv, p.applyPartially(10).test(11,12,13,14,15,16,17)); + assertEquals(pv, p.applyPartially(10,11).test(12,13,14,15,16,17)); + assertEquals(pv, p.applyPartially(10,11,12).test(13,14,15,16,17)); + assertEquals(pv, p.applyPartially(10,11,12,13).test(14,15,16,17)); + assertEquals(pv, p.applyPartially(10,11,12,13,14).test(15,16,17)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15).test(16,17)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16).test(17)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17).test()); + } + + @Test public void testPredicate9 () { + Predicate9 p = GenericPredicateTest::logic; + Tuple9 tuple = tuple(9); + boolean pv = tuple.degree() % 2 == 0; + + assertEquals(pv, p.toFunction().apply(tuple)); + assertEquals(pv, p.test(tuple)); + assertEquals(pv, p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertEquals(pv, p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertEquals(pv, p.applyPartially(tuple.limit3()).test(tuple.skip3())); + assertEquals(pv, p.applyPartially(tuple.limit4()).test(tuple.skip4())); + assertEquals(pv, p.applyPartially(tuple.limit5()).test(tuple.skip5())); + assertEquals(pv, p.applyPartially(tuple.limit6()).test(tuple.skip6())); + assertEquals(pv, p.applyPartially(tuple.limit7()).test(tuple.skip7())); + assertEquals(pv, p.applyPartially(tuple.limit8()).test(tuple.skip8())); + assertEquals(pv, p.applyPartially(tuple.limit9()).test(tuple.skip9())); + + assertEquals(pv, p.test(10,11,12,13,14,15,16,17,18)); + assertEquals(pv, p.applyPartially(10).test(11,12,13,14,15,16,17,18)); + assertEquals(pv, p.applyPartially(10,11).test(12,13,14,15,16,17,18)); + assertEquals(pv, p.applyPartially(10,11,12).test(13,14,15,16,17,18)); + assertEquals(pv, p.applyPartially(10,11,12,13).test(14,15,16,17,18)); + assertEquals(pv, p.applyPartially(10,11,12,13,14).test(15,16,17,18)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15).test(16,17,18)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16).test(17,18)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17).test(18)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18).test()); + } + + @Test public void testPredicate10 () { + Predicate10 p = GenericPredicateTest::logic; + Tuple10 tuple = tuple(10); + boolean pv = tuple.degree() % 2 == 0; + + assertEquals(pv, p.toFunction().apply(tuple)); + assertEquals(pv, p.test(tuple)); + assertEquals(pv, p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertEquals(pv, p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertEquals(pv, p.applyPartially(tuple.limit3()).test(tuple.skip3())); + assertEquals(pv, p.applyPartially(tuple.limit4()).test(tuple.skip4())); + assertEquals(pv, p.applyPartially(tuple.limit5()).test(tuple.skip5())); + assertEquals(pv, p.applyPartially(tuple.limit6()).test(tuple.skip6())); + assertEquals(pv, p.applyPartially(tuple.limit7()).test(tuple.skip7())); + assertEquals(pv, p.applyPartially(tuple.limit8()).test(tuple.skip8())); + assertEquals(pv, p.applyPartially(tuple.limit9()).test(tuple.skip9())); + assertEquals(pv, p.applyPartially(tuple.limit10()).test(tuple.skip10())); + + assertEquals(pv, p.test(10,11,12,13,14,15,16,17,18,19)); + assertEquals(pv, p.applyPartially(10).test(11,12,13,14,15,16,17,18,19)); + assertEquals(pv, p.applyPartially(10,11).test(12,13,14,15,16,17,18,19)); + assertEquals(pv, p.applyPartially(10,11,12).test(13,14,15,16,17,18,19)); + assertEquals(pv, p.applyPartially(10,11,12,13).test(14,15,16,17,18,19)); + assertEquals(pv, p.applyPartially(10,11,12,13,14).test(15,16,17,18,19)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15).test(16,17,18,19)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16).test(17,18,19)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17).test(18,19)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18).test(19)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19).test()); + } + + @Test public void testPredicate11 () { + Predicate11 p = GenericPredicateTest::logic; + Tuple11 tuple = tuple(11); + boolean pv = tuple.degree() % 2 == 0; + + assertEquals(pv, p.toFunction().apply(tuple)); + assertEquals(pv, p.test(tuple)); + assertEquals(pv, p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertEquals(pv, p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertEquals(pv, p.applyPartially(tuple.limit3()).test(tuple.skip3())); + assertEquals(pv, p.applyPartially(tuple.limit4()).test(tuple.skip4())); + assertEquals(pv, p.applyPartially(tuple.limit5()).test(tuple.skip5())); + assertEquals(pv, p.applyPartially(tuple.limit6()).test(tuple.skip6())); + assertEquals(pv, p.applyPartially(tuple.limit7()).test(tuple.skip7())); + assertEquals(pv, p.applyPartially(tuple.limit8()).test(tuple.skip8())); + assertEquals(pv, p.applyPartially(tuple.limit9()).test(tuple.skip9())); + assertEquals(pv, p.applyPartially(tuple.limit10()).test(tuple.skip10())); + assertEquals(pv, p.applyPartially(tuple.limit11()).test(tuple.skip11())); + + assertEquals(pv, p.test(10,11,12,13,14,15,16,17,18,19,20)); + assertEquals(pv, p.applyPartially(10).test(11,12,13,14,15,16,17,18,19,20)); + assertEquals(pv, p.applyPartially(10,11).test(12,13,14,15,16,17,18,19,20)); + assertEquals(pv, p.applyPartially(10,11,12).test(13,14,15,16,17,18,19,20)); + assertEquals(pv, p.applyPartially(10,11,12,13).test(14,15,16,17,18,19,20)); + assertEquals(pv, p.applyPartially(10,11,12,13,14).test(15,16,17,18,19,20)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15).test(16,17,18,19,20)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16).test(17,18,19,20)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17).test(18,19,20)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18).test(19,20)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19).test(20)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20).test()); + } + + @Test public void testPredicate12 () { + Predicate12 p = GenericPredicateTest::logic; + Tuple12 tuple = tuple(12); + boolean pv = tuple.degree() % 2 == 0; + + assertEquals(pv, p.toFunction().apply(tuple)); + assertEquals(pv, p.test(tuple)); + assertEquals(pv, p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertEquals(pv, p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertEquals(pv, p.applyPartially(tuple.limit3()).test(tuple.skip3())); + assertEquals(pv, p.applyPartially(tuple.limit4()).test(tuple.skip4())); + assertEquals(pv, p.applyPartially(tuple.limit5()).test(tuple.skip5())); + assertEquals(pv, p.applyPartially(tuple.limit6()).test(tuple.skip6())); + assertEquals(pv, p.applyPartially(tuple.limit7()).test(tuple.skip7())); + assertEquals(pv, p.applyPartially(tuple.limit8()).test(tuple.skip8())); + assertEquals(pv, p.applyPartially(tuple.limit9()).test(tuple.skip9())); + assertEquals(pv, p.applyPartially(tuple.limit10()).test(tuple.skip10())); + assertEquals(pv, p.applyPartially(tuple.limit11()).test(tuple.skip11())); + assertEquals(pv, p.applyPartially(tuple.limit12()).test(tuple.skip12())); + + assertEquals(pv, p.test(10,11,12,13,14,15,16,17,18,19,20,21)); + assertEquals(pv, p.applyPartially(10).test(11,12,13,14,15,16,17,18,19,20,21)); + assertEquals(pv, p.applyPartially(10,11).test(12,13,14,15,16,17,18,19,20,21)); + assertEquals(pv, p.applyPartially(10,11,12).test(13,14,15,16,17,18,19,20,21)); + assertEquals(pv, p.applyPartially(10,11,12,13).test(14,15,16,17,18,19,20,21)); + assertEquals(pv, p.applyPartially(10,11,12,13,14).test(15,16,17,18,19,20,21)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15).test(16,17,18,19,20,21)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16).test(17,18,19,20,21)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17).test(18,19,20,21)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18).test(19,20,21)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19).test(20,21)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20).test(21)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21).test()); + } + + @Test public void testPredicate13 () { + Predicate13 + p = GenericPredicateTest::logic; + Tuple13 + tuple = tuple(13); + boolean pv = tuple.degree() % 2 == 0; + + assertEquals(pv, p.toFunction().apply(tuple)); + assertEquals(pv, p.test(tuple)); + assertEquals(pv, p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertEquals(pv, p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertEquals(pv, p.applyPartially(tuple.limit3()).test(tuple.skip3())); + assertEquals(pv, p.applyPartially(tuple.limit4()).test(tuple.skip4())); + assertEquals(pv, p.applyPartially(tuple.limit5()).test(tuple.skip5())); + assertEquals(pv, p.applyPartially(tuple.limit6()).test(tuple.skip6())); + assertEquals(pv, p.applyPartially(tuple.limit7()).test(tuple.skip7())); + assertEquals(pv, p.applyPartially(tuple.limit8()).test(tuple.skip8())); + assertEquals(pv, p.applyPartially(tuple.limit9()).test(tuple.skip9())); + assertEquals(pv, p.applyPartially(tuple.limit10()).test(tuple.skip10())); + assertEquals(pv, p.applyPartially(tuple.limit11()).test(tuple.skip11())); + assertEquals(pv, p.applyPartially(tuple.limit12()).test(tuple.skip12())); + assertEquals(pv, p.applyPartially(tuple.limit13()).test(tuple.skip13())); + + assertEquals(pv, p.test(10,11,12,13,14,15,16,17,18,19,20,21,22)); + assertEquals(pv, p.applyPartially(10).test(11,12,13,14,15,16,17,18,19,20,21,22)); + assertEquals(pv, p.applyPartially(10,11).test(12,13,14,15,16,17,18,19,20,21,22)); + assertEquals(pv, p.applyPartially(10,11,12).test(13,14,15,16,17,18,19,20,21,22)); + assertEquals(pv, p.applyPartially(10,11,12,13).test(14,15,16,17,18,19,20,21,22)); + assertEquals(pv, p.applyPartially(10,11,12,13,14).test(15,16,17,18,19,20,21,22)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15).test(16,17,18,19,20,21,22)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16).test(17,18,19,20,21,22)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17).test(18,19,20,21,22)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18).test(19,20,21,22)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19).test(20,21,22)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20).test(21,22)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21).test(22)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21,22).test()); + } + + @Test public void testPredicate14 () { + Predicate14 + p = GenericPredicateTest::logic; + Tuple14 + tuple = tuple(14); + boolean pv = tuple.degree() % 2 == 0; + + assertEquals(pv, p.toFunction().apply(tuple)); + assertEquals(pv, p.test(tuple)); + assertEquals(pv, p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertEquals(pv, p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertEquals(pv, p.applyPartially(tuple.limit3()).test(tuple.skip3())); + assertEquals(pv, p.applyPartially(tuple.limit4()).test(tuple.skip4())); + assertEquals(pv, p.applyPartially(tuple.limit5()).test(tuple.skip5())); + assertEquals(pv, p.applyPartially(tuple.limit6()).test(tuple.skip6())); + assertEquals(pv, p.applyPartially(tuple.limit7()).test(tuple.skip7())); + assertEquals(pv, p.applyPartially(tuple.limit8()).test(tuple.skip8())); + assertEquals(pv, p.applyPartially(tuple.limit9()).test(tuple.skip9())); + assertEquals(pv, p.applyPartially(tuple.limit10()).test(tuple.skip10())); + assertEquals(pv, p.applyPartially(tuple.limit11()).test(tuple.skip11())); + assertEquals(pv, p.applyPartially(tuple.limit12()).test(tuple.skip12())); + assertEquals(pv, p.applyPartially(tuple.limit13()).test(tuple.skip13())); + assertEquals(pv, p.applyPartially(tuple.limit14()).test(tuple.skip14())); + + assertEquals(pv, p.test(10,11,12,13,14,15,16,17,18,19,20,21,22,23)); + assertEquals(pv, p.applyPartially(10).test(11,12,13,14,15,16,17,18,19,20,21,22,23)); + assertEquals(pv, p.applyPartially(10,11).test(12,13,14,15,16,17,18,19,20,21,22,23)); + assertEquals(pv, p.applyPartially(10,11,12).test(13,14,15,16,17,18,19,20,21,22,23)); + assertEquals(pv, p.applyPartially(10,11,12,13).test(14,15,16,17,18,19,20,21,22,23)); + assertEquals(pv, p.applyPartially(10,11,12,13,14).test(15,16,17,18,19,20,21,22,23)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15).test(16,17,18,19,20,21,22,23)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16).test(17,18,19,20,21,22,23)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17).test(18,19,20,21,22,23)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18).test(19,20,21,22,23)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19).test(20,21,22,23)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20).test(21,22,23)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21).test(22,23)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21,22).test(23)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21,22,23).test()); + } + + @Test public void testPredicate15 () { + Predicate15 p = GenericPredicateTest::logic; + Tuple15 tuple = tuple(15); + boolean pv = tuple.degree() % 2 == 0; + + assertEquals(pv, p.toFunction().apply(tuple)); + assertEquals(pv, p.test(tuple)); + assertEquals(pv, p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertEquals(pv, p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertEquals(pv, p.applyPartially(tuple.limit3()).test(tuple.skip3())); + assertEquals(pv, p.applyPartially(tuple.limit4()).test(tuple.skip4())); + assertEquals(pv, p.applyPartially(tuple.limit5()).test(tuple.skip5())); + assertEquals(pv, p.applyPartially(tuple.limit6()).test(tuple.skip6())); + assertEquals(pv, p.applyPartially(tuple.limit7()).test(tuple.skip7())); + assertEquals(pv, p.applyPartially(tuple.limit8()).test(tuple.skip8())); + assertEquals(pv, p.applyPartially(tuple.limit9()).test(tuple.skip9())); + assertEquals(pv, p.applyPartially(tuple.limit10()).test(tuple.skip10())); + assertEquals(pv, p.applyPartially(tuple.limit11()).test(tuple.skip11())); + assertEquals(pv, p.applyPartially(tuple.limit12()).test(tuple.skip12())); + assertEquals(pv, p.applyPartially(tuple.limit13()).test(tuple.skip13())); + assertEquals(pv, p.applyPartially(tuple.limit14()).test(tuple.skip14())); + assertEquals(pv, p.applyPartially(tuple.limit15()).test(tuple.skip15())); + + assertEquals(pv, p.test(10,11,12,13,14,15,16,17,18,19,20,21,22,23,24)); + assertEquals(pv, p.applyPartially(10).test(11,12,13,14,15,16,17,18,19,20,21,22,23,24)); + assertEquals(pv, p.applyPartially(10,11).test(12,13,14,15,16,17,18,19,20,21,22,23,24)); + assertEquals(pv, p.applyPartially(10,11,12).test(13,14,15,16,17,18,19,20,21,22,23,24)); + assertEquals(pv, p.applyPartially(10,11,12,13).test(14,15,16,17,18,19,20,21,22,23,24)); + assertEquals(pv, p.applyPartially(10,11,12,13,14).test(15,16,17,18,19,20,21,22,23,24)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15).test(16,17,18,19,20,21,22,23,24)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16).test(17,18,19,20,21,22,23,24)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17).test(18,19,20,21,22,23,24)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18).test(19,20,21,22,23,24)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19).test(20,21,22,23,24)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20).test(21,22,23,24)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21).test(22,23,24)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21,22).test(23,24)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21,22,23).test(24)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21,22,23,24).test()); + } + + @Test public void testPredicate16 () { + Predicate16 p = GenericPredicateTest::logic; + Tuple16 tuple = tuple(16); + boolean pv = tuple.degree() % 2 == 0; + + assertEquals(pv, p.toFunction().apply(tuple)); + assertEquals(pv, p.test(tuple)); + assertEquals(pv, p.applyPartially(tuple.limit1()).test(tuple.skip1())); + assertEquals(pv, p.applyPartially(tuple.limit2()).test(tuple.skip2())); + assertEquals(pv, p.applyPartially(tuple.limit3()).test(tuple.skip3())); + assertEquals(pv, p.applyPartially(tuple.limit4()).test(tuple.skip4())); + assertEquals(pv, p.applyPartially(tuple.limit5()).test(tuple.skip5())); + assertEquals(pv, p.applyPartially(tuple.limit6()).test(tuple.skip6())); + assertEquals(pv, p.applyPartially(tuple.limit7()).test(tuple.skip7())); + assertEquals(pv, p.applyPartially(tuple.limit8()).test(tuple.skip8())); + assertEquals(pv, p.applyPartially(tuple.limit9()).test(tuple.skip9())); + assertEquals(pv, p.applyPartially(tuple.limit10()).test(tuple.skip10())); + assertEquals(pv, p.applyPartially(tuple.limit11()).test(tuple.skip11())); + assertEquals(pv, p.applyPartially(tuple.limit12()).test(tuple.skip12())); + assertEquals(pv, p.applyPartially(tuple.limit13()).test(tuple.skip13())); + assertEquals(pv, p.applyPartially(tuple.limit14()).test(tuple.skip14())); + assertEquals(pv, p.applyPartially(tuple.limit15()).test(tuple.skip15())); + assertEquals(pv, p.applyPartially(tuple.limit16()).test(tuple.skip16())); + + assertEquals(pv, p.test(10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25)); + assertEquals(pv, p.applyPartially(10).test(11,12,13,14,15,16,17,18,19,20,21,22,23,24,25)); + assertEquals(pv, p.applyPartially(10,11).test(12,13,14,15,16,17,18,19,20,21,22,23,24,25)); + assertEquals(pv, p.applyPartially(10,11,12).test(13,14,15,16,17,18,19,20,21,22,23,24,25)); + assertEquals(pv, p.applyPartially(10,11,12,13).test(14,15,16,17,18,19,20,21,22,23,24,25)); + assertEquals(pv, p.applyPartially(10,11,12,13,14).test(15,16,17,18,19,20,21,22,23,24,25)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15).test(16,17,18,19,20,21,22,23,24,25)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16).test(17,18,19,20,21,22,23,24,25)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17).test(18,19,20,21,22,23,24,25)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18).test(19,20,21,22,23,24,25)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19).test(20,21,22,23,24,25)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20).test(21,22,23,24,25)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21).test(22,23,24,25)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21,22).test(23,24,25)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21,22,23).test(24,25)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21,22,23,24).test(25)); + assertEquals(pv, p.applyPartially(10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25).test()); + } +} \ No newline at end of file