♻️ Add matcher for linked elements
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Fri, 2 Sep 2022 15:14:06 +0000 (17:14 +0200)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Fri, 2 Sep 2022 15:58:36 +0000 (17:58 +0200)
src/test/kotlin/net/pterodactylus/sone/core/DefaultElementLoaderTest.kt
src/test/kotlin/net/pterodactylus/sone/test/Matchers.kt

index a3c6af0..1b03d7a 100644 (file)
@@ -4,9 +4,14 @@ import com.google.common.base.Ticker
 import freenet.keys.FreenetURI
 import net.pterodactylus.sone.core.FreenetInterface.BackgroundFetchCallback
 import net.pterodactylus.sone.test.*
+import org.hamcrest.Description
+import org.hamcrest.Matcher
 import org.hamcrest.MatcherAssert.assertThat
+import org.hamcrest.Matchers.allOf
 import org.hamcrest.Matchers.contains
 import org.hamcrest.Matchers.equalTo
+import org.hamcrest.Matchers.hasEntry
+import org.hamcrest.TypeSafeDiagnosingMatcher
 import org.junit.Rule
 import org.junit.Test
 import java.io.ByteArrayOutputStream
@@ -88,11 +93,9 @@ class DefaultElementLoaderTest {
                runWithCallback(decomposedKey) { elementLoader, _, callback, _ ->
                        callback.loaded(FreenetURI(normalizedKey), "image/png", read("/static/images/unknown-image-0.png"))
                        val linkedElement = elementLoader.loadElement(decomposedKey)
-                       mapOf(
-                               "type" to "image",
-                               "size" to 2451,
-                               "sizeHuman" to "2 KiB"
-                       ).also { assertThat(linkedElement, equalTo(LinkedElement(normalizedKey, properties = it))) }
+                       assertThat(linkedElement, isLinkedElement(equalTo(normalizedKey), allOf(
+                               hasEntry("type", "image"), hasEntry("size", 2451), hasEntry("sizeHuman", "2 KiB"),
+                       )))
                }
        }
 
@@ -101,13 +104,11 @@ class DefaultElementLoaderTest {
                runWithCallback(textKey) { elementLoader, _, callback, _ ->
                        callback.loaded(FreenetURI(textKey), "text/html; charset=UTF-8", read("element-loader.html"))
                        val linkedElement = elementLoader.loadElement(textKey)
-                       mapOf(
-                               "type" to "html",
-                               "size" to 266,
-                               "sizeHuman" to "266 B",
-                               "title" to "Some Nice Page Title",
-                               "description" to "This is an example of a very nice freesite."
-                       ).also { assertThat(linkedElement, equalTo(LinkedElement(textKey, properties = it))) }
+                       assertThat(linkedElement, isLinkedElement(equalTo(textKey), allOf(
+                               hasEntry("type", "html"), hasEntry("size", 266), hasEntry("sizeHuman", "266 B"),
+                               hasEntry("title", "Some Nice Page Title"),
+                               hasEntry("description", "This is an example of a very nice freesite.")
+                       )))
                }
        }
 
@@ -116,13 +117,11 @@ class DefaultElementLoaderTest {
                runWithCallback(textKey) { elementLoader, _, callback, _ ->
                        callback.loaded(FreenetURI(textKey), "text/html; charset=UTF-8", read("element-loader2.html"))
                        val linkedElement = elementLoader.loadElement(textKey)
-                       mapOf(
-                               "type" to "html",
-                               "size" to 185,
-                               "sizeHuman" to "185 B",
-                               "title" to "Some Nice Page Title",
-                               "description" to "This is the first paragraph of the very nice freesite."
-                       ).also { assertThat(linkedElement, equalTo(LinkedElement(textKey, properties = it))) }
+                       assertThat(linkedElement, isLinkedElement(equalTo(textKey), allOf(
+                               hasEntry("type", "html"), hasEntry("size", 185), hasEntry("sizeHuman", "185 B"),
+                               hasEntry("title", "Some Nice Page Title"),
+                               hasEntry("description", "This is the first paragraph of the very nice freesite.")
+                       )))
                }
        }
 
@@ -131,13 +130,11 @@ class DefaultElementLoaderTest {
                runWithCallback(textKey) { elementLoader, _, callback, _ ->
                        callback.loaded(FreenetURI(textKey), "text/html; charset=UTF-8", read("element-loader3.html"))
                        val linkedElement = elementLoader.loadElement(textKey)
-                       mapOf(
-                               "type" to "html",
-                               "size" to 204,
-                               "sizeHuman" to "204 B",
-                               "title" to "Some Nice Page Title",
-                               "description" to null
-                       ).also { assertThat(linkedElement, equalTo(LinkedElement(textKey, properties = it))) }
+                       assertThat(linkedElement, isLinkedElement(equalTo(textKey), allOf(
+                               hasEntry("type", "html"), hasEntry("size", 204), hasEntry("sizeHuman", "204 B"),
+                               hasEntry("title", "Some Nice Page Title"),
+                               hasEntry("description", null)
+                       )))
                }
        }
 
@@ -146,13 +143,10 @@ class DefaultElementLoaderTest {
                runWithCallback(textKey) { elementLoader, _, callback, _ ->
                        callback.loaded(FreenetURI(textKey), "text/html; charset=UTF-8", read("element-loader4.html"))
                        val linkedElement = elementLoader.loadElement(textKey)
-                       mapOf(
-                               "type" to "html",
-                               "size" to 229,
-                               "sizeHuman" to "229 B",
-                               "title" to null,
-                               "description" to "This is an example of a very nice freesite."
-                       ).also { assertThat(linkedElement, equalTo(LinkedElement(textKey, properties = it))) }
+                       assertThat(linkedElement, isLinkedElement(equalTo(textKey), allOf(
+                               hasEntry("type", "html"), hasEntry("size", 229), hasEntry("sizeHuman", "229 B"), hasEntry("title", null),
+                               hasEntry("description", "This is an example of a very nice freesite.")
+                       )))
                }
        }
 
@@ -214,6 +208,21 @@ private fun createTicker(vararg times: Long = LongArray(1) { 1 }) = object : Tic
                        .also { counter++ }
 }
 
+private fun isLinkedElement(link: Matcher<String> = everything(), properties: Matcher<Map<String, Any?>> = everything(), failed: Matcher<Boolean> = everything(), loading: Matcher<Boolean> = everything()) = object : TypeSafeDiagnosingMatcher<LinkedElement>() {
+       override fun matchesSafely(item: LinkedElement, mismatchDescription: Description) =
+               handleMatcher(link, item.link, mismatchDescription) &&
+                               handleMatcher(properties, item.properties, mismatchDescription) &&
+                               handleMatcher(failed, item.failed, mismatchDescription) &&
+                               handleMatcher(loading, item.loading, mismatchDescription)
+
+       override fun describeTo(description: Description) {
+               description.appendText("is linked element for key matching ").appendValue(link)
+                       .appendText(", properties matching ").appendValue(properties)
+                       .appendText(", failed matching ").appendValue(failed)
+                       .appendText(", loading matching ").appendValue(loading)
+       }
+}
+
 private const val IMAGE_ID = "KSK@gpl.png"
 private val freenetURI = FreenetURI(IMAGE_ID)
 private const val decomposedKey = "CHK@DCiVgTWW9nnWHJc9EVwtFJ6jAfBSVyy~rgiPvhUKbS4,mNY85V0x7dYcv7SnEYo1PCC6y2wNWMDNt-y9UWQx9fI,AAMC--8/fru%CC%88hstu%CC%88ck.jpg"
index ecb2049..9d21557 100644 (file)
@@ -9,6 +9,12 @@ import org.hamcrest.*
 import org.hamcrest.Matchers.*
 
 /**
+ * A kotlin-ified version of Hamcrest’s [anything()][anything]. It matches
+ * everything and has the right type, too!
+ */
+inline fun <reified T> everything(): Matcher<T> = any(T::class.java)
+
+/**
  * Returns a [hamcrest matcher][Matcher] constructed from the given predicate.
  */
 fun <T> matches(description: String? = null, predicate: (T) -> Boolean) = object : TypeSafeDiagnosingMatcher<T>() {
@@ -38,6 +44,10 @@ fun hasHeader(name: String, value: String) = object : TypeSafeDiagnosingMatcher<
        }
 }
 
+fun <T> handleMatcher(matcher: Matcher<T>, item: T, mismatchDescription: Description) =
+       matcher.matches(item)
+               .onFalse { matcher.describeMismatch(item, mismatchDescription) }
+
 fun <T : Any> compare(value: T, comparison: (T) -> Boolean, onError: (T) -> Unit) =
                false.takeUnless { comparison(value) }
                                ?.also { onError(value) }
@@ -96,9 +106,7 @@ fun isOwnIdentity(id: String, nickname: String, requestUri: String, insertUri: S
 
 fun hasField(name: String, valueMatcher: Matcher<String>) = object : TypeSafeDiagnosingMatcher<SimpleFieldSet>() {
        override fun matchesSafely(item: SimpleFieldSet, mismatchDescription: Description) =
-                       valueMatcher.matches(item.get(name)).onFalse {
-                               valueMatcher.describeMismatch(item, mismatchDescription)
-                       }
+               handleMatcher(valueMatcher, item.get(name), mismatchDescription)
 
        override fun describeTo(description: Description) {
                description