Cleanup obsolete code in test helper.

Refactor mock program builder for ease of use.
This commit is contained in:
Fedor Isakov 2019-05-02 18:49:01 +02:00
parent 736e0c2470
commit 13e8f4a205
5 changed files with 70 additions and 97 deletions

View File

@ -6,35 +6,30 @@ import jetbrains.mps.logic.reactor.evaluation.InvocationContext
import jetbrains.mps.logic.reactor.logical.LogicalContext
import jetbrains.mps.logic.reactor.logical.MetaLogical
import jetbrains.mps.logic.reactor.program.*
import program.MockConstraint
import java.util.*
import java.util.Collections.*
class ProgramBuilder(val registry: MockConstraintRegistry) {
private val handlers = ArrayList<Handler>()
fun addHandler(handler: Handler) {
for (r in handler.rules()) {
registry.update(r)
fun program(name: String, handlers: List<Handler>): Program {
for (h in handlers) {
for (r in h.rules()) {
registry.update(r)
}
}
handlers.add(handler)
return MockProgram(name, handlers, registry)
}
fun constraint(symbol: ConstraintSymbol, vararg args: Any): Constraint = MockConstraint(symbol, listOf(* args))
fun program(name: String): Program = MockProgram(name, handlers, registry)
}
open class HandlerBuilder(val name: String, val primary: Iterable<ConstraintSymbol>) {
open class HandlerBuilder(val name: String) {
val rules = ArrayList<Rule>()
fun appendRule(rule: Rule) {
rules.add(rule)
}
fun toHandler(): Handler = MockHandler(name, primary, rules)
fun toHandler(): Handler = MockHandler(name, rules)
}
open class RuleBuilder(val tag: String) {
@ -61,7 +56,6 @@ open class RuleBuilder(val tag: String) {
class MockHandler(
val name: String,
val primary: Iterable<ConstraintSymbol>,
val rules: List<Rule>) : Handler() {
override fun name(): String = name

View File

@ -9,10 +9,12 @@ import java.util.*
* @author Fedor Isakov
*/
class Builder(val env: Environment, val handlers: List<Handler>) : RuleLookup {
class Builder(var handlers: List<Handler>) : RuleLookup {
val tag2rule = HashMap<String, Rule>()
val programBuilder = ProgramBuilder(MockConstraintRegistry())
init {
handlers
.flatMap { it.rules() }
@ -25,73 +27,57 @@ class Builder(val env: Environment, val handlers: List<Handler>) : RuleLookup {
override fun lookupRuleByTag(tag: String): Rule? = tag2rule[tag]
fun ruleMatcher(): RuleMatcher = createRuleMatcher(this, rules.first().tag())
fun program(name: String): Program = programBuilder.program(name, handlers)
}
@Deprecated("don't use")
class Environment(val programBuilder: ProgramBuilder? = null) {
fun programWithRules(vararg ruleBuilders: () -> Rule): Builder {
return builder(arrayOf(handler("test", * ruleBuilders)))
}
fun programWithRules(vararg ruleBuilders: Environment.() -> Rule): Builder {
return programWithRules(Environment(), ruleBuilders)
}
fun programWithRules(pb: ProgramBuilder, vararg ruleBuilders: Environment.() -> Rule): Builder {
return programWithRules(Environment(pb), ruleBuilders)
}
private fun programWithRules(env: Environment, ruleBuilders: Array<out Environment.() -> Rule>): Builder {
return builder(env, arrayOf(handler("test", emptyList(), * ruleBuilders)))
}
fun programWithHandlers(vararg handlerBuilders: Environment.() -> Handler): Builder {
return builder(Environment(), handlerBuilders)
}
private fun builder(env: Environment, handlerBlocks: Array<out Environment.() -> Handler>): Builder {
private fun builder(handlerBlocks: Array<out () -> Handler>): Builder {
val handlers = ArrayList<Handler>()
with(env) {
for (block in handlerBlocks) {
handlers.add(block())
}
for (block in handlerBlocks) {
handlers.add(block())
}
return Builder(env, handlers)
return Builder(handlers)
}
fun handler(name: String, primary: Iterable<ConstraintSymbol>, vararg ruleBlocks: Environment.() -> Rule): Environment.() -> Handler = {
val hb = HandlerBuilder(name, primary)
fun handler(name: String, vararg ruleBlocks: () -> Rule): () -> Handler = {
val hb = HandlerBuilder(name)
for (block in ruleBlocks) {
hb.appendRule(this.block())
hb.appendRule(block())
}
hb.toHandler()
}
fun rule(tag: String, vararg component: RB.() -> Unit): Environment.() -> Rule = {
val rb = RB(this, tag)
fun rule(tag: String, vararg component: RuleBuilder.() -> Unit): () -> Rule = {
val rb = RuleBuilder(tag)
for (cmp in component) {
rb.cmp()
}
rb.toRule()
}
fun headKept(vararg content: ConjBuilder.() -> Unit): RB.() -> Unit = {
appendHeadKept(* buildConjunction(Constraint::class.java, env, content).toArray())
fun headKept(vararg content: ConjBuilder.() -> Unit): RuleBuilder.() -> Unit = {
appendHeadKept(* buildConjunction(Constraint::class.java, content).toArray())
}
fun headReplaced(vararg content: ConjBuilder.() -> Unit): RB.() -> Unit = {
appendHeadReplaced(* buildConjunction(Constraint::class.java, env, content).toArray())
fun headReplaced(vararg content: ConjBuilder.() -> Unit): RuleBuilder.() -> Unit = {
appendHeadReplaced(* buildConjunction(Constraint::class.java, content).toArray())
}
fun guard(vararg content: ConjBuilder.() -> Unit): RB.() -> Unit = {
appendGuard(* buildConjunction(Predicate::class.java, env, content).toArray())
fun guard(vararg content: ConjBuilder.() -> Unit): RuleBuilder.() -> Unit = {
appendGuard(* buildConjunction(Predicate::class.java, content).toArray())
}
fun body(vararg content: ConjBuilder.() -> Unit): RB.() -> Unit = {
appendBody(false, * buildConjunction(AndItem::class.java, env, content).toArray())
fun body(vararg content: ConjBuilder.() -> Unit): RuleBuilder.() -> Unit = {
appendBody(false, * buildConjunction(AndItem::class.java, content).toArray())
}
fun altBody(vararg content: ConjBuilder.() -> Unit): RB.() -> Unit = {
appendBody(true, * buildConjunction(AndItem::class.java, env, content).toArray())
fun altBody(vararg content: ConjBuilder.() -> Unit): RuleBuilder.() -> Unit = {
appendBody(true, * buildConjunction(AndItem::class.java, content).toArray())
}
fun constraint(id: String, vararg args: Any): ConjBuilder.() -> Unit = {
@ -119,16 +105,11 @@ object fooObservable : FrameObservable {
}
}
class RB(val env: Environment, tag: String) : RuleBuilder(tag) {
}
class ConjBuilder(val type: Class<out AndItem>, val env: Environment) {
class ConjBuilder(val type: Class<out AndItem>) {
val constraints = ArrayList<AndItem>()
fun createConstraint(args: Array<out Any>, id: String): Constraint {
return env.programBuilder?.constraint(ConstraintSymbol(id, args.size), * args)
?: MockConstraint(ConstraintSymbol(id, args.size), * args)
return MockConstraint(ConstraintSymbol(id, args.size), * args)
}
fun add(item: AndItem): Unit {
@ -155,9 +136,8 @@ class ConjBuilder(val type: Class<out AndItem>, val env: Environment) {
}
private fun buildConjunction(type: Class<out AndItem>,
env: Environment,
content: Array<out ConjBuilder.() -> Unit>): ConjBuilder {
val conjBuilder = ConjBuilder(type, env)
val conjBuilder = ConjBuilder(type)
for (c in content) {
conjBuilder.c()
}

View File

@ -1,4 +1,5 @@
import jetbrains.mps.logic.reactor.core.ReactorLifecycle
import jetbrains.mps.logic.reactor.evaluation.EvaluationResult
import jetbrains.mps.logic.reactor.evaluation.EvaluationSession
import jetbrains.mps.logic.reactor.evaluation.StoreView
import jetbrains.mps.logic.reactor.program.Constraint
@ -45,17 +46,20 @@ class TestIncrementalProgram {
}
}
private fun Builder.launch(name: String): StoreView {
val programBuilder = ProgramBuilder(MockConstraintRegistry())
for (h in handlers) {
programBuilder.addHandler(h)
}
val result = EvaluationSession.newSession(programBuilder.program(name))
private fun Builder.launch(name: String, resultHandler: (EvaluationResult) -> Unit): Pair<Builder, StoreView> {
val result = EvaluationSession.newSession(program(name))
.withParameter(EvaluationSession.ParameterKey.of("main", Constraint::class.java), MockConstraint(ConstraintSymbol("main", 0)))
.start()
return result.storeView()
result.failure()?.let { throw it.cause }
resultHandler(result)
return this to result.storeView()
}
private fun Builder.relaunch(name: String, storeView: StoreView, resultHandler: (EvaluationResult) -> Unit) {
}
// private fun StoreView.launch(name: String): StoreView {
// val programBuilder = ProgramBuilder(MockConstraintRegistry())
// for (h in handlers) {
@ -84,8 +88,11 @@ class TestIncrementalProgram {
constraint("bar")
)
)
).launch("replace").apply {
Assert.assertEquals(setOf(ConstraintSymbol("foo", 0), ConstraintSymbol("bar", 0)), constraintSymbols())
).launch("replace") { result ->
result.storeView().constraintSymbols() shouldBe setOf(ConstraintSymbol("foo", 0), ConstraintSymbol("bar", 0))
}.also { (builder, storeView) ->
}
}

View File

@ -32,11 +32,7 @@ class TestProgram {
}
private fun Builder.session(name: String): StoreView {
val programBuilder = ProgramBuilder(MockConstraintRegistry())
for (h in handlers) {
programBuilder.addHandler(h)
}
val session = EvaluationSession.newSession(programBuilder.program(name))
val session = EvaluationSession.newSession(program(name))
.withParameter(EvaluationSession.ParameterKey.of("main", Constraint::class.java), MockConstraint(ConstraintSymbol("main", 0)))
.start()
return session.storeView()

View File

@ -10,27 +10,22 @@ import org.junit.Test
class TestProgramBuilder {
@Before fun beforeTest() {
programBuilder = ProgramBuilder(MockConstraintRegistry())
}
lateinit var programBuilder: ProgramBuilder
@Test(expected = InvalidRuleException::class)
fun emptyBody() {
programWithRules(programBuilder,
programWithRules(
rule("foo",
headKept(
constraint("bar")
))).run {
programBuilder.addHandler(MockHandler("test", emptyList(), rules))
)
)
).run {
program("test")
}
}
@Test
fun replace() {
programWithRules(programBuilder,
programWithRules(
rule("foo",
headReplaced(
constraint("bar")
@ -47,25 +42,26 @@ class TestProgramBuilder {
),
body(
constraint("blah")
))).run {
programBuilder.addHandler(MockHandler("test", emptyList(), rules))
assertEquals(programBuilder.program("test").handlers().flatMap { it.rules() }.count(), 2)
)
)
).run {
assertEquals(program("test").handlers().flatMap { it.rules() }.count(), 2)
}
}
@Test(expected = InvalidConstraintException::class)
fun fail() {
programWithRules(programBuilder,
programWithRules(
rule("foo",
headReplaced(
constraint("bar", 1)
),
body(
constraint("bar", "1")
))).run {
programBuilder.addHandler(MockHandler("test", emptyList(), rules))
)
)
).run {
program("test")
}
}
}