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 8a63a9e  Tests extended.
8a63a9e is described below

commit 8a63a9e4e07afd727a11beb7a43e9111eb871fe7
Author: Sergey Kamov <skhdlem...@gmail.com>
AuthorDate: Sun Mar 13 13:33:10 2022 +0300

    Tests extended.
---
 .../apache/nlpcraft/examples/time/EchoModel.java   | 10 ++--
 .../examples/lightswitch/LightSwitchRuModel.scala  | 10 ++--
 .../lightswitch/LightSwitchGroovyModel.groovy      | 10 ++--
 .../examples/lightswitch/LightSwitchJavaModel.java | 10 ++--
 .../examples/lightswitch/LightSwitchKotlinModel.kt | 10 ++--
 .../lightswitch/LightSwitchScalaModel.scala        | 10 ++--
 .../apache/nlpcraft/examples/time/TimeModel.java   | 11 ++--
 .../entity/parser/impl/NCNLPEntityParserImpl.scala |  3 +-
 .../internal/impl/NCModelCallbacksSpec.scala       | 21 ++------
 .../internal/impl/NCModelPingPongSpec.scala        |  4 +-
 .../impl/scan/NCModelIntentsInvalidArgsSpec.scala  |  4 +-
 .../nlpcraft/nlp/NCENDefaultPipelineSpec.scala     |  8 +--
 .../apache/nlpcraft/nlp/NCEntityEnricherSpec.scala | 59 ++++++++++++++++++++++
 .../nlpcraft/nlp/NCEntityValidatorSpec.scala       | 55 ++++++++++++++++++++
 .../apache/nlpcraft/nlp/NCTokenEnricherSpec.scala  | 59 ++++++++++++++++++++++
 .../apache/nlpcraft/nlp/NCTokenValidatorSpec.scala | 55 ++++++++++++++++++++
 .../apache/nlpcraft/nlp/NCVariantFilterSpec.scala  | 58 +++++++++++++++++++++
 .../org/apache/nlpcraft/nlp/util/NCTestUtils.scala | 21 +++++++-
 18 files changed, 347 insertions(+), 71 deletions(-)

diff --git 
a/nlpcraft-examples/echo/src/main/java/org/apache/nlpcraft/examples/time/EchoModel.java
 
b/nlpcraft-examples/echo/src/main/java/org/apache/nlpcraft/examples/time/EchoModel.java
index 019d804..127787f 100644
--- 
a/nlpcraft-examples/echo/src/main/java/org/apache/nlpcraft/examples/time/EchoModel.java
+++ 
b/nlpcraft-examples/echo/src/main/java/org/apache/nlpcraft/examples/time/EchoModel.java
@@ -59,11 +59,9 @@ public class EchoModel extends NCModelAdapter {
         m.put("variants", ctx.getVariants());
         m.put("tokens", ctx.getTokens());
 
-        NCResult res = new NCResult();
-
-        res.setType(NCResultType.ASK_RESULT);
-        res.setBody(new GsonBuilder().setPrettyPrinting().create().toJson(m));
-
-        return res;
+        return new NCResult(
+            new GsonBuilder().setPrettyPrinting().create().toJson(m),
+            NCResultType.ASK_RESULT
+        );
     }
 }
diff --git 
a/nlpcraft-examples/lightswitch-ru/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchRuModel.scala
 
b/nlpcraft-examples/lightswitch-ru/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchRuModel.scala
index f3e144b..5350aee 100644
--- 
a/nlpcraft-examples/lightswitch-ru/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchRuModel.scala
+++ 
b/nlpcraft-examples/lightswitch-ru/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchRuModel.scala
@@ -82,9 +82,7 @@ class LightSwitchRuModel extends NCModelAdapter(
         // Add HomeKit, Arduino or other integration here.
 
         // By default - just return a descriptive action string.
-        val res = new NCResult()
-
-        res.setType(NCResultType.ASK_RESULT)
-        res.setBody(s"Lights are [$status] in [${locations.toLowerCase}].")
-
-        res
\ No newline at end of file
+        new NCResult(
+            s"Lights are [$status] in [${locations.toLowerCase}].",
+            NCResultType.ASK_RESULT
+        )
\ No newline at end of file
diff --git 
a/nlpcraft-examples/lightswitch/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchGroovyModel.groovy
 
b/nlpcraft-examples/lightswitch/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchGroovyModel.groovy
index be9e5f1..e6e4733 100644
--- 
a/nlpcraft-examples/lightswitch/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchGroovyModel.groovy
+++ 
b/nlpcraft-examples/lightswitch/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchGroovyModel.groovy
@@ -81,11 +81,9 @@ class LightSwitchGroovyModel extends NCModelAdapter {
         // Add HomeKit, Arduino or other integration here.
 
         // By default - just return a descriptive action string.
-        NCResult res = new NCResult()
-
-        res.type = NCResultType.ASK_RESULT
-        res.body = "Lights are [$status] in [${locations.toLowerCase()}]."
-
-        res
+        new NCResult(
+            "Lights are [$status] in [${locations.toLowerCase()}].",
+            NCResultType.ASK_RESULT
+        )
     }
 }
