package net.ttddyy.dsproxy.test.hamcrest;

import net.ttddyy.dsproxy.QueryType;
import net.ttddyy.dsproxy.listener.QueryUtils;
import net.ttddyy.dsproxy.test.QueryHolder;
import org.hamcrest.Description;
import org.hamcrest.FeatureMatcher;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;

/**
 * @author Tadaya Tsuyukubo
 * @since 1.4
 */
public class QueryHolderAssertions {

    public static Matcher<? super QueryHolder> query(final Matcher<String> stringMatcher) {
        return new FeatureMatcher<QueryHolder, String>(stringMatcher, "query", "query") {
            @Override
            protected String featureValueOf(QueryHolder actual) {
                return actual.getQuery();
            }
        };
    }

    public static Matcher<? super QueryHolder> queryType(final QueryType expectedType) {

        return new TypeSafeMatcher<QueryHolder>() {
            @Override
            protected boolean matchesSafely(QueryHolder item) {
                String query = item.getQuery();
                QueryType actualType = QueryUtils.getQueryType(query);
                if (expectedType != actualType) {
                    return false;
                }
                return true;
            }

            @Override
            public void describeTo(Description description) {
                // expected clause
                description.appendText("query type \"" + expectedType + "\"");
            }

            @Override
            protected void describeMismatchSafely(QueryHolder item, Description mismatchDescription) {
                // but was clause
                String query = item.getQuery();
                QueryType actualType = QueryUtils.getQueryType(query);

                String msg = "query type was \"" + actualType + "\" (" + query + ")";
                mismatchDescription.appendText(msg);
            }
        };
    }

    public static Matcher<? super QueryHolder> select() {
        return queryType(QueryType.SELECT);
    }

    public static Matcher<? super QueryHolder> insert() {
        return queryType(QueryType.INSERT);
    }

    public static Matcher<? super QueryHolder> update() {
        return queryType(QueryType.UPDATE);
    }

    public static Matcher<? super QueryHolder> delete() {
        return queryType(QueryType.DELETE);
    }

    public static Matcher<? super QueryHolder> other() {
        return queryType(QueryType.OTHER);
    }

}

@@ -304,16 +304,65 @@
 r;%0A%0A/**%0A
+ * Hamcrest matchers for %7B@link QueryHolder%7D.%0A *%0A
  * @auth
@@ -433,24 +433,199 @@
 sertions %7B%0A%0A
+    /**%0A     * Matcher to examine the query with given %7B@link String%7D matcher.%0A     *%0A     * Example:%0A     * %3Cpre%3E assertThat(qe, query(startsWith(%22select%22))); %3C/pre%3E%0A     */%0A
     public s
@@ -948,32 +948,168 @@
       %7D;%0A    %7D%0A%0A
+    /**%0A     * Matcher to examine the query type.%0A     *%0A     * Example:%0A     * %3Cpre%3E assertThat(qe, queryType(SELECT)); %3C/pre%3E%0A     */%0A
     public stati
@@ -2256,439 +2256,1123 @@
     
-public static Matcher%3C? super QueryHolder%3E select() %7B%0A        return queryType(QueryType.SELECT);%0A    %7D%0A%0A    public static Matcher%3C? super QueryHolder%3E insert() %7B%0A        return queryType(QueryType.INSERT);%0A    %7D%0A%0A    public static Matcher%3C? super QueryHolder%3E update() %7B%0A        return queryType(QueryType.UPDATE);%0A    %7D%0A%0A    public static Matcher%3C? super QueryHolder%3E delete() %7B%0A        return queryType(QueryType.DELETE);%0A    %7D%0A
+/**%0A     * Matcher to examine the query type is SELECT.%0A     *%0A     * Example:%0A     * %3Cpre%3E assertThat(qe, select()); %3C/pre%3E%0A     */%0A    public static Matcher%3C? super QueryHolder%3E select() %7B%0A        return queryType(QueryType.SELECT);%0A    %7D%0A%0A    /**%0A     * Matcher to examine the query type is SELECT.%0A     *%0A     * Example:%0A     * %3Cpre%3E assertThat(qe, insert()); %3C/pre%3E%0A     */%0A    public static Matcher%3C? super QueryHolder%3E insert() %7B%0A        return queryType(QueryType.INSERT);%0A    %7D%0A%0A    /**%0A     * Matcher to examine the query type is SELECT.%0A     *%0A     * Example:%0A     * %3Cpre%3E assertThat(qe, update()); %3C/pre%3E%0A     */%0A    public static Matcher%3C? super QueryHolder%3E update() %7B%0A        return queryType(QueryType.UPDATE);%0A    %7D%0A%0A    /**%0A     * Matcher to examine the query type is SELECT.%0A     *%0A     * Example:%0A     * %3Cpre%3E assertThat(qe, delete()); %3C/pre%3E%0A     */%0A    public static Matcher%3C? super QueryHolder%3E delete() %7B%0A        return queryType(QueryType.DELETE);%0A    %7D%0A%0A    /**%0A     * Matcher to examine the query type is SELECT.%0A     *%0A     * Example:%0A     * %3Cpre%3E assertThat(qe, other()); %3C/pre%3E%0A     */
 %0A   

document QueryHolderAssertions