diff options
Diffstat (limited to 'test-tools/src/main/kotlin/matchers/content/ContentMatchersDsl.kt')
-rw-r--r-- | test-tools/src/main/kotlin/matchers/content/ContentMatchersDsl.kt | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/test-tools/src/main/kotlin/matchers/content/ContentMatchersDsl.kt b/test-tools/src/main/kotlin/matchers/content/ContentMatchersDsl.kt new file mode 100644 index 00000000..01abab28 --- /dev/null +++ b/test-tools/src/main/kotlin/matchers/content/ContentMatchersDsl.kt @@ -0,0 +1,101 @@ +package matchers.content + +import assertk.assertThat +import assertk.assertions.contains +import assertk.assertions.isEqualTo +import org.jetbrains.dokka.pages.* +import org.jetbrains.dokka.test.tools.matchers.content.* +import kotlin.reflect.KClass + +// entry point: +fun ContentNode.assertNode(block: ContentMatcherBuilder<ContentComposite>.() -> Unit) { + val matcher = ContentMatcherBuilder(ContentComposite::class).apply(block).build() + try { + matcher.tryMatch(this) + } catch (e: MatcherError) { + throw AssertionError(e.message + "\n" + matcher.toDebugString(e.anchor, e.anchorAfter)) + } +} + + +// DSL: +@DslMarker +annotation class ContentMatchersDsl + +@ContentMatchersDsl +class ContentMatcherBuilder<T : ContentComposite> @PublishedApi internal constructor(private val kclass: KClass<T>) { + @PublishedApi + internal val children = mutableListOf<MatcherElement>() + internal val assertions = mutableListOf<T.() -> Unit>() + + fun build() = CompositeMatcher(kclass, children) { assertions.forEach { it() } } + + // part of DSL that cannot be defined as an extension + operator fun String.unaryPlus() { + children += TextMatcher(this) + } +} + +fun <T : ContentComposite> ContentMatcherBuilder<T>.check(assertion: T.() -> Unit) { + assertions += assertion +} + +inline fun <reified S : ContentComposite> ContentMatcherBuilder<*>.composite( + block: ContentMatcherBuilder<S>.() -> Unit +) { + children += ContentMatcherBuilder(S::class).apply(block).build() +} + +inline fun <reified S : ContentNode> ContentMatcherBuilder<*>.node(noinline assertions: S.() -> Unit = {}) { + children += NodeMatcher(S::class, assertions) +} + +fun ContentMatcherBuilder<*>.skipAllNotMatching() { + children += Anything +} + + +// Convenience functions: +fun ContentMatcherBuilder<*>.group(block: ContentMatcherBuilder<ContentGroup>.() -> Unit) = composite(block) + +fun ContentMatcherBuilder<*>.header(expectedLevel: Int? = null, block: ContentMatcherBuilder<ContentHeader>.() -> Unit) = + composite<ContentHeader> { + block() + check { if (expectedLevel != null) assertThat(this::level).isEqualTo(expectedLevel) } + } + +fun ContentMatcherBuilder<*>.p(block: ContentMatcherBuilder<ContentGroup>.() -> Unit) = + composite<ContentGroup> { + block() + check { assertThat(this::style).contains(TextStyle.Paragraph) } + } + +fun ContentMatcherBuilder<*>.link(block: ContentMatcherBuilder<ContentLink>.() -> Unit) = composite(block) + +fun ContentMatcherBuilder<*>.table(block: ContentMatcherBuilder<ContentTable>.() -> Unit) = composite(block) + +fun ContentMatcherBuilder<*>.platformHinted(block: ContentMatcherBuilder<ContentGroup>.() -> Unit) = + composite<PlatformHintedContent> { group(block) } + +fun ContentMatcherBuilder<*>.br() = node<ContentBreakLine>() + +fun ContentMatcherBuilder<*>.somewhere(block: ContentMatcherBuilder<*>.() -> Unit) { + skipAllNotMatching() + block() + skipAllNotMatching() +} + +fun ContentMatcherBuilder<*>.divergentGroup(block: ContentMatcherBuilder<ContentDivergentGroup>.() -> Unit) = + composite(block) + +fun ContentMatcherBuilder<ContentDivergentGroup>.divergentInstance(block: ContentMatcherBuilder<ContentDivergentInstance>.() -> Unit) = + composite(block) + +fun ContentMatcherBuilder<ContentDivergentInstance>.before(block: ContentMatcherBuilder<ContentComposite>.() -> Unit) = + composite(block) + +fun ContentMatcherBuilder<ContentDivergentInstance>.divergent(block: ContentMatcherBuilder<ContentComposite>.() -> Unit) = + composite(block) + +fun ContentMatcherBuilder<ContentDivergentInstance>.after(block: ContentMatcherBuilder<ContentComposite>.() -> Unit) = + composite(block)
\ No newline at end of file |