diff --git 
a/nlpcraft-examples/lightswitch/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchJavaModel.java
 
b/nlpcraft-examples/lightswitch/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchJavaModel.java
index 825639a..68d94a9 100644
--- 
a/nlpcraft-examples/lightswitch/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchJavaModel.java
+++ 
b/nlpcraft-examples/lightswitch/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchJavaModel.java
@@ -86,11 +86,9 @@ public class LightSwitchJavaModel extends NCModelAdapter {
         // Add HomeKit, Arduino or other integration here.
 
         // By default - just return a descriptive action string.
-        NCResult res = new NCResult();
-
-        res.setType(NCResultType.ASK_RESULT);
-        res.setBody("Lights are [" + status + "] in [" + 
locations.toLowerCase() + "].");
-
-        return res;
+        return new NCResult(
+            "Lights are [" + status + "] in [" + locations.toLowerCase() + 
"].",
+            NCResultType.ASK_RESULT
+        );
     }
 }
\ No newline at end of file
diff --git 
a/nlpcraft-examples/lightswitch/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchKotlinModel.kt
 
b/nlpcraft-examples/lightswitch/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchKotlinModel.kt
index 5e3b1d4..aeef339 100644
--- 
a/nlpcraft-examples/lightswitch/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchKotlinModel.kt
+++ 
b/nlpcraft-examples/lightswitch/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchKotlinModel.kt
@@ -84,11 +84,9 @@ class LightSwitchKotlinModel : NCModelAdapter(
         // Add HomeKit, Arduino or other integration here.
 
         // By default - just return a descriptive action string.
-        val res = NCResult()
-
-        res.setType(NCResultType.ASK_RESULT)
-        res.setBody("Lights are [" + status + "] in [" + 
locations.lowercase(Locale.getDefault()) + "].")
-
-        return res
+        return NCResult(
+            "Lights are [" + status + "] in [" + 
locations.lowercase(Locale.getDefault()) + "].",
+            NCResultType.ASK_RESULT
+        )
     }
 }
\ No newline at end of file
diff --git 
a/nlpcraft-examples/lightswitch/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchScalaModel.scala
 
