Skip to content
This repository was archived by the owner on Sep 22, 2022. It is now read-only.

Commit 59b959e

Browse files
authored
Redesign reports (#49)
* redesign
1 parent 713e3b0 commit 59b959e

File tree

34 files changed

+814
-437
lines changed

34 files changed

+814
-437
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ buildscript {
44
ext.exposed_version = '0.35.1'
55
ext.restAssured_version = '4.4.0'
66
ext.klogging_version = '2.0.11'
7-
ext.libVersion = '6.0.0-beta'
7+
ext.libVersion = '6.0.0-beta-1'
88
repositories {
99
mavenCentral()
1010
}

exam-core/src/main/java/io/github/adven27/concordion/extensions/exam/core/ExamPlugin.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package io.github.adven27.concordion.extensions.exam.core
22

3-
import io.github.adven27.concordion.extensions.exam.core.commands.ExamCommand
3+
import io.github.adven27.concordion.extensions.exam.core.commands.NamedExamCommand
44

55
interface ExamPlugin {
6-
fun commands(): List<ExamCommand>
6+
fun commands(): List<NamedExamCommand>
77
fun setUp()
88
fun tearDown()
99

exam-core/src/main/java/io/github/adven27/concordion/extensions/exam/core/PlaceholdersResolver.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
package io.github.adven27.concordion.extensions.exam.core
44

55
import io.github.adven27.concordion.extensions.exam.core.handlebars.HANDLEBARS
6-
import io.github.adven27.concordion.extensions.exam.core.handlebars.PLACEHOLDER_TYPE
6+
import io.github.adven27.concordion.extensions.exam.core.handlebars.matchers.PLACEHOLDER_TYPE
77
import io.github.adven27.concordion.extensions.exam.core.handlebars.resolve
88
import io.github.adven27.concordion.extensions.exam.core.handlebars.resolveObj
99
import org.concordion.api.Evaluator

exam-core/src/main/java/io/github/adven27/concordion/extensions/exam/core/commands/ExamCommand.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,10 @@ interface BeforeParseExamCommand {
4747

4848
open class BaseExamCommand(override val name: String) : NamedExamCommand, AbstractCommand()
4949

50-
open class ExamCommand(override val name: String, override val tag: String) : BeforeParseExamCommand,
51-
BaseExamCommand(name) {
50+
open class ExamCommand(
51+
name: String,
52+
override val tag: String
53+
) : BeforeParseExamCommand, BaseExamCommand(name) {
5254
private val listeners = Announcer.to(ExecuteListener::class.java)
5355

5456
override fun execute(
@@ -107,7 +109,7 @@ fun Html.awaitConfig(prefix: String = "await") = AwaitConfig(
107109
takeAwayAttr("${prefix}PollIntervalMillis")?.toLong()
108110
)
109111

110-
data class AwaitConfig(val atMostSec: Long?, val pollDelay: Long?, val pollInterval: Long?) {
112+
data class AwaitConfig(val atMostSec: Long? = null, val pollDelay: Long? = null, val pollInterval: Long? = null) {
111113
fun enabled(): Boolean = !(atMostSec == null && pollDelay == null && pollInterval == null)
112114
}
113115

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,41 @@
11
package io.github.adven27.concordion.extensions.exam.core.commands
22

33
import io.github.adven27.concordion.extensions.exam.core.html.Html
4+
import org.concordion.api.AbstractCommand
45
import org.concordion.api.Element
56
import org.concordion.api.Result.FAILURE
67
import org.concordion.api.Result.SUCCESS
78
import org.concordion.api.ResultRecorder
9+
import org.concordion.api.listener.AbstractElementEvent
810
import org.concordion.api.listener.AssertEqualsListener
911
import org.concordion.api.listener.AssertFailureEvent
1012
import org.concordion.api.listener.AssertSuccessEvent
11-
import org.concordion.internal.util.Announcer
13+
import java.util.EventListener
1214

13-
open class ExamVerifyCommand(name: String, tag: String, listener: AssertEqualsListener) : ExamCommand(name, tag) {
14-
private val listeners = Announcer.to(AssertEqualsListener::class.java)
15+
class VerifyFailureEvent(el: Element, val expected: Any?, val actual: Any?, error: Throwable) : AbstractElementEvent(el)
16+
class VerifySuccessEvent(el: Element, val expected: Any? = null, val actual: Any? = null) : AbstractElementEvent(el)
1517

16-
init {
17-
listeners.addListener(listener)
18-
}
18+
interface VerifyListener : EventListener {
19+
fun successReported(event: VerifySuccessEvent)
20+
fun failureReported(event: VerifyFailureEvent)
21+
}
22+
23+
open class ExamVerifyCommand(
24+
name: String,
25+
tag: String,
26+
private val listener: AssertEqualsListener
27+
) : ExamCommand(name, tag) {
1928

2029
protected fun success(resultRecorder: ResultRecorder, element: Element) {
2130
resultRecorder.record(SUCCESS)
22-
listeners.announce().successReported(AssertSuccessEvent(element))
31+
listener.successReported(AssertSuccessEvent(element))
2332
}
2433

2534
protected fun success(resultRecorder: ResultRecorder, element: Html) = success(resultRecorder, element.el())
2635

2736
protected fun failure(resultRecorder: ResultRecorder, element: Element, actual: Any, expected: String) {
2837
resultRecorder.record(FAILURE)
29-
listeners.announce().failureReported(AssertFailureEvent(element, expected, actual))
38+
listener.failureReported(AssertFailureEvent(element, expected, actual))
3039
}
3140

3241
protected fun failure(resultRecorder: ResultRecorder, element: Html, actual: Any, expected: String) =
@@ -42,9 +51,42 @@ open class ExamVerifyCommand(name: String, tag: String, listener: AssertEqualsLi
4251
actual: String,
4352
expected: String,
4453
test: (String, String) -> Boolean = { a, e -> a == e }
45-
) =
46-
if (test(actual, expected)) {
47-
root.text(expected)
48-
this.pass(root)
49-
} else this.failure(root, actual, expected)
54+
) = if (test(actual, expected)) {
55+
root.text(expected)
56+
this.pass(root)
57+
} else this.failure(root, actual, expected)
58+
}
59+
60+
open class ExamAssertCommand(private val listener: VerifyListener) : AbstractCommand() {
61+
62+
protected fun success(resultRecorder: ResultRecorder, element: Element) {
63+
resultRecorder.record(SUCCESS)
64+
listener.successReported(VerifySuccessEvent(element))
65+
}
66+
67+
protected fun success(resultRecorder: ResultRecorder, element: Html) = success(resultRecorder, element.el())
68+
69+
protected fun failure(
70+
resultRecorder: ResultRecorder,
71+
element: Element,
72+
actual: Any,
73+
expected: Any,
74+
error: Throwable
75+
) {
76+
resultRecorder.record(FAILURE)
77+
listener.failureReported(VerifyFailureEvent(element, expected, actual, error))
78+
}
79+
80+
protected fun failure(
81+
resultRecorder: ResultRecorder,
82+
element: Html,
83+
actual: Any,
84+
expected: Any,
85+
error: Throwable
86+
) = failure(resultRecorder, element.el(), actual, expected, error)
87+
88+
protected fun ResultRecorder.pass(element: Html): Html = element.also { success(this, it) }
89+
90+
protected fun ResultRecorder.failure(element: Html, actual: String, expected: String, error: Throwable) =
91+
element.also { failure(this, it, actual, expected, error) }
5092
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package io.github.adven27.concordion.extensions.exam.core.handlebars
2+
3+
import com.github.jknack.handlebars.Context
4+
import com.github.jknack.handlebars.EscapingStrategy.NOOP
5+
import com.github.jknack.handlebars.Handlebars
6+
import com.github.jknack.handlebars.Helper
7+
import com.github.jknack.handlebars.Options
8+
import io.github.adven27.concordion.extensions.exam.core.handlebars.date.DateHelpers
9+
import io.github.adven27.concordion.extensions.exam.core.handlebars.matchers.MatcherHelpers
10+
import io.github.adven27.concordion.extensions.exam.core.handlebars.misc.MiscHelpers
11+
import org.concordion.api.Evaluator
12+
import java.util.concurrent.atomic.AtomicReference
13+
14+
val HB_RESULT: AtomicReference<Any?> = AtomicReference()
15+
16+
val HANDLEBARS: Handlebars = Handlebars()
17+
.with(NOOP)
18+
.with { value, next ->
19+
HB_RESULT.set(value)
20+
return@with next.format(value)
21+
}
22+
.prettyPrint(false)
23+
.registerHelpers(MiscHelpers::class.java)
24+
.registerHelpers(DateHelpers::class.java)
25+
.registerHelpers(MatcherHelpers::class.java)
26+
.registerHelperMissing(HelperMissing())
27+
28+
class MissingHelperException(options: Options) : IllegalArgumentException(
29+
"Variable or helper '${options.fn.text()}' not found"
30+
)
31+
32+
const val REGISTER_HELPER_EXAMPLE = """ExamExtension().withHandlebar { hb ->
33+
hb.registerHelper("hi", Helper { context: Any?, options ->
34+
//{{hi '1' 'p1 'p2' o1='a' o2='b'}} => Hello context = 1; params = [p1, p2]; options = {o1=a, o2=b}!
35+
//{{hi variable1 variable2 o1=variable3}} => Hello context = 1; params = [2]; options = {o1=3}!
36+
"Hello context = ${"$"}context; params = ${"$"}{options.params.map { it.toString() }}; options = ${"$"}{options.hash}!"
37+
})
38+
}"""
39+
40+
class HelperMissing : Helper<Any?> {
41+
override fun apply(context: Any?, options: Options) = throw MissingHelperException(options)
42+
43+
companion object {
44+
fun helpersDesc(): Map<Package, Map<String, Helper<*>>> =
45+
HANDLEBARS.helpers().groupBy { it.value.javaClass.`package` }.map { e ->
46+
e.key to e.value
47+
.filterNot { it.key == "helperMissing" }
48+
.sortedBy { it.key }
49+
.associate { it.key to it.value }
50+
}.toMap()
51+
}
52+
}
53+
54+
fun Handlebars.resolve(eval: Any?, placeholder: String): String = compileInline(placeholder).apply(
55+
Context.newBuilder(eval).resolver(EvaluatorValueResolver.INSTANCE).build()
56+
)
57+
58+
fun Handlebars.resolveObj(eval: Evaluator, placeholder: String): Any? {
59+
HB_RESULT.set(placeholder)
60+
resolve(eval, placeholder)
61+
return HB_RESULT.get()
62+
}
63+
64+
interface ExamHelper : Helper<Any?> {
65+
val example: String
66+
val context: Map<String, Any?>
67+
val expected: Any?
68+
val options: Map<String, String>
69+
70+
fun describe() =
71+
"$example will produce: ${expectedStr()} ${if (context.isEmpty()) "" else "(given context has variables: $context)"}"
72+
73+
private fun expectedStr() = when (expected) {
74+
is String -> "\"$expected\""
75+
null -> null
76+
else -> "object of ${expected?.javaClass} = \"$expected\""
77+
}
78+
79+
class InvocationFailed(name: String, context: Any?, options: Options, throwable: Throwable) :
80+
RuntimeException(
81+
"Invocation of {{$name}} (context: $context, options: ${options.fn.text()}) failed: ${throwable.message}",
82+
throwable
83+
)
84+
}
85+
86+
fun Options.evaluator(): Evaluator = (this.context.model() as Evaluator)

0 commit comments

Comments
 (0)