package io.github.pyranja.hamcrest;

import org.hamcrest.FeatureMatcher;
import org.hamcrest.Matcher;
import org.junit.Test;

import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;

/**
 * Define and test expected behavior of {@link FeatureMatcher}, as required by jaxrs matcher
 * implementations.
 */
public class FeatureMatcherTest {

  @Test
  public void shouldRejectIfExpectationNotMet() throws Exception {
    final FeatureMatcher<?, ?> subject = new FakeIntegerFeatureMatcher(Hamcrest.contradiction());
    assertThat(subject.matches(new Object()), equalTo(false));
  }

  @Test
  public void shouldMatchIfExpectationIsMet() throws Exception {
    final FeatureMatcher<?, ?> subject = new FakeIntegerFeatureMatcher(Hamcrest.tautology());
    assertThat(subject.matches(new Object()), equalTo(true));
  }

  @Test
  public void shouldRejectNullInput() throws Exception {
    final FeatureMatcher<?, ?> subject = new FakeIntegerFeatureMatcher(Hamcrest.tautology());
    assertThat(subject.matches(null), equalTo(false));
  }

  @Test
  public void shouldRejectInputOnTypeMismatch() throws Exception {
    // auto type detection only works on 'real' sub-classes, where the method signature of
    // featureValueOf has a concrete return type, not a generic one
    final FeatureMatcher<Integer, Integer> subject =
      new FeatureMatcher<Integer, Integer>(Hamcrest.<Integer>tautology(), "test", "test") {
        @Override
        protected Integer featureValueOf(final Integer actual) {
          return Integer.MIN_VALUE;
        }
      };
    assertThat(subject.matches(Long.MAX_VALUE), equalTo(false));
  }

  private static class FakeIntegerFeatureMatcher extends FeatureMatcher<Integer, Integer> {
    public FakeIntegerFeatureMatcher(final Matcher<? super Integer> subMatcher) {
      super(subMatcher, "test feature", "test");
    }

    @Override
    protected Integer featureValueOf(final Integer actual) {
      return Integer.MIN_VALUE;
    }
  }
}

@@ -115,24 +115,83 @@
 unit.Test;%0A%0A
+import static io.github.pyranja.hamcrest.Hamcrest.isFalse;%0A
 import stati
@@ -214,23 +214,19 @@
 atchers.
-equalTo
+not
 ;%0Aimport
@@ -502,74 +502,50 @@
     
-final FeatureMatcher%3C?, ?%3E subject = new FakeIntegerFeatureM
+assertThat(Integer.MIN_VALUE, not(m
 atch
-er
+ing
 (Ham
@@ -570,69 +570,8 @@
 n())
-;%0A    assertThat(subject.matches(new Object()), equalTo(false
 ));%0A
@@ -656,74 +656,46 @@
     
-final FeatureMatcher%3C?, ?%3E subject = new FakeIntegerFeatureM
+assertThat(Integer.MIN_VALUE, m
 atch
-er
+ing
 (Ham
@@ -716,69 +716,8 @@
 y())
-;%0A    assertThat(subject.matches(new Object()), equalTo(true)
 );%0A 
@@ -793,74 +793,37 @@
     
-final FeatureMatcher%3C?, ?%3E subject = new FakeIntegerFeatureM
+assertThat(null, not(m
 atch
-er
+ing
 (Ham
@@ -844,61 +844,8 @@
 y())
-;%0A    assertThat(subject.matches(null), equalTo(false
 ));%0A
@@ -932,258 +932,27 @@
     
-// auto type detection only works on 'real' sub-classes, where the method signature of%0A    // featureValueOf has a concrete return type, not a generic one%0A    final FeatureMatcher%3CInteger, Integer%3E subject =%0A      new FeatureMatcher%3CInteger, Integer%3E
+assertThat(matching
 (Ham
@@ -961,17 +961,8 @@
 est.
-%3CInteger%3E
 taut
@@ -972,117 +972,136 @@
 gy()
-, %22test%22, %22test%22) %7B%0A        @Override%0A        protected 
+).matches(Long.MAX_VALUE), isFalse());%0A  %7D%0A%0A  private Fake
 Integer
- f
+F
 eature
-ValueOf(final Integer actual
+Matcher matching(final Matcher%3CObject%3E contradiction
 ) %7B%0A
-      
     
@@ -1111,108 +1111,51 @@
 urn 
-Integer.MIN_VALUE;%0A        %7D%0A      %7D;%0A    assertThat(subject.matches(Long.MAX_VALUE), equalTo(false)
+new FakeIntegerFeatureMatcher(contradiction
 );%0A 

Use subject matchers in assertions