b/nlpcraft-examples/lightswitch/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchScalaModel.scala
index f3a85b6..a3e0f1f 100644
--- 
a/nlpcraft-examples/lightswitch/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchScalaModel.scala
+++ 
b/nlpcraft-examples/lightswitch/src/main/java/org/apache/nlpcraft/examples/lightswitch/LightSwitchScalaModel.scala
@@ -83,9 +83,7 @@ class LightSwitchScalaModel extends NCModelAdapter(
         // Add HomeKit, Arduino or other integration here.
 
         // By default - just return a descriptive action string.
-        val res = new NCResult()
-
-        res.setType(NCResultType.ASK_RESULT)
-        res.setBody(s"Lights are [$status] in [${locations.toLowerCase}].")
-
-        res
+        new NCResult(
+            s"Lights are [$status] in [${locations.toLowerCase}].",
+            NCResultType.ASK_RESULT
+        )
\ No newline at end of file
diff --git 
a/nlpcraft-examples/time/src/main/java/org/apache/nlpcraft/examples/time/TimeModel.java
 
b/nlpcraft-examples/time/src/main/java/org/apache/nlpcraft/examples/time/TimeModel.java
index 09c4295..00358d1 100644
--- 
a/nlpcraft-examples/time/src/main/java/org/apache/nlpcraft/examples/time/TimeModel.java
+++ 
b/nlpcraft-examples/time/src/main/java/org/apache/nlpcraft/examples/time/TimeModel.java
@@ -99,18 +99,15 @@ public class TimeModel extends NCModelAdapter {
         m.put("lon", lon);
         m.put("localTime", ZonedDateTime.now(ZoneId.of(tmz)).format(FMT));
 
-        NCResult res = new NCResult();
-
-        res.setType(NCResultType.ASK_RESULT);
-
         try {
-            res.setBody(new ObjectMapper(new 
YAMLFactory()).writeValueAsString(m));
+            return new NCResult(
+                new ObjectMapper(new YAMLFactory()).writeValueAsString(m),
+                NCResultType.ASK_RESULT
+            );
         }
         catch (JsonProcessingException e) {
             throw new RuntimeException("YAML conversion error.", e);
         }
-
-        return res;
     }
 
     /**
diff --git 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/nlp/entity/parser/impl/NCNLPEntityParserImpl.scala
 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/nlp/entity/parser/impl/NCNLPEntityParserImpl.scala
index 0171bc6..8a49e1b 100644
--- 
a/nlpcraft/src/main/scala/org/apache/nlpcraft/nlp/entity/parser/impl/NCNLPEntityParserImpl.scala
+++ 
b/nlpcraft/src/main/scala/org/apache/nlpcraft/nlp/entity/parser/impl/NCNLPEntityParserImpl.scala
@@ -41,7 +41,8 @@ class NCNLPEntityParserImpl extends NCEntityParser:
                 put(s"$id:text", t.getText)
                 put(s"$id:index", t.getIndex)
                 put(s"$id:startCharIndex", t.getStartCharIndex)
-                put(s"$id:endCharIndex", t.getEndCharIndex)
+
+                t.keysSet().forEach(key => put(s"$id:$key", t.get(key)))
 
                 override val getTokens: JList[NCToken] = 
util.Collections.singletonList(t)
                 override val getRequestId: String = req.getRequestId
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
index 1c08462..b6af4c2 100644
--- 
a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelCallbacksSpec.scala
+++ 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelCallbacksSpec.scala
@@ -42,11 +42,11 @@ class NCModelCallbacksSpec:
 
     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 RESULT_INTENT = new NCResult("result-intent", 
NCResultType.ASK_RESULT)
+    private val RESULT_CONTEXT = new NCResult("result-context", 
NCResultType.ASK_RESULT)
+    private val RESULT_RESULT = new NCResult("result-result", 
NCResultType.ASK_RESULT)
+    private val RESULT_REJECTION = new NCResult("result-rejection", 
NCResultType.ASK_RESULT)
+    private val RESULT_ERROR = new NCResult("result-error", 
NCResultType.ASK_RESULT)
 
     private val MDL: NCModel =
         new NCTestModelAdapter():
@@ -86,17 +86,6 @@ class NCModelCallbacksSpec:
 
     /**
       *
-      * @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
       */
diff --git 
a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelPingPongSpec.scala
 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelPingPongSpec.scala
index 4034fa3..3f49806 100644
--- 
a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelPingPongSpec.scala
+++ 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/NCModelPingPongSpec.scala
@@ -34,9 +34,7 @@ import scala.util.Using
 class NCModelPingPongSpec:
     private var client: NCModelClient = _
 
-    private case class R(resType: NCResultType, txt: String) extends NCResult:
-        this.setType(resType)
-        this.setBody(txt)
+    private case class R(resType: NCResultType, txt: String) extends 
NCResult(txt, resType):
         override def toString: String = s"$resType ($txt)"
 
     private val MDL: NCModel =
diff --git 
a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/scan/NCModelIntentsInvalidArgsSpec.scala
 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/scan/NCModelIntentsInvalidArgsSpec.scala
index ebd5ed5..ac5f7e7 100644
--- 
a/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/scan/NCModelIntentsInvalidArgsSpec.scala
+++ 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/internal/impl/scan/NCModelIntentsInvalidArgsSpec.scala
@@ -78,9 +78,7 @@ class NCModelIntentsInvalidArgsSpec:
 
     private def mkResult0(obj: Any): NCResult =
         println(s"Result body: $obj, class=${obj.getClass}")
-        val res = new NCResult()
-        res.setBody(obj)
-        res
+        new NCResult(obj, NCResultType.ASK_RESULT)
 
     private def processOptInt(opt: Option[Int]): NCResult =
         // Access and cast.
diff --git 
a/nlpcraft/src/test/scala/org/apache/nlpcraft/nlp/NCENDefaultPipelineSpec.scala 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/nlp/NCENDefaultPipelineSpec.scala
index 857a216..e8b7931 100644
--- 
a/nlpcraft/src/test/scala/org/apache/nlpcraft/nlp/NCENDefaultPipelineSpec.scala
+++ 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/nlp/NCENDefaultPipelineSpec.scala
@@ -43,10 +43,10 @@ class NCENDefaultPipelineSpec:
             ): NCResult =
                 val status = if actEnt.getId == "ls:on" then "on" else "off"
                 val locations = if locEnts.isEmpty then "entire house" else 
