Skip to content

Commit 2fb87fd

Browse files
committed
implement better inheritance
1 parent fa29d1b commit 2fb87fd

File tree

5 files changed

+35
-20
lines changed

5 files changed

+35
-20
lines changed

src/main/kotlin/com/memozr/assertk/AbstractAssertBuilder.kt

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,47 +10,51 @@ enum class ObjectStuff {
1010

1111
inline fun <reified R : Any> of() = AbstractAssertBuilder.InstanceMatcher<R>()
1212

13-
open class AbstractAssertBuilder<T : Any>(other: T?) {
13+
abstract class AbstractAssertBuilder<S : AbstractAssertBuilder<S, A>, A : Any> internal constructor(actual: A?, selfType: Class<*>) {
1414
class InstanceMatcher<R>
1515

16-
open protected val assertion: AbstractAssert<*, out T?> = Assertions.assertThat(other)
16+
@Suppress("UNCHECKED_CAST", "LeakingThis")
17+
protected val myself: S = selfType.cast(this) as S
1718

18-
infix fun isEqualTo(other: T): AbstractAssertBuilder<T> {
19+
open protected val assertion: AbstractAssert<*, out A?> = Assertions.assertThat(actual)
20+
21+
infix fun isEqualTo(other: A): S {
1922
assertion.isEqualTo(other)
20-
return this
23+
return myself
2124
}
2225

23-
infix fun isNotEqualTo(other: T): AbstractAssertBuilder<T> {
26+
infix fun isNotEqualTo(other: A): S {
2427
assertion.isNotEqualTo(other)
25-
return this
28+
return myself
2629
}
2730

2831
@Suppress("UNUSED_PARAMETER")
29-
inline infix fun <reified R: Any> isInstance(bar: InstanceMatcher<R>) : AbstractAssertBuilder<T> {
32+
inline infix fun <reified R : Any> isInstance(bar: InstanceMatcher<R>): S {
3033
assertion.isInstanceOf(R::class.java)
31-
return this
34+
return myself
3235
}
3336

34-
infix fun _is(objectStuff: ObjectStuff?): AbstractAssertBuilder<T> {
37+
infix fun _is(objectStuff: ObjectStuff?): S {
3538
return when (objectStuff) {
3639
notNull -> {
3740
assertion.isNotNull()
38-
this
41+
myself
3942
}
4043
else -> {
4144
assertion.isNull()
42-
this
45+
myself
4346
}
4447
}
4548
}
4649

47-
infix fun describedAs(description: String): AbstractAssertBuilder<T> {
50+
infix fun describedAs(description: String): S {
4851
assertion.`as`(description)
49-
return this
52+
return myself
5053
}
5154

52-
infix fun isSuchThat(assertionBlock: AbstractAssertBuilder<T>.(AbstractAssertBuilder<T>) -> Unit): AbstractAssertBuilder<T> {
53-
assertionBlock(this)
54-
return this
55+
@Suppress("UNCHECKED_CAST")
56+
infix fun isSuchThat(assertionBlock: S.(S) -> Unit): S {
57+
(this as S).assertionBlock(this)
58+
return myself
5559
}
56-
}
60+
}

src/main/kotlin/com/memozr/assertk/CharSequenceAssert.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ enum class CharSequenceAssertTest {
1111

1212
class CharSequenceAssert internal constructor(
1313
private val subject: String?,
14-
override protected val assertion: AbstractCharSequenceAssert<*, String> = assertThat(subject))
15-
: AbstractAssertBuilder<String>(subject) {
14+
override val assertion: AbstractCharSequenceAssert<*, String> = assertThat(subject))
15+
: AbstractAssertBuilder<CharSequenceAssert, String>(subject, CharSequenceAssert::class.java) {
1616

1717
object onlyDigits
1818

src/main/kotlin/com/memozr/assertk/General.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ val assert: AssertionHook get() = RealAssertionHook()
44
val expect: AssertionHook get() = RealAssertionHook()
55

66
interface AssertionHook {
7-
infix fun <T : Any> that(subjectUnderTest: T?) = AbstractAssertBuilder(subjectUnderTest)
7+
infix fun <T : Any> that(subjectUnderTest: T?) = ObjectAssert(subjectUnderTest)
88
infix fun that(subjectUnderTest: String?) = CharSequenceAssert(subjectUnderTest)
99
infix fun thatThrownBy(expressionUnderTest: () -> Unit) = ThrowableAssertionBuilder(expressionUnderTest)
1010
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package com.memozr.assertk
2+
3+
class ObjectAssert<A : Any>(actual: A?) : AbstractAssertBuilder<ObjectAssert<A>, A>(actual, ObjectAssert::class.java)

src/test/kotlin/com/memozr/assertk/Char sequence assert test.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,4 +193,12 @@ class `Char sequence assert test` {
193193
_expect that "foo bar" containsPattern pattern canBe chained
194194
verify(mockAssertion).containsPattern(pattern)
195195
}
196+
197+
@Test
198+
fun `Block syntax is supported`() {
199+
_expect that "foo" isSuchThat {
200+
it contains "foo"
201+
it isSubstringOf "fooBar"
202+
}
203+
}
196204
}

0 commit comments

Comments
 (0)