Fehler in Predicates Implementierung?

Hi,

habe mal einen JUnit-Test für die Predicates Implementierung geschrieben, da mir diese etwas spooky vorkam.

Und sie schlägt fehl.


import org.junit.Ignore;
import org.junit.Test;
import static org.junit.Assert.assertThat;
import static org.hamcrest.CoreMatchers.*;
import static org.fjorum.util.Predicates.and;
import static org.fjorum.util.Predicates.or;

public class TestPredicates {

  @Test
  public void testAnd() {
    assertThat("an empty and", and().test(new Object()), is(true));

    assertThat("and true", and((x -> true)).test(new Object()), is(true));
    assertThat("and false", and((x -> false)).test(new Object()), is(false));

    assertThat("true and true", and((x -> true), (x -> true)).test(new Object()), is(true));
    assertThat("true and false", and((x -> true), (x -> false)).test(new Object()), is(false));
    assertThat("false and true", and((x -> false), (x -> true)).test(new Object()), is(false));
    assertThat("false and false", and((x -> false), (x -> false)).test(new Object()), is(false));
  }

  @Test
  public void testOr() {
    assertThat("empty or", or().test(new Object()), is(false));

    assertThat("or true", or((x -> true)).test(new Object()), is(true));
    assertThat("or false", or((x -> false)).test(new Object()), is(false));

    assertThat("true or true", or((x -> true), (x -> true)).test(new Object()), is(true));
    assertThat("true or false", or((x -> true), (x -> false)).test(new Object()), is(true));
    assertThat("false or true", or((x -> false), (x -> true)).test(new Object()), is(true));
    assertThat("false or false", or((x -> false), (x -> false)).test(new Object()), is(false));
  }

}```

Bei and kommt immer true raus und bei or immer false.

[SPOILER]-------------------------------------------------------------------------------
Test set: org.fjorum.util.TestPredicates
-------------------------------------------------------------------------------
Tests run: 2, Failures: 2, Errors: 0, Skipped: 0, Time elapsed: 0.154 sec <<< FAILURE!
testAnd(org.fjorum.util.TestPredicates)  Time elapsed: 0.075 sec  <<< FAILURE!
java.lang.AssertionError: and false
Expected: is <false>
     but: was <true>
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
	at org.junit.Assert.assertThat(Assert.java:865)
	at org.fjorum.util.TestPredicates.testAnd(TestPredicates.java:17)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
	at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53)
	at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123)
	at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
	at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
	at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175)
	at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:107)
	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68)
testOr(org.fjorum.util.TestPredicates)  Time elapsed: 0 sec  <<< FAILURE!
java.lang.AssertionError: or true
Expected: is <true>
     but: was <false>
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
	at org.junit.Assert.assertThat(Assert.java:865)
	at org.fjorum.util.TestPredicates.testOr(TestPredicates.java:29)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
	at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53)
	at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123)
	at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
	at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
	at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175)
	at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:107)
	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68)[/SPOILER]


Mein Verdacht

```result = result.map(r -> r.or(predicate));```

result ist Anfangs Optional.empty(). Daher steht in der Funktion mehr oder weniger
null.or(predicate) laienhaft ausgedrückt. (Vielleicht sollte ich ja mal ne IDE anwerfen)

Um das ganze zu Fixen schlage ich vor
bei or

—Optional<Predicate> result = Optional.empty();
+++Optional<Predicate
> result = Optional.of( a -> false);


bei and

—Optional<Predicate> result = Optional.empty();
+++Optional<Predicate
> result = Optional.of( a -> true);


Damit läuft auch der bereitgestellte Test.

Btw. würde ich noch anregen dem anderen Test "ApiControllerDocTesterTest.java" eine Annotation @org.junit.Ignore zu verpassen, da dieser fehlschlägt.

Stimmt, da wollte ich zu clever sein. Ist gefixt.

Kann ich deinen Test im Projekt verwenden?

Ja natürlich. Ist ja schließlich Code, den schreibt man ja damit er ausgeführt wird.