locEnts.map(_.mkText()).mkString(", ")
-                val res = new NCResult()
-                res.setType(NCResultType.ASK_RESULT)
-                res.setBody(s"Lights are [$status] in 
[${locations.toLowerCase}].")
-                res
+                new NCResult(
+                    s"Lights are [$status] in [${locations.toLowerCase}].",
+                    NCResultType.ASK_RESULT
+                )
 
     @Test
     def test(): Unit =
diff --git 
a/nlpcraft/src/test/scala/org/apache/nlpcraft/nlp/NCEntityEnricherSpec.scala 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/nlp/NCEntityEnricherSpec.scala
new file mode 100644
index 0000000..f5414e4
--- /dev/null
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/nlp/NCEntityEnricherSpec.scala
@@ -0,0 +1,59 @@
+/*
+ * 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.nlp
+
+import org.apache.nlpcraft.*
+import org.apache.nlpcraft.nlp.entity.parser.NCNLPEntityParser
+import org.apache.nlpcraft.nlp.util.NCTestUtils
+import org.junit.jupiter.api.Test
+
+import java.util.List as JList
+import scala.util.Using
+
+/**
+  *
+  */
+class NCEntityEnricherSpec:
+    private def test0(pipeline: NCModelPipeline, ok: Boolean): Unit =
+        val mdl: NCModel = new NCModelAdapter(new NCModelConfig("test.id", 
"Test model", "1.0"), pipeline):
+            @NCIntent("intent=i term(any)={meta_ent('k1') == 'v1'}")
+            def onMatch(): NCResult = new NCResult("OK", 
NCResultType.ASK_RESULT)
+
+        NCTestUtils.askSomething(mdl, ok)
+
+    private def mkBuilder(): NCModelPipelineBuilder =
+        new NCModelPipelineBuilder().
+            withLanguage("EN").
+            //  For intents matching, we have to add at least one entity 
parser.
+            withEntityParser(new NCNLPEntityParser)
+
+    private def mkPipeline(apply: NCModelPipelineBuilder => 
NCModelPipelineBuilder): NCModelPipeline = apply(mkBuilder()).build()
+
+    @Test
+    def test(): Unit =
+        test0(
+            mkBuilder().build(),
+            false
+        )
+
+        test0(
+            mkPipeline(_.withEntityEnricher(
+                (req: NCRequest, cfg: NCModelConfig, ents: JList[NCEntity]) => 
ents.forEach(_.put("k1", "v1"))
+            )),
+            true
+        )
\ No newline at end of file
diff --git 
a/nlpcraft/src/test/scala/org/apache/nlpcraft/nlp/NCEntityValidatorSpec.scala 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/nlp/NCEntityValidatorSpec.scala
new file mode 100644
index 0000000..de6070f
--- /dev/null
+++ 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/nlp/NCEntityValidatorSpec.scala
@@ -0,0 +1,55 @@
+/*
+ * 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.nlp
+
+import org.apache.nlpcraft.*
+import org.apache.nlpcraft.nlp.util.NCTestUtils
+import org.junit.jupiter.api.Test
+
+import java.util.List as JList
+import scala.util.Using
+
+/**
+  *
+  */
+class NCEntityValidatorSpec:
+    private def test0(pipeline: NCModelPipeline, ok: Boolean): Unit =
+        val mdl: NCModel = new NCModelAdapter(new NCModelConfig("test.id", 
"Test model", "1.0"), pipeline):
+            override def onContext(ctx: NCContext): NCResult = new 
NCResult("OK", NCResultType.ASK_RESULT)
+
+        NCTestUtils.askSomething(mdl, ok)
+
+    private def mkBuilder(): NCModelPipelineBuilder = new 
NCModelPipelineBuilder().withLanguage("EN")
+    private def mkPipeline(apply: NCModelPipelineBuilder => 
NCModelPipelineBuilder): NCModelPipeline = apply(mkBuilder()).build()
+
+    @Test
+    def test(): Unit =
+        test0(
+            mkBuilder().build(),
+            true
+        )
+
+        test0(
+            mkPipeline(_.withEntityValidator((req: NCRequest, cfg: 
NCModelConfig, ents: JList[NCEntity]) => throw new RuntimeException("Runtime 
Exception"))),
+            false
+        )
+
+        test0(
+            mkPipeline(_.withEntityValidator((req: NCRequest, cfg: 
NCModelConfig, ents: JList[NCEntity]) => throw new NCException("Checked 
Exception"))),
+            false
+        )
\ No newline at end of file
diff --git 
a/nlpcraft/src/test/scala/org/apache/nlpcraft/nlp/NCTokenEnricherSpec.scala 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/nlp/NCTokenEnricherSpec.scala
new file mode 100644
index 0000000..485369d
--- /dev/null
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/nlp/NCTokenEnricherSpec.scala
@@ -0,0 +1,59 @@
+/*
+ * 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.nlp
+
+import org.apache.nlpcraft.*
+import org.apache.nlpcraft.nlp.entity.parser.NCNLPEntityParser
+import org.apache.nlpcraft.nlp.util.NCTestUtils
+import org.junit.jupiter.api.Test
+
+import java.util.List as JList
+import scala.util.Using
+
+/**
+  *
+  */
+class NCTokenEnricherSpec:
+    private def test0(pipeline: NCModelPipeline, ok: Boolean): Unit =
+        val mdl: NCModel = new NCModelAdapter(new NCModelConfig("test.id", 
"Test model", "1.0"), pipeline):
+            @NCIntent("intent=i term(any)={meta_ent('nlp:token:k1') == 'v1'}")
+            def onMatch(): NCResult = new NCResult("OK", 
NCResultType.ASK_RESULT)
+
+        NCTestUtils.askSomething(mdl, ok)
+
+    private def mkBuilder(): NCModelPipelineBuilder =
+        new NCModelPipelineBuilder().
+            withLanguage("EN").
+            //  For intents matching, we have to add at least one entity 
parser.
+            withEntityParser(new NCNLPEntityParser)
+
+    private def mkPipeline(apply: NCModelPipelineBuilder => 
NCModelPipelineBuilder): NCModelPipeline = apply(mkBuilder()).build()
+
+    @Test
+    def test(): Unit =
+        test0(
+            mkBuilder().build(),
+            false
+        )
+
+        test0(
+            mkPipeline(_.withTokenEnricher(
+                (req: NCRequest, cfg: NCModelConfig, toks: JList[NCToken]) => 
toks.forEach(_.put("k1", "v1"))
+            )),
+            true
+        )
\ No newline at end of file
diff --git 
a/nlpcraft/src/test/scala/org/apache/nlpcraft/nlp/NCTokenValidatorSpec.scala 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/nlp/NCTokenValidatorSpec.scala
new file mode 100644
index 0000000..e7b0a4a
--- /dev/null
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/nlp/NCTokenValidatorSpec.scala
@@ -0,0 +1,55 @@
+/*
+ * 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.nlp
+
+import org.apache.nlpcraft.*
+import org.apache.nlpcraft.nlp.util.NCTestUtils
+import org.junit.jupiter.api.Test
+
+import java.util.List as JList
+import scala.util.Using
+
+/**
+  *
+  */
+class NCTokenValidatorSpec:
+    private def test0(pipeline: NCModelPipeline, ok: Boolean): Unit =
+        val mdl: NCModel = new NCModelAdapter(new NCModelConfig("test.id", 
"Test model", "1.0"), pipeline):
+            override def onContext(ctx: NCContext): NCResult = new 
NCResult("OK", NCResultType.ASK_RESULT)
+
+        NCTestUtils.askSomething(mdl, ok)
+
+    private def mkBuilder(): NCModelPipelineBuilder = new 
NCModelPipelineBuilder().withLanguage("EN")
+    private def mkPipeline(apply: NCModelPipelineBuilder => 
NCModelPipelineBuilder): NCModelPipeline = apply(mkBuilder()).build()
+
+    @Test
+    def test(): Unit =
+        test0(
+            mkBuilder().build(),
+            true
+        )
+
+        test0(
+            mkPipeline(_.withTokenValidator((req: NCRequest, cfg: 
NCModelConfig, toks: JList[NCToken]) => throw new RuntimeException("Runtime 
Exception"))),
+            false
+        )
+
+        test0(
+            mkPipeline(_.withTokenValidator((req: NCRequest, cfg: 
NCModelConfig, toks: JList[NCToken]) => throw new NCException("Checked 
Exception"))),
+            false
+        )
diff --git 
a/nlpcraft/src/test/scala/org/apache/nlpcraft/nlp/NCVariantFilterSpec.scala 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/nlp/NCVariantFilterSpec.scala
new file mode 100644
index 0000000..a9274be
--- /dev/null
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/nlp/NCVariantFilterSpec.scala
@@ -0,0 +1,58 @@
+/*
+ * 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.nlp
+
+import org.apache.nlpcraft.*
+import org.apache.nlpcraft.nlp.entity.parser.NCNLPEntityParser
+import org.apache.nlpcraft.nlp.util.NCTestUtils
+import org.junit.jupiter.api.Test
+
+import java.util
+import java.util.List as JList
+import scala.util.Using
+
+/**
+  *
+  */
+class NCVariantFilterSpec:
+    private def test0(pipeline: NCModelPipeline, ok: Boolean): Unit =
+        val mdl: NCModel = new NCModelAdapter(new NCModelConfig("test.id", 
"Test model", "1.0"), pipeline):
+            @NCIntent("intent=i term(any)={true}")
+            def onMatch(): NCResult = new NCResult("OK", 
NCResultType.ASK_RESULT)
+
+        NCTestUtils.askSomething(mdl, ok)
+
+    private def mkBuilder(): NCModelPipelineBuilder =
+        new NCModelPipelineBuilder().
+            withLanguage("EN").
+            //  For intents matching, we have to add at least one entity 
parser.
+            withEntityParser(new NCNLPEntityParser)
+
+    private def mkPipeline(apply: NCModelPipelineBuilder => 
NCModelPipelineBuilder): NCModelPipeline = apply(mkBuilder()).build()
+
+    @Test
+    def test(): Unit =
+        test0(
+            mkBuilder().build(),
+            true
+        )
+
+        test0(
+            mkPipeline(_.withVariantFilter((req: NCRequest, cfg: 
NCModelConfig, variants: JList[NCVariant]) => util.Collections.emptyList())),
+            false
+        )
\ No newline at end of file
diff --git 
a/nlpcraft/src/test/scala/org/apache/nlpcraft/nlp/util/NCTestUtils.scala 
b/nlpcraft/src/test/scala/org/apache/nlpcraft/nlp/util/NCTestUtils.scala
index 0c83ab1..342dca6 100644
--- a/nlpcraft/src/test/scala/org/apache/nlpcraft/nlp/util/NCTestUtils.scala
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/nlp/util/NCTestUtils.scala
@@ -24,6 +24,7 @@ import java.util
 import java.util.List as JList
 import scala.jdk.CollectionConverters.*
 import scala.jdk.OptionConverters.RichOptional
+import scala.util.Using
 
 /**
   *
@@ -75,4 +76,22 @@ object NCTestUtils:
                 mkProps(e)
             )
 
-        tbl.print(s"Request: $req")
\ No newline at end of file
+        tbl.print(s"Request: $req")
+
+    /**
+      *
+      * @param mdl
+      * @param expectedOk
+      */
+    def askSomething(mdl: NCModel, expectedOk: Boolean): Unit =
+        Using.resource(new NCModelClient(mdl)) { client =>
+            def ask(): NCResult = client.ask("test", null, "userId")
+
+            if expectedOk then
+                println(ask().getBody)
+            else
+                try
+                    ask()
+                    require(false)
+                catch case e: Exception => println(s"Expected error: 
${e.getMessage}")
+        }
\ No newline at end of file

Reply via email to