diff --git a/CHANGELOG.md b/CHANGELOG.md index 059a489f2..1cefb7604 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Changed - Allow construction of Message without body +- Ensure Event Handlers are not invoked if there are no PE matches + https://github.com/atomist/rug/issues/454 ## [0.17.1] - 2017-03-20 diff --git a/src/main/scala/com/atomist/rug/runtime/js/JavaScriptEventHandler.scala b/src/main/scala/com/atomist/rug/runtime/js/JavaScriptEventHandler.scala index 8e054ec9f..0737820f6 100644 --- a/src/main/scala/com/atomist/rug/runtime/js/JavaScriptEventHandler.scala +++ b/src/main/scala/com/atomist/rug/runtime/js/JavaScriptEventHandler.scala @@ -57,7 +57,7 @@ class JavaScriptEventHandler(jsc: JavaScriptContext, val root = SimpleContainerGraphNode("root", targetNode) ctx.pathExpressionEngine.ee.evaluate(root, pathExpression, ctx.typeRegistry, None) match { case Right(Nil) => None - case Right(matches) => + case Right(matches) if matches.nonEmpty => val cm = jsContextMatch( jsSafeCommittingProxy.wrapOne(targetNode, ctx.typeRegistry), jsSafeCommittingProxy.wrap(matches, ctx.typeRegistry), @@ -66,6 +66,7 @@ class JavaScriptEventHandler(jsc: JavaScriptContext, case plan: ScriptObjectMirror => ConstructPlan(plan) case other => throw new InvalidHandlerResultException(s"$name EventHandler returned an invalid response ($other) when handling $pathExpressionStr") } + case Right(matches) if matches.isEmpty => None case Left(failure) => throw new RugRuntimeException(pathExpressionStr, s"Error evaluating path expression $pathExpression: [$failure]") diff --git a/src/test/scala/com/atomist/rug/runtime/js/JavaScriptEventHandlerTest.scala b/src/test/scala/com/atomist/rug/runtime/js/JavaScriptEventHandlerTest.scala index 772aba88c..db9909642 100644 --- a/src/test/scala/com/atomist/rug/runtime/js/JavaScriptEventHandlerTest.scala +++ b/src/test/scala/com/atomist/rug/runtime/js/JavaScriptEventHandlerTest.scala @@ -114,6 +114,23 @@ object JavaScriptEventHandlerTest { |} |export let handler = new SimpleHandler(); """.stripMargin) + + val eventHandlerWithEmptyMatches = StringFileArtifact(atomistConfig.handlersRoot + "/Handler.ts", + s""" + |import {HandleEvent, Plan, Message} from '@atomist/rug/operations/Handlers' + |import {TreeNode, Match, PathExpression} from '@atomist/rug/tree/PathExpression' + |import {EventHandler, Tags} from '@atomist/rug/operations/Decorators' + | + |@EventHandler("BuildHandler", "Handles a Build event", new PathExpression("/nomatch")) + |@Tags("github", "build") + |class SimpleHandler implements HandleEvent { + | handle(event: Match): Message{ + | return new Message("woot").withCorrelationId("dude").withNode(event.root()); + | } + |} + |export let handler = new SimpleHandler(); + """.stripMargin) + } @@ -221,6 +238,18 @@ class JavaScriptEventHandlerTest extends FlatSpec with Matchers with DiagrammedA assert(msg.treeNode.nonEmpty) assert(msg.correlationId.nonEmpty) } + + it should "it should not invoke the actual handler if there matches are empty" in { + val rugArchive = TypeScriptBuilder.compileWithModel(SimpleFileBasedArtifactSource(JavaScriptEventHandlerTest.eventHandlerWithEmptyMatches)) + val finder = new JavaScriptEventHandlerFinder() + val handlers = finder.find(new JavaScriptContext(rugArchive)) + handlers.size should be(1) + val handler = handlers.head + handler.rootNodeName should be("nomatch") + handler.pathExpression should not be null + val actualPlan = handler.handle(LocalRugContext(TestTreeMaterializer), SysEvent) + assert(actualPlan.isEmpty) + } } object SysEvent extends SystemEvent ("blah", "issue", 0l)