// Path: ersatz/src/main/java/io/github/cjstehno/ersatz/match/ErsatzMatchers.java
// public interface ErsatzMatchers {
// 
//     /**
//      * Matcher that matches a request path. A wildcard (*) may be used to match any request path.
//      *
//      * @param path the path to be matched or * for wildcard
//      * @return the matcher
//      */
//     static Matcher<String> pathMatcher(final String path) {
//         return path.equals("*") ? Matchers.any(String.class) : equalTo(path);
//     }
// 
//     /**
//      * Matcher that matches if the object is an Iterable of Strings whose elements match (in any order) the provided
//      * matchers.
//      *
//      * @param matchers the element matchers
//      * @return the wrapping matcher
//      */
//     static Matcher<Iterable<? super String>> stringIterableMatcher(final Collection<Matcher<? super String>> matchers) {
//         return new StringIterableMatcher(matchers);
//     }
// 
//     /**
//      * The provided value must be a byte array with the same length and same first and last element values.
//      *
//      * @param array the array
//      * @return the resulting matcher
//      */
//     static Matcher<byte[]> byteArrayLike(final byte[] array) {
//         return new ByteArrayMatcher(array);
//     }
// 
//     /**
//      * The provided function is used to verify the match, wrapped in a Matcher.
//      *
//      * @param fun the function being wrapped (a true response implies a match)
//      * @param <T> the type of object(s) being matched
//      * @return the function wrapped in a matcher
//      */
//     static <T> Matcher<T> functionMatcher(final Function<T, Boolean> fun) {
//         return new FunctionMatcher<>(fun);
//     }
// }
// 
// Path: ersatz/src/main/java/io/github/cjstehno/ersatz/match/ErsatzMatchers.java
// static Matcher<byte[]> byteArrayLike(final byte[] array) {
//     return new ByteArrayMatcher(array);
// }
// 
// Path: ersatz/src/main/java/io/github/cjstehno/ersatz/match/ErsatzMatchers.java
// static Matcher<String> pathMatcher(final String path) {
//     return path.equals("*") ? Matchers.any(String.class) : equalTo(path);
// }


import io.github.cjstehno.ersatz.match.ErsatzMatchers;
import lombok.val;
import org.hamcrest.StringDescription;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import java.util.List;
import static io.github.cjstehno.ersatz.match.ErsatzMatchers.byteArrayLike;
import static io.github.cjstehno.ersatz.match.ErsatzMatchers.pathMatcher;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.jupiter.api.Assertions.*;
        "some bytes,other bytes,false"
    })
    void alikeByteArray(final String pattern, final String value, final boolean matches){
        assertEquals(matches, byteArrayLike(pattern.getBytes(UTF_8)).matches(value.getBytes(UTF_8)));
    }

    @Test @DisplayName("byte array matcher description")
    void byteArrayMatcherDescription(){
        val matcher = byteArrayLike("stuff".getBytes(UTF_8));

        val desc = new StringDescription();
        matcher.describeTo(desc);
        assertEquals("A byte array of length 5 having 115 as the first element and 102 as the last.", desc.toString());
    }

    @Test @DisplayName("function matcher")
    void functionMatcher(){
        val matcher = ErsatzMatchers.functionMatcher(x -> x instanceof String);

        assertTrue(matcher.matches("a string"));
        assertFalse(matcher.matches(new Object()));

        val desc = new StringDescription();
        matcher.describeTo(desc);
        assertEquals("A function that checks for matching.", desc.toString());
    }

    @Test @DisplayName("string iterable matcher")
    void stringIterableMatcher(){
        val matcher = ErsatzMatchers.stringIterableMatcher(List.of(
// Path: ersatz/src/main/java/io/github/cjstehno/ersatz/match/ErsatzMatchers.java
// public interface ErsatzMatchers {
// 
//     /**
//      * Matcher that matches a request path. A wildcard (*) may be used to match any request path.
//      *
//      * @param path the path to be matched or * for wildcard
//      * @return the matcher
//      */
//     static Matcher<String> pathMatcher(final String path) {
//         return path.equals("*") ? Matchers.any(String.class) : equalTo(path);
//     }
// 
//     /**
//      * Matcher that matches if the object is an Iterable of Strings whose elements match (in any order) the provided
//      * matchers.
//      *
//      * @param matchers the element matchers
//      * @return the wrapping matcher
//      */
//     static Matcher<Iterable<? super String>> stringIterableMatcher(final Collection<Matcher<? super String>> matchers) {
//         return new StringIterableMatcher(matchers);
//     }
// 
//     /**
//      * The provided value must be a byte array with the same length and same first and last element values.
//      *
//      * @param array the array
//      * @return the resulting matcher
//      */
//     static Matcher<byte[]> byteArrayLike(final byte[] array) {
//         return new ByteArrayMatcher(array);
//     }
// 
//     /**
//      * The provided function is used to verify the match, wrapped in a Matcher.
//      *
//      * @param fun the function being wrapped (a true response implies a match)
//      * @param <T> the type of object(s) being matched
//      * @return the function wrapped in a matcher
//      */
//     static <T> Matcher<T> functionMatcher(final Function<T, Boolean> fun) {
//         return new FunctionMatcher<>(fun);
//     }
// }
// 
// Path: ersatz/src/main/java/io/github/cjstehno/ersatz/match/ErsatzMatchers.java
// static Matcher<byte[]> byteArrayLike(final byte[] array) {
//     return new ByteArrayMatcher(array);
// }
// 
// Path: ersatz/src/main/java/io/github/cjstehno/ersatz/match/ErsatzMatchers.java
// static Matcher<String> pathMatcher(final String path) {
//     return path.equals("*") ? Matchers.any(String.class) : equalTo(path);
// }


// Path: ersatz/src/test/java/io/github/cjstehno/ersatz/match/ErsatzMatchersTest.java
import io.github.cjstehno.ersatz.match.ErsatzMatchers;
import lombok.val;
import org.hamcrest.StringDescription;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import java.util.List;
import static io.github.cjstehno.ersatz.match.ErsatzMatchers.byteArrayLike;
import static io.github.cjstehno.ersatz.match.ErsatzMatchers.pathMatcher;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.jupiter.api.Assertions.*;

        "some bytes,other bytes,false"
    })
    void alikeByteArray(final String pattern, final String value, final boolean matches){
        assertEquals(matches, byteArrayLike(pattern.getBytes(UTF_8)).matches(value.getBytes(UTF_8)));
    }

    @Test @DisplayName("byte array matcher description")
    void byteArrayMatcherDescription(){
        val matcher = byteArrayLike("stuff".getBytes(UTF_8));

        val desc = new StringDescription();
        matcher.describeTo(desc);
        assertEquals("A byte array of length 5 having 115 as the first element and 102 as the last.", desc.toString());
    }

    @Test @DisplayName("function matcher")
    void functionMatcher(){
        val matcher = ErsatzMatchers.functionMatcher(x -> x instanceof String);

        assertTrue(matcher.matches("a string"));
        assertFalse(matcher.matches(new Object()));

        val desc = new StringDescription();
        matcher.describeTo(desc);
        assertEquals("A function that checks for matching.", desc.toString());
    }

    @Test @DisplayName("string iterable matcher")
    void stringIterableMatcher(){
        val matcher = ErsatzMatchers.stringIterableMatcher(List.of(
            startsWith("prefix-"),