package io.github.pyranja.hamcrest.jaxrs;

import org.hamcrest.StringDescription;
import org.junit.Test;
import org.junit.experimental.theories.DataPoints;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.runner.RunWith;

import javax.ws.rs.core.Response;
import java.util.Objects;

import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertThat;
import static org.junit.Assume.assumeThat;

@RunWith(Theories.class)
public class ResponseStatusMatcherTest {

  @DataPoints
  public static final Response.Status[] statuses = Response.Status.values();

  private final StringDescription description = new StringDescription();

  @Test(expected = NullPointerException.class)
  public void shouldFailFastOnNullReference() throws Exception {
    subjectExpecting(null);
  }

  @Theory
  public void shouldIncludeExpectedReasonAndCodeInDescription(final Response.Status status) throws Exception {
    subjectExpecting(status).describeTo(description);
    assertThat(description.toString(), containsString(status.toString()));
    assertThat(description.toString(), containsString(Objects.toString(status.getStatusCode())));
  }

  @Theory
  public void shouldMatchIfResponseHasExpectedStatus(final Response.Status status) throws Exception {
    assertThat(subjectExpecting(status).matches(MockResponse.with(status)), equalTo(true));
  }

  @Theory
  public void shouldRejectResponseWithUnexpectedStatus(final Response.Status status, final Response.Status other) throws Exception {
    assumeThat(status, not(equalTo(other)));
    assertThat(subjectExpecting(status).matches(MockResponse.with(other)), equalTo(false));
  }

  @Theory
  public void shouldIncludeFoundReasonAndCodeInMismatchDescription(final Response.Status status, final Response.Status other) throws Exception {
    assumeThat(status, not(equalTo(other)));
    subjectExpecting(status).describeMismatch(MockResponse.with(other), description);
    assertThat(description.toString(), containsString(other.toString()));
    assertThat(description.toString(), containsString(Objects.toString(other.getStatusCode())));
  }

  private ResponseStatusMatcher subjectExpecting(final Response.Status expected) {
    return new ResponseStatusMatcher(expected);
  }

}

@@ -102,59 +102,8 @@
 st;%0A
-import org.junit.experimental.theories.DataPoints;%0A
 impo
@@ -147,16 +147,16 @@
 eories;%0A
+
 import o
@@ -486,174 +486,8 @@
  %7B%0A%0A
-  @DataPoints%0A  public static final Response.Status%5B%5D statuses = Response.Status.values();%0A%0A  private final StringDescription description = new StringDescription();%0A%0A
   @T
@@ -740,32 +740,99 @@
 ows Exception %7B%0A
+    final StringDescription description = new StringDescription();%0A
     subjectExpec
@@ -1737,24 +1737,91 @@
 o(other)));%0A
+    final StringDescription description = new StringDescription();%0A
     subjectE
@@ -2201,15 +2201,14 @@
 ected);%0A
+
   %7D%0A
-%0A
 %7D%0A

Remove superfluous data point and inline description field