diff --git a/reactor/Test/test/RulesHelper.kt b/reactor/Test/test/RulesHelper.kt index 6d7ae677..8c191d88 100644 --- a/reactor/Test/test/RulesHelper.kt +++ b/reactor/Test/test/RulesHelper.kt @@ -71,6 +71,22 @@ private fun updateHandler(name: String, rulesList: RulesList, vararg ruleBlocks: hb.toHandler() } +private fun insertRulesInHandler(at: Int, name: String, rulesList: RulesList, vararg ruleBlocks: () -> Rule): () -> RulesList = { + val hb = HandlerBuilder(name) + rulesList.rules().forEachIndexed { index, rule -> + if (index == at) { + for (block in ruleBlocks) { + hb.appendRule(block()) + } + } + hb.appendRule(rule) + } + hb.toHandler() +} + +private fun insertRulesInHandlerWhen(at: (Rule) -> Boolean, name: String, rulesList: RulesList, vararg ruleBlocks: () -> Rule): () -> RulesList = + insertRulesInHandler(rulesList.rules().indexOfFirst(at), name, rulesList, * ruleBlocks) + // builder DSL for constructing program fun programWithRules(vararg ruleBuilders: () -> Rule): Builder = @@ -79,6 +95,12 @@ fun programWithRules(vararg ruleBuilders: () -> Rule): Builder = fun Builder.programWithRules(vararg ruleBuilders: () -> Rule): Builder = updateBuilder(this, arrayOf(updateHandler("test", rulesLists.first(), * ruleBuilders))) +fun Builder.insertRulesAt(at: Int, vararg ruleBuilders: () -> Rule): Builder = + updateBuilder(this, arrayOf(insertRulesInHandler(at, "test", rulesLists.first(), * ruleBuilders))) + +fun Builder.insertRulesWhen(at: (Rule) -> Boolean, vararg ruleBuilders: () -> Rule): Builder = + updateBuilder(this, arrayOf(insertRulesInHandlerWhen(at, "test", rulesLists.first(), * ruleBuilders))) + fun rule(tag: String, vararg component: RuleBuilder.() -> Unit): () -> Rule = { val rb = RuleBuilder(tag) for (cmp in component) { diff --git a/reactor/Test/test/TestIncrementalProgram.kt b/reactor/Test/test/TestIncrementalProgram.kt index 93627ee1..6b12b189 100644 --- a/reactor/Test/test/TestIncrementalProgram.kt +++ b/reactor/Test/test/TestIncrementalProgram.kt @@ -279,7 +279,7 @@ class TestIncrementalProgram { setOf("main", "foo.bar", "foo.baz", "baz.dummy"), setOf(sym0("foo"), sym0("baz")) ) - val p1 = programWithRules( + programWithRules( rule("main", headReplaced( constraint("main") @@ -302,48 +302,26 @@ class TestIncrementalProgram { constraint("dummy") ) ) - ) - // p2 differs in that before discarding foo in foo.baz it also produces bar in foo.bar - val p2 = programWithRules( - rule("main", - headReplaced( - constraint("main") - ), - body( - princConstraint("foo") - )), - rule("foo.bar", - headKept( - princConstraint("foo") - ), - body( - constraint("bar") - )), - rule("foo.baz", - headReplaced( - princConstraint("foo") - ), - body( - constraint("baz") - )), - rule("baz.dummy", - headKept( - princConstraint("baz") - ), - body( - constraint("dummy") - ) - ) - ) + ).launch("initial run", progSpec) { result -> - val evalRes1 = p1.launch("initial run", progSpec) { result -> result.storeView().constraintSymbols() shouldBe setOf(sym0("baz"), sym0("dummy")) result.lastChunk().activatedLog().constraintSymbols() shouldBe listOf(sym0("dummy")) - }.second - p2.relaunch("test1", progSpec, evalRes1.token()) { result -> - result.storeView().constraintSymbols() shouldBe setOf(sym0("bar"), sym0("baz"), sym0("dummy")) - result.lastChunk().activatedLog().constraintSymbols() shouldBe listOf(sym0("dummy")) + }.also { (builder, evalRes) -> + // Insert rule before foo.baz: produce bar before discarding foo in foo.baz + builder.insertRulesAt(1, + rule("foo.bar", + headKept( + princConstraint("foo") + ), + body( + constraint("bar") + )) + ).relaunch("test1", progSpec, evalRes.token()) { result -> + + result.storeView().constraintSymbols() shouldBe setOf(sym0("bar"), sym0("baz"), sym0("dummy")) + result.lastChunk().activatedLog().constraintSymbols() shouldBe listOf(sym0("dummy")) + } } } @@ -353,7 +331,7 @@ class TestIncrementalProgram { setOf("main", "foo.bar", "foo.baz", "foo.qux"), setOf(sym0("foo")) ) - val p1 = programWithRules( + programWithRules( rule("main", headReplaced( constraint("main") @@ -376,45 +354,23 @@ class TestIncrementalProgram { constraint("qux") ) ) - ) - val p2 = programWithRules( - rule("main", - headReplaced( - constraint("main") - ), - body( - princConstraint("foo") - )), - rule("foo.bar", - headKept( - princConstraint("foo") - ), - body( - constraint("bar") - )), - rule("foo.baz", - headKept( - princConstraint("foo") - ), - body( - constraint("baz") - )), - rule("foo.qux", - headReplaced( - princConstraint("foo") - ), - body( - constraint("qux") - ) - ) - ) + ).launch("initial run", progSpec) { result -> - val evalRes1 = p1.launch("initial run", progSpec) { result -> result.storeView().constraintSymbols() shouldBe setOf(sym0("bar"), sym0("qux")) - }.second - p2.relaunch("test1", progSpec, evalRes1.token()) { result -> - result.storeView().constraintSymbols() shouldBe setOf(sym0("bar"), sym0("baz"), sym0("qux")) + }.also { (builder, evalRes) -> + builder.insertRulesAt(2, + rule("foo.baz", + headKept( + princConstraint("foo") + ), + body( + constraint("baz") + )) + ).relaunch("test1", progSpec, evalRes.token()) { result -> + + result.storeView().constraintSymbols() shouldBe setOf(sym0("bar"), sym0("baz"), sym0("qux")) + } } }