Repository: willowtreeapps/assertk
Pull request #502 (2023-11-29 21:10:15)

add map assertion doesNotContainKey
Just adding a convenience assertion `Map::doesNotContainKey`. While existing assertions on `Map` can achieve the same functionality, having to pass an arbitrary value in addition to the key to be checked is overhead this PR endeavors to eliminate.

jzbrooks: In the same way that `isNull` is a terminal assertion while `isNotNull` is both an assertion and transformation, `doesNotContainKey` is a terminal assertion while `key` is an assertion and transformation.
JakeWharton: I would not expect this to be a terminal operation. It operates on the contents of the map which does not preclude additional assertions on it.
nukeforum: > ... which does not preclude additional assertions on it.

@JakeWharton 
Isn't that what the `.all {}` extension is for? I'm actually pretty new to assertK, so I could use some context to understand your feedback. 🙏  
JakeWharton: Sorry yeah you're right. I've been working on a different testing library in Rust and it's been screwing up my knowledge of AssertK now multiple times today 🤦‍♂️
evant: yeah, https://github.com/willowtreeapps/assertk/discussions/346

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a212c64..1688dcc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
 
 ## [Unreleased]
+- Added `doesNotContainKey` assertion for `Map`
 
 ## [0.27.0] 2023-09-13
 
diff --git a/assertk/src/commonMain/kotlin/assertk/assertions/map.kt b/assertk/src/commonMain/kotlin/assertk/assertions/map.kt
index 63e93b1..9eabb07 100644
--- a/assertk/src/commonMain/kotlin/assertk/assertions/map.kt
+++ b/assertk/src/commonMain/kotlin/assertk/assertions/map.kt
@@ -115,6 +115,14 @@ fun <K, V> Assert<Map<K, V>>.doesNotContain(element: Pair<K, V>) {
     doesNotContain(element.first, element.second)
 }
 
+/**
+ * Asserts the map does not contain the expected key.
+ */
+fun <K, V> Assert<Map<K, V>>.doesNotContainKey(key: K) = given {
+    if (!it.containsKey(key)) return
+    expected("to not contain key:${show(key)} but had value: ${show(it[key])}")
+}
+
 /**
  * Asserts the map does not contain any of the expected elements.
  * @see [containsAtLeast]


Test patch:
diff --git a/assertk/src/commonTest/kotlin/test/assertk/assertions/MapTest.kt b/assertk/src/commonTest/kotlin/test/assertk/assertions/MapTest.kt
index 8f55f23..601c013 100644
--- a/assertk/src/commonTest/kotlin/test/assertk/assertions/MapTest.kt
+++ b/assertk/src/commonTest/kotlin/test/assertk/assertions/MapTest.kt
@@ -42,6 +42,18 @@ class MapTest {
         }
         assertEquals("expected to not contain:<{\"two\"=2}> but was:<{\"one\"=1, \"two\"=2}>", error.message)
     }
+
+    @Test fun doesNotContainKey_key_missing_passes() {
+        assertThat(emptyMap<String, Int>()).doesNotContainKey("one")
+    }
+
+    @Test fun doesNotContainKey_key_present_fails() {
+        val error = assertFailsWith<AssertionError> {
+            assertThat(mapOf("one" to 1)).doesNotContainKey("one")
+        }
+        assertEquals("expected to not contain key:<\"one\"> but had value: <1>", error.message)
+    }
+
     //endregion
 
     //region containsNone