This is an automated email from the ASF dual-hosted git repository.

sergeykamov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git


The following commit(s) were added to refs/heads/master by this push:
     new 79255bb  Bugfixes and tests.
79255bb is described below

commit 79255bbbe2f61ad36ff03713a52c00724da51b6e
Author: Sergey Kamov <[email protected]>
AuthorDate: Tue Feb 22 16:28:44 2022 +0300

    Bugfixes and tests.
---
 .../intent/matcher/NCIntentSolverManager.scala     |  24 ++--
 .../internal/impl/NCModelCallbacksSpec.scala       | 157 +++++++++++++++++++++
 2 files changed, 169 insertions(+), 12 deletions(-)

diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/intent/matcher/NCIntentSolverManager.scala
 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/intent/matcher/NCIntentSolverManager.scala
index d093e9b..11475bd 100644
--- 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/intent/matcher/NCIntentSolverManager.scala
+++ 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/intent/matcher/NCIntentSolverManager.scala
@@ -697,26 +697,26 @@ class NCIntentSolverManager(dialog: NCDialogFlowManager, 
intents: Map[NCIDLInten
       * @return
       */
     def solve(mdl: NCModel, ctx: NCContext): NCResult =
-        val resCtx: NCResult = mdl.onContext(ctx)
+        var res: NCResult = mdl.onContext(ctx)
 
-        if resCtx != null then
-            resCtx
+        if res != null then
+            res
         else
-            var res: IterationResult = null
+            var loopRes: IterationResult = null
 
             try
-                while (res == null)
+                while (loopRes == null)
                     solveIteration(mdl, ctx) match
-                        case Some(iterRes) => res = iterRes
+                        case Some(iterRes) => loopRes = iterRes
                         case None => // No-op.
 
-                mdl.onResult(res.intentMatch, res.result)
+                res = mdl.onResult(loopRes.intentMatch, loopRes.result)
 
-                res.result
+                if res != null then res else loopRes.result
             catch
                 case e: NCRejection =>
-                    mdl.onRejection(if res != null then res.intentMatch else 
null, e)
-                    throw e
+                    val res = mdl.onRejection(if loopRes != null then 
loopRes.intentMatch else null, e)
+                    if res != null then res else throw e
                 case e: Throwable =>
-                    mdl.onError(ctx, e)
-                    throw e
\ No newline at end of file
+                    val res = mdl.onError(ctx, e)
+                    if res != null then res else throw e
\ No newline at end of file
diff --git 
a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelCallbacksSpec.scala
 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelCallbacksSpec.scala
new file mode 100644
index 0000000..b601e5d
--- /dev/null
+++ 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelCallbacksSpec.scala
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nlpcraft.internal.impl
+
+import org.apache.nlpcraft.*
+import org.apache.nlpcraft.NCResultType.*
+import org.apache.nlpcraft.nlp.entity.parser.semantic.*
+import 
org.apache.nlpcraft.nlp.entity.parser.semantic.impl.en.NCEnSemanticPorterStemmer
+import org.apache.nlpcraft.nlp.util.NCTestModelAdapter
+import org.apache.nlpcraft.nlp.util.opennlp.*
+import org.junit.jupiter.api.*
+
+import scala.jdk.CollectionConverters.*
+import scala.util.Using
+
+/**
+  *
+  */
+class NCModelCallbacksSpec:
+    enum State:
+        case
+            Default,
+            MatchFalse, VariantFalse,
+            ContextNotNull, ResultNotNull, RejectionNotNull, ErrorNotNull,
+            IntentError, IntentReject
+
+    import State.*
+
+    private val states = collection.mutable.HashSet.empty[State]
+
+    private val RESULT_INTENT = mkResult("result-intent")
+    private val RESULT_CONTEXT = mkResult("result-context")
+    private val RESULT_RESULT = mkResult("result-result")
+    private val RESULT_REJECTION = mkResult("result-rejection")
+    private val RESULT_ERROR = mkResult("result-error")
+
+    private val MDL: NCModel =
+        new NCTestModelAdapter():
+            @NCIntent("intent=x term(x)={# == 'x'}")
+            def intent(im: NCIntentMatch, @NCIntentTerm("x") x: NCEntity): 
NCResult =
+                if has(IntentError) then throw new RuntimeException("Error")
+                else if has(IntentReject) then throw new 
NCRejection("Rejection")
+                else RESULT_INTENT
+
+            override def onMatchedIntent(ctx: NCIntentMatch): Boolean = if 
has(MatchFalse) then false  else true
+            override def onVariant(vrn: NCVariant): Boolean = if 
has(VariantFalse) then false  else true
+            override def onContext(ctx: NCContext): NCResult = if 
has(ContextNotNull) then RESULT_CONTEXT  else null
+            override def onResult(ctx: NCIntentMatch, res: NCResult): NCResult 
= if has(ResultNotNull) then RESULT_RESULT  else null
+            override def onRejection(ctx: NCIntentMatch, e: NCRejection): 
NCResult = if has(RejectionNotNull) then RESULT_REJECTION else null
+            override def onError(ctx: NCContext, e: Throwable): NCResult = if 
has(ErrorNotNull) then RESULT_ERROR else null
+
+    MDL.getPipeline.getEntityParsers.add(
+        new NCSemanticEntityParser(
+            new NCEnSemanticPorterStemmer,
+            EN_PIPELINE.getTokenParser,
+            Seq(NCSemanticTestElement("x")).asJava
+        )
+    )
+
+    /**
+      *
+      * @param s
+      * @return
+      */
+    private def has(s: State): Boolean = states.synchronized { 
states.contains(s) }
+
+    /**
+      *
+      * @param txt
+      * @return
+      */
+    private def mkResult(txt: String): NCResult =
+        val res = new NCResult()
+        res.setType(NCResultType.ASK_RESULT)
+        res.setBody(txt)
+        res
+
+    /**
+      *
+      * @param states
+      * @return
+      */
+    private def set(states: State*) =
+        this.states.synchronized {
+            this.states.clear()
+            this.states ++= states
+        }
+
+    /**
+      *
+      * @param client
+      * @param exp
+      * @param states
+      */
+    private def testOk(client: NCModelClient, exp: NCResult, states: State*): 
Unit =
+        set(states*)
+
+        val res = client.ask("x", null, "userId")
+
+        require(res.getBody == exp.getBody)
+
+    /**
+      *
+      * @param client
+      * @param states
+      */
+    private def testFail(client: NCModelClient, states: State*): Unit =
+        set(states*)
+
+        try
+            client.ask("x", null, "userId")
+
+            require(false)
+        catch
+            case e: Throwable => println(s"Expected error: ${e.getMessage}")
+
+    /**
+      *
+      */
+    @Test
+    def test(): Unit = Using.resource(new NCModelClient(MDL)) { client =>
+        testOk(client, RESULT_INTENT)
+        testOk(client, RESULT_RESULT, ResultNotNull)
+        testOk(client, RESULT_CONTEXT, ContextNotNull)
+
+        testFail(client, IntentReject)
+        testFail(client, IntentError)
+        testFail(client, VariantFalse)
+
+        testOk(client, RESULT_REJECTION, IntentReject, RejectionNotNull)
+        testOk(client, RESULT_ERROR, IntentError, ErrorNotNull)
+
+        val threadReset =
+            new Thread("reset-thread"):
+                override def run(): Unit =
+                    Thread.sleep(500)
+                    states.clear()
+
+        threadReset.start()
+
+        testOk(client, RESULT_INTENT, MatchFalse)
+    }

Reply via email to