diff --git a/src/main/java/org/takes/facets/hamcrest/AbstractHmBody.java b/src/main/java/org/takes/facets/hamcrest/AbstractHmBody.java new file mode 100644 index 000000000..15414e37c --- /dev/null +++ b/src/main/java/org/takes/facets/hamcrest/AbstractHmBody.java @@ -0,0 +1,120 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014-2018 Yegor Bugayenko + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.takes.facets.hamcrest; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import org.hamcrest.Description; +import org.hamcrest.TypeSafeMatcher; + +/** + * Body Matcher. + * + *

This "matcher" tests given item body

+ * + * @author Tolegen Izbassar (t.izbassar@gmail.com) + * @version $Id$ + * @param Item type. Should be able to return own item + * @since 2.0 + * + * @todo #485:30min Right now we can only check that InputStream + * have the same content as other InputStream. This is very + * limited usage. Task is to introduce `HmTextBody` that will + * make available to us to use useful string matchers from + * hamcrest. The usage will be like that: + * ``` + * MatcherAssert.assertThat( + * response, + * new HmRsTextBody<>(Matchers.startsWith("")) + * ); + * ``` + * The default constructor should use `Matcher.containsString` + * as default matcher, which is used for matching string to body. + * Current implementation of `AbstractHmBody` should be converted + * to `HmBytesBody` that will check equality of bytes. We can think + * of improving that class lately. + * + * @todo #485:30min Right now the describeTo doesn't properly + * show the reason behind mismatch. It should show expected + * bytes and actual bytes for better clarification for + * end user. Also describeMismatchSafely should be implemented. + */ +abstract class AbstractHmBody extends TypeSafeMatcher { + + /** + * Body. + */ + private final InputStream body; + + /** + * Ctor. + * @param value Value to test against. + */ + protected AbstractHmBody(final InputStream value) { + super(); + this.body = value; + } + + @Override + public final void describeTo(final Description description) { + description.appendText("item: ") + .appendValue(this.body); + } + + @Override + protected final boolean matchesSafely(final T item) { + boolean result = true; + try ( + final InputStream val = new BufferedInputStream(this.itemBody(item)) + ) { + int left = this.body.read(); + while (left != -1) { + final int right = val.read(); + if (left != right) { + result = false; + break; + } + left = this.body.read(); + } + final int right = val.read(); + if (result) { + result = right == -1; + } + } catch (final IOException ex) { + throw new IllegalStateException(ex); + } + return result; + } + + /** + * Item's body. + * @param item Item to retrieve body from + * @return InputStream of body + * @throws IOException If some problem inside + */ + protected abstract InputStream itemBody(final T item) throws IOException; +} + diff --git a/src/main/java/org/takes/facets/hamcrest/HmRqBody.java b/src/main/java/org/takes/facets/hamcrest/HmRqBody.java new file mode 100644 index 000000000..ebed33ca5 --- /dev/null +++ b/src/main/java/org/takes/facets/hamcrest/HmRqBody.java @@ -0,0 +1,84 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014-2018 Yegor Bugayenko + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.takes.facets.hamcrest; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.Charset; +import org.takes.Request; + +/** + * Request Body Matcher. + * + *

This "matcher" tests given request body. + * + * @author Tolegen Izbassar (t.izbassar@gmail.com) + * @version $Id$ + * @since 2.0 + */ +public final class HmRqBody extends AbstractHmBody { + + /** + * Ctor. + * + *

Will create instance with defaultCharset. + * @param value Value to test against + */ + public HmRqBody(final String value) { + this(value, Charset.defaultCharset()); + } + + /** + * Ctor. + * @param value Value to test against + * @param charset Charset of given value + */ + public HmRqBody(final String value, final Charset charset) { + this(value.getBytes(charset)); + } + + /** + * Ctor. + * @param value Value to test against + */ + public HmRqBody(final byte[] value) { + this(new ByteArrayInputStream(value)); + } + + /** + * Ctor. + * @param value Value to test against + */ + public HmRqBody(final InputStream value) { + super(value); + } + + @Override + public InputStream itemBody(final Request item) throws IOException { + return item.body(); + } +} + diff --git a/src/main/java/org/takes/facets/hamcrest/HmRsBody.java b/src/main/java/org/takes/facets/hamcrest/HmRsBody.java new file mode 100644 index 000000000..753978240 --- /dev/null +++ b/src/main/java/org/takes/facets/hamcrest/HmRsBody.java @@ -0,0 +1,84 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014-2018 Yegor Bugayenko + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.takes.facets.hamcrest; + + import java.io.ByteArrayInputStream; + import java.io.IOException; + import java.io.InputStream; + import java.nio.charset.Charset; + import org.takes.Response; + +/** + * Response Body Matcher. + * + *

This "matcher" tests given response body. + * + * @author Tolegen Izbassar (t.izbassar@gmail.com) + * @version $Id$ + * @since 2.0 + */ +public final class HmRsBody extends AbstractHmBody { + + /** + * Ctor. + * + *

Will create instance with defaultCharset. + * @param value Value to test against + */ + public HmRsBody(final String value) { + this(value, Charset.defaultCharset()); + } + + /** + * Ctor. + * @param value Value to test against + * @param charset Charset of given value + */ + public HmRsBody(final String value, final Charset charset) { + this(value.getBytes(charset)); + } + + /** + * Ctor. + * @param value Value to test against + */ + public HmRsBody(final byte[] value) { + this(new ByteArrayInputStream(value)); + } + + /** + * Ctor. + * @param value Value to test against + */ + public HmRsBody(final InputStream value) { + super(value); + } + + @Override + public InputStream itemBody(final Response item) throws IOException { + return item.body(); + } +} + diff --git a/src/test/java/org/takes/facets/hamcrest/HmRqBodyTest.java b/src/test/java/org/takes/facets/hamcrest/HmRqBodyTest.java new file mode 100644 index 000000000..805b79af9 --- /dev/null +++ b/src/test/java/org/takes/facets/hamcrest/HmRqBodyTest.java @@ -0,0 +1,71 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014-2018 Yegor Bugayenko + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.takes.facets.hamcrest; + +import java.util.Collections; +import org.hamcrest.MatcherAssert; +import org.hamcrest.Matchers; +import org.junit.Test; +import org.takes.rq.RqFake; + +/** + * Test case for {@link HmRqBody}. + * + * @author Tolegen Izbassar (t.izbassar@gmail.com) + * @version $Id$ + * @since 2.0 + */ +public final class HmRqBodyTest { + + /** + * HmRqBody can test if values of bodies are same. + */ + @Test + public void testsBodyValuesAreSame() { + final String body = "Same"; + MatcherAssert.assertThat( + new RqFake( + Collections.emptyList(), + body + ), + new HmRqBody(body) + ); + } + + /** + * HmRqBody can test if values of bodies are different. + */ + @Test + public void testsBodyValuesAreDifferent() { + MatcherAssert.assertThat( + new RqFake( + Collections.emptyList(), + "this" + ), + Matchers.not(new HmRqBody("that")) + ); + } +} + diff --git a/src/test/java/org/takes/facets/hamcrest/HmRsBodyTest.java b/src/test/java/org/takes/facets/hamcrest/HmRsBodyTest.java new file mode 100644 index 000000000..99877eddb --- /dev/null +++ b/src/test/java/org/takes/facets/hamcrest/HmRsBodyTest.java @@ -0,0 +1,71 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014-2018 Yegor Bugayenko + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.takes.facets.hamcrest; + +import java.util.Collections; +import org.hamcrest.MatcherAssert; +import org.hamcrest.Matchers; +import org.junit.Test; +import org.takes.rs.RsSimple; + +/** + * Test case for {@link HmRsBody}. + * + * @author Tolegen Izbassar (t.izbassar@gmail.com) + * @version $Id$ + * @since 2.0 + */ +public final class HmRsBodyTest { + + /** + * HmRsBody can test if values of bodies are same. + */ + @Test + public void bodyValuesAreSame() { + final String body = "Same"; + MatcherAssert.assertThat( + new RsSimple( + Collections.emptyList(), + body + ), + new HmRsBody(body) + ); + } + + /** + * HmRsBody can test if values of bodies are different. + */ + @Test + public void bodyValuesAreDifferent() { + MatcherAssert.assertThat( + new RsSimple( + Collections.emptyList(), + "this" + ), + Matchers.not(new HmRsBody("that")) + ); + } +} +