Piotr Krzemiński
08/27/2025, 12:05 PMobj shouldNotBe null
is not equivalent to obj.shouldNotBeNull()
. The former was used by Junie when obj
was an iterator, and instead of just asserting on it not being null
, it consumed all items of the iterator, making it unusable for future assertions. I think both should be equivalent since they read the same, and here in should.kt, we could have another check: if any
is null
. If yes, delegate it to any.shouldNotBeNull()
. The same applies to shouldBe null
. WDYT?Alex Kuznetsov
08/27/2025, 1:44 PMobj
was an iterator, and instead of just asserting on it not being null
, it consumed all items of the iterator, making it unusable for future assertions"Piotr Krzemiński
08/27/2025, 1:59 PMPiotr Krzemiński
08/27/2025, 2:46 PMpackage it.krzeminski.snakeyaml.engine.kmp.issues.issue46
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.nulls.shouldNotBeNull
import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe
class MyStatefulObject : Iterable<Int> {
var state: Int? = 5
override fun iterator(): Iterator<Int> = iterator {
if (state != null) {
yield(state!!)
state = null
}
}
}
class ReproductionTest : FunSpec({
test("reproduction") {
val obj = MyStatefulObject()
// Uncomment just this to make the test fail
// since the iterator is consumed, and after this assertion
// there are no items to consume
// obj shouldNotBe null
// Uncomment just this to make the test pass
// since the iterator isn't consumed
obj.shouldNotBeNull()
val iterator = obj as Iterable<*>
iterator.iterator().hasNext() shouldBe true
}
})
Alex Kuznetsov
08/27/2025, 2:48 PMPiotr Krzemiński
08/28/2025, 6:29 AMScott Fedorov
08/28/2025, 11:17 PMPiotr Krzemiński
08/29/2025, 4:19 AM