You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nlpcraft.apache.org by se...@apache.org on 2021/03/23 11:13:22 UTC

[incubator-nlpcraft] 02/04: WIP.

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

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

commit 27b900f200cca2470eaaa9ea23150628eace6dbb
Author: Sergey Kamov <sk...@gmail.com>
AuthorDate: Tue Mar 23 13:03:25 2021 +0300

    WIP.
---
 .../idl/compiler/NCIdlCompilerSpecFunctions.scala  | 192 ---------------------
 .../idl/compiler/functions/NCIdlFunctions.scala    | 185 ++++++++++++++++++++
 .../compiler/functions/NCIdlFunctionsColl.scala    |  36 ++++
 .../compiler/functions/NCIdlFunctionsCompany.scala |  76 ++++++++
 .../compiler/functions/NCIdlFunctionsDate.scala    |  34 ++++
 .../compiler/functions/NCIdlFunctionsMath.scala    |  33 ++++
 .../compiler/functions/NCIdlFunctionsRequest.scala |  34 ++++
 .../compiler/functions/NCIdlFunctionsStat.scala    |  32 ++++
 .../compiler/functions/NCIdlFunctionsStrings.scala |  36 ++++
 .../compiler/functions/NCIdlFunctionsToken.scala   |  35 ++++
 .../compiler/functions/NCIdlFunctionsUser.scala    |  72 ++++++++
 11 files changed, 573 insertions(+), 192 deletions(-)

diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/NCIdlCompilerSpecFunctions.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/NCIdlCompilerSpecFunctions.scala
deleted file mode 100644
index 5f3c687..0000000
--- a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/NCIdlCompilerSpecFunctions.scala
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * 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
- *
- *      http://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.model.intent.idl.compiler
-
-import org.apache.nlpcraft.model.intent.compiler.{NCIdlCompiler, NCIdlCompilerGlobal}
-import org.apache.nlpcraft.model.intent.{NCIdlContext, NCIdlFunction, NCIdlStackItem}
-import org.apache.nlpcraft.model.{NCModel, NCModelView, NCToken}
-import org.junit.jupiter.api.{BeforeEach, Test}
-
-import java.util
-import java.util.{Collections, UUID}
-import scala.collection.JavaConverters._
-
-/**
-  * Tests for IDL functions.
-  */
-class NCIdlCompilerSpecFunctions {
-    private final val MODEL_ID = "test.mdl.id"
-
-    private final val MODEL: NCModel = new NCModel {
-        override val getId: String = MODEL_ID
-        override val getName: String = MODEL_ID
-        override val getVersion: String = "1.0.0"
-
-        override def getOrigin: String = "test"
-    }
-
-    private final val DUMMY_CTX: NCIdlContext = NCIdlContext(req = null)
-
-    @BeforeEach
-    def before(): Unit = NCIdlCompilerGlobal.clearCache(MODEL_ID)
-
-    import BoolFunc._
-
-    case class BoolFunc(func: NCIdlFunction, token: NCToken, result: Boolean) {
-        override def toString: String =
-            s"Boolean function [" +
-                s"token=${t2s(token)}, " +
-                s"function=$func, " +
-                s"expected=$result" +
-                s"]"
-    }
-
-    object BoolFunc {
-        private def t2s(t: NCToken) = s"${t.getOriginalText} (${t.getId})"
-
-        private def mkToken(
-            id: String = null,
-            value: String = null,
-            txt: String = null,
-            start: Int = 0,
-            end: Int = 0,
-            meta: Map[String, AnyRef] = Map.empty[String, AnyRef]
-        ): NCToken = {
-            val map = new util.HashMap[String, AnyRef]
-
-            map.putAll(meta.asJava)
-
-            def nvl(v: String): String = if (v != null) v else "(not set)"
-
-            map.put("nlpcraft:nlp:origtext", nvl(txt))
-
-            new NCToken {
-                override def getModel: NCModelView = MODEL
-                override def getServerRequestId: String = UUID.randomUUID().toString
-                override def getId: String = nvl(id)
-                override def getParentId: String = null
-                override def getAncestors: util.List[String] = Collections.emptyList()
-                override def getPartTokens: util.List[NCToken] = Collections.emptyList()
-                override def getAliases: util.Set[String] = Collections.emptySet()
-                override def getValue: String = value
-                override def getGroups: util.List[String] = Collections.singletonList(id)
-                override def getStartCharIndex: Int = start
-                override def getEndCharIndex: Int = end
-                override def isAbstract: Boolean = false
-                override def getMetadata: util.Map[String, AnyRef] = map
-            }
-        }
-
-        private def mkFunc(term: String): NCIdlFunction = {
-            val intents = NCIdlCompiler.compileIntents(s"intent=i term(t)={$term}", MODEL, MODEL_ID)
-
-            require(intents.size == 1)
-
-            val intent = intents.head
-
-            require(intent.terms.size == 1)
-
-            new NCIdlFunction() {
-                override def apply(v1: NCToken, v2: NCIdlContext): NCIdlStackItem = intent.terms.head.pred.apply(v1, v2)
-                override def toString(): String = s"Function, based on term: $term"
-            }
-        }
-
-        def apply(boolCondition: String, token: String, result: Boolean): BoolFunc =
-            BoolFunc(func = mkFunc(boolCondition), token = mkToken(token), result = result)
-
-        def apply(boolCondition: String, tokenId: String): BoolFunc =
-            BoolFunc(func = mkFunc(boolCondition), token = mkToken(tokenId), result = true)
-
-        def apply(boolCondition: String, token: NCToken, result: Boolean): BoolFunc =
-            BoolFunc(func = mkFunc(boolCondition), token, result = result)
-
-        def apply(bool: String): BoolFunc =
-            BoolFunc(func = mkFunc(bool), mkToken(), result = true)
-    }
-
-    private def test(funcs: BoolFunc*): Unit =
-        for ((func, idx) ← funcs.zipWithIndex) {
-            val res =
-                try
-                    func.func.apply(func.token, DUMMY_CTX).value
-                catch {
-                    case e: Exception ⇒ throw new Exception(s"Execution error [index=$idx, testFunc=$func]", e)
-                }
-
-                res match {
-                    case b: java.lang.Boolean ⇒
-                        require(b == func.result,
-                            s"Unexpected result [" +
-                                s"index=$idx, " +
-                                s"testFunc=$func, " +
-                                s"expected=${func.result}, " +
-                                s"result=$res" +
-                                s"]"
-                        )
-                    case _ ⇒
-                        require(requirement = false,
-                            s"Unexpected result type [" +
-                                s"index=$idx, " +
-                                s"testFunc=$func, " +
-                                s"expected=${func.result}, " +
-                                s"result=$res" +
-                                s"]"
-                        )
-                }
-
-        }
-
-    @Test
-    def test(): Unit = {
-        val now = System.currentTimeMillis()
-
-        test(
-            BoolFunc(boolCondition = "id() == 'a'", tokenId = "a"),
-
-            // Math.
-            // BoolFunc(boolCondition = "sin(90.0) == 0")
-            // BoolFunc(boolCondition = "rand() < 1")
-
-            // String.
-            BoolFunc(bool = "trim(' a b  ') == 'a b'"),
-            BoolFunc(bool = "strip(' a b  ') == 'a b'"),
-            BoolFunc(bool = "uppercase('aB') == 'AB'"),
-            BoolFunc(bool = "lowercase('aB') == 'ab'"),
-            BoolFunc(bool = "is_num('a') == false"),
-            BoolFunc(bool = "is_num('1') == true"),
-
-            // Statistical.
-            // BoolFunc(boolCondition = "max(list(1, 2, 3)) == 3"),
-            // BoolFunc(boolCondition = "min(list(1, 2, 3)) == 1")
-
-            // Collection.
-            // BoolFunc(boolCondition = "first(list(1, 2, 3)) == 1"),
-            // BoolFunc(boolCondition = "last(list(1, 2, 3)) == 3")
-            BoolFunc(bool = "is_empty(list()) == true"),
-            BoolFunc(bool = "is_empty(list(1)) == false"),
-            BoolFunc(bool = "non_empty(list()) == false"),
-            BoolFunc(bool = "non_empty(list(1)) == true"),
-
-            // Date-time functions.
-
-
-            BoolFunc(bool = s"now() - $now < 1000")
-        )
-    }
-}
diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctions.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctions.scala
new file mode 100644
index 0000000..b65dc4c
--- /dev/null
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctions.scala
@@ -0,0 +1,185 @@
+/*
+ * 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
+ *
+ *      http://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.model.intent.idl.compiler.functions
+
+import org.apache.nlpcraft.model.intent.compiler.{NCIdlCompiler, NCIdlCompilerGlobal}
+import org.apache.nlpcraft.model.intent.{NCIdlContext, NCIdlFunction, NCIdlStackItem}
+import org.apache.nlpcraft.model.{NCCompany, NCModel, NCModelView, NCRequest, NCToken, NCUser}
+import org.junit.jupiter.api.BeforeEach
+
+import java.util
+import java.util.{Collections, Optional}
+import scala.collection.JavaConverters._
+
+/**
+  * Tests for IDL functions.
+  */
+private[functions] trait NCIdlFunctions {
+    private final val MODEL_ID = "test.mdl.id"
+
+    private final val MODEL: NCModel = new NCModel {
+        override val getId: String = MODEL_ID
+        override val getName: String = MODEL_ID
+        override val getVersion: String = "1.0.0"
+
+        override def getOrigin: String = "test"
+    }
+
+    @BeforeEach
+    def before(): Unit = NCIdlCompilerGlobal.clearCache(MODEL_ID)
+
+    import BoolFunc._
+
+    case class BoolFunc(
+        func: NCIdlFunction,
+        token: NCToken,
+        idlContext: NCIdlContext
+    ) {
+        override def toString: String =
+            s"Boolean function [" +
+                s"token=${t2s(token)}, " +
+                s"function=$func" +
+                s"]"
+    }
+
+    object BoolFunc {
+        private def t2s(t: NCToken) = s"${t.getOriginalText} (${t.getId})"
+
+        private def mkFunc(term: String): NCIdlFunction = {
+            val intents = NCIdlCompiler.compileIntents(s"intent=i term(t)={$term}", MODEL, MODEL_ID)
+
+            require(intents.size == 1)
+
+            val intent = intents.head
+
+            require(intent.terms.size == 1)
+
+            new NCIdlFunction() {
+                override def apply(v1: NCToken, v2: NCIdlContext): NCIdlStackItem = intent.terms.head.pred.apply(v1, v2)
+                override def toString(): String = s"Function, based on term: $term"
+            }
+        }
+
+        def apply(bool: String, tokenId: String): BoolFunc =
+            BoolFunc(func = mkFunc(bool), token = mkToken(tokenId), idlContext = mkIdlContext())
+
+        def apply(bool: String, token: NCToken): BoolFunc =
+            BoolFunc(func = mkFunc(bool), token, idlContext = mkIdlContext())
+
+        def apply(bool: String, idlContext: NCIdlContext): BoolFunc =
+            BoolFunc(func = mkFunc(bool), mkToken(), idlContext)
+
+        def apply(bool: String): BoolFunc =
+            BoolFunc(func = mkFunc(bool), mkToken(), idlContext = mkIdlContext())
+    }
+
+    protected def mkIdlContext(
+        usr: NCUser = null,
+        comp: NCCompany = null,
+        srvReqId: String = null,
+        normTxt: String = null,
+        recTimestamp: Long = 0,
+        remAddress: String = null,
+        clientAgent: String = null,
+        reqData: Map[String, AnyRef] = Map.empty[String, AnyRef]
+    ): NCIdlContext = {
+        NCIdlContext(
+            req =
+                new NCRequest() {
+                    override def getUser: NCUser = usr
+                    override def getCompany: NCCompany = comp
+                    override def getServerRequestId: String = srvReqId
+                    override def getNormalizedText: String = normTxt
+                    override def getReceiveTimestamp: Long = recTimestamp
+                    override def getRemoteAddress: Optional[String] = Optional.ofNullable(remAddress)
+                    override def getClientAgent: Optional[String] = Optional.ofNullable(clientAgent)
+                    override def getRequestData: util.Map[String, AnyRef] = reqData.asJava
+                }
+        )
+    }
+
+    protected def mkToken(
+        id: String = null,
+        srvReqId: String = null,
+        parentId: String = null,
+        value: String = null,
+        txt: String = null,
+        start: Int = 0,
+        end: Int = 0,
+        groups: Seq[String] = Seq.empty,
+        ancestors: Seq[String] = Seq.empty,
+        aliases: Set[String] = Set.empty,
+        partTokens: Seq[NCToken] = Seq.empty,
+        meta: Map[String, AnyRef] = Map.empty[String, AnyRef]
+    ): NCToken = {
+        val map = new util.HashMap[String, AnyRef]
+
+        map.putAll(meta.asJava)
+
+        map.put("nlpcraft:nlp:origtext", txt)
+        map.put("nlpcraft:nlp:origtext", txt)
+
+        new NCToken {
+            override def getModel: NCModelView = MODEL
+
+            override def getServerRequestId: String = srvReqId
+            override def getId: String = id
+            override def getParentId: String = parentId
+            override def getAncestors: util.List[String] = ancestors.asJava
+            override def getPartTokens: util.List[NCToken] = partTokens.asJava
+            override def getAliases: util.Set[String] = aliases.asJava
+            override def getValue: String = value
+            override def getGroups: util.List[String] =
+                if (groups.isEmpty && id != null) Collections.singletonList(id) else groups.asJava
+            override def getStartCharIndex: Int = start
+            override def getEndCharIndex: Int = end
+            override def isAbstract: Boolean = false
+            override def getMetadata: util.Map[String, AnyRef] = map
+        }
+    }
+
+    protected def test(funcs: BoolFunc*): Unit =
+        for ((func, idx) ← funcs.zipWithIndex) {
+            val res =
+                try
+                    func.func.apply(func.token, func.idlContext).value
+                catch {
+                    case e: Exception ⇒ throw new Exception(s"Execution error [index=$idx, testFunc=$func]", e)
+                }
+
+            res match {
+                case b: java.lang.Boolean ⇒
+                    require(b,
+                        s"Unexpected result [" +
+                            s"index=$idx, " +
+                            s"testFunc=$func, " +
+                            s"result=$res" +
+                            s"]"
+                    )
+                case _ ⇒
+                    require(requirement = false,
+                        s"Unexpected result type [" +
+                            s"index=$idx, " +
+                            s"testFunc=$func, " +
+                            s"result=$res" +
+                            s"]"
+                    )
+            }
+
+        }
+}
diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctionsColl.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctionsColl.scala
new file mode 100644
index 0000000..0fe5523
--- /dev/null
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctionsColl.scala
@@ -0,0 +1,36 @@
+/*
+ * 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
+ *
+ *      http://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.model.intent.idl.compiler.functions
+
+import org.junit.jupiter.api.Test
+
+/**
+  * Tests for IDL functions.
+  */
+class NCIdlFunctionsColl extends NCIdlFunctions {
+    @Test
+    def test(): Unit =
+        test(
+            // BoolFunc(boolCondition = "first(list(1, 2, 3)) == 1"),
+            // BoolFunc(boolCondition = "last(list(1, 2, 3)) == 3")
+            BoolFunc(bool = "is_empty(list()) == true"),
+            BoolFunc(bool = "is_empty(list(1)) == false"),
+            BoolFunc(bool = "non_empty(list()) == false"),
+            BoolFunc(bool = "non_empty(list(1)) == true")
+        )
+}
diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctionsCompany.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctionsCompany.scala
new file mode 100644
index 0000000..35976ab
--- /dev/null
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctionsCompany.scala
@@ -0,0 +1,76 @@
+/*
+ * 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
+ *
+ *      http://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.model.intent.idl.compiler.functions
+
+import org.apache.nlpcraft.model.NCCompany
+import org.apache.nlpcraft.server.rest.NCRestSpec
+import org.junit.jupiter.api.{BeforeEach, Test}
+
+import java.util
+import java.util.Optional
+
+/**
+  * Tests for IDL functions.
+  */
+class NCIdlFunctionsCompany extends NCRestSpec with NCIdlFunctions {
+    private var company: NCCompany = _
+
+    @BeforeEach
+    def setCompany(): Unit = {
+        var compName: String = null
+        var compWebsite: String = null
+        var compCountry: String = null
+        var compRegion: String = null
+        var compCity: String = null
+        var compAddress: String = null
+        var compPostalCode: String = null
+        var props: java.util.Map[String, AnyRef] = null
+
+        post("company/get")(
+            ("$.name", (v: String) ⇒ compName = v),
+            ("$.website", (v: String) ⇒ compWebsite = v),
+            ("$.country", (v: String) ⇒ compCountry = v),
+            ("$.region", (v: String) ⇒ compRegion = v),
+            ("$.city", (v: String) ⇒ compCity = v),
+            ("$.address", (v: String) ⇒ compAddress = v),
+            ("$.postalCode", (v: String) ⇒ compPostalCode = v),
+            ("$.properties", (v: java.util.Map[String, AnyRef]) ⇒ props = v)
+        )
+
+        company = new NCCompany() {
+            override def getId: Long = -1  // TODO: No REST API data
+            override def getName: String = compName
+            override def getWebsite: Optional[String] = Optional.ofNullable(compWebsite)
+            override def getCountry: Optional[String] = Optional.ofNullable(compCountry)
+            override def getRegion: Optional[String] = Optional.ofNullable(compRegion)
+            override def getCity: Optional[String] = Optional.ofNullable(compCity)
+            override def getAddress: Optional[String] = Optional.ofNullable(compAddress)
+            override def getPostalCode: Optional[String] = Optional.ofNullable(compPostalCode)
+            override def getMetadata: util.Map[String, AnyRef] = props
+        }
+    }
+
+    @Test
+    def test(): Unit = {
+        val ctx = mkIdlContext(comp = company)
+
+        test(
+            BoolFunc(s"comp_name() == '${company.getName}'", ctx)
+        )
+    }
+}
diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctionsDate.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctionsDate.scala
new file mode 100644
index 0000000..34cbe19
--- /dev/null
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctionsDate.scala
@@ -0,0 +1,34 @@
+/*
+ * 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
+ *
+ *      http://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.model.intent.idl.compiler.functions
+
+import org.junit.jupiter.api.Test
+
+/**
+  * Tests for IDL functions.
+  */
+class NCIdlFunctionsDate extends NCIdlFunctions {
+    @Test
+    def test(): Unit = {
+        val now = System.currentTimeMillis()
+
+        test(
+            BoolFunc(bool = s"now() - $now < 1000")
+        )
+    }
+}
diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctionsMath.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctionsMath.scala
new file mode 100644
index 0000000..cb7da1b
--- /dev/null
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctionsMath.scala
@@ -0,0 +1,33 @@
+/*
+ * 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
+ *
+ *      http://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.model.intent.idl.compiler.functions
+
+import org.junit.jupiter.api.Test
+
+/**
+  * Tests for IDL functions.
+  */
+class NCIdlFunctionsMath extends NCIdlFunctions {
+    @Test
+    def test(): Unit =
+        test(
+            BoolFunc(bool = "sin(90.0) == 0"),
+            BoolFunc(bool = "sin(90) == 0"),
+            BoolFunc(bool = "rand() < 1")
+        )
+}
diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctionsRequest.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctionsRequest.scala
new file mode 100644
index 0000000..d60c2ca
--- /dev/null
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctionsRequest.scala
@@ -0,0 +1,34 @@
+/*
+ * 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
+ *
+ *      http://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.model.intent.idl.compiler.functions
+
+import org.junit.jupiter.api.Test
+
+/**
+  * Tests for IDL functions.
+  */
+class NCIdlFunctionsRequest extends NCIdlFunctions {
+    @Test
+    def test(): Unit = {
+        val ctx = mkIdlContext(srvReqId = "req.id")
+
+        test(
+            BoolFunc(s"req_id() == '${ctx.req.getServerRequestId}'", ctx)
+        )
+    }
+}
diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctionsStat.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctionsStat.scala
new file mode 100644
index 0000000..d6aeabc
--- /dev/null
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctionsStat.scala
@@ -0,0 +1,32 @@
+/*
+ * 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
+ *
+ *      http://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.model.intent.idl.compiler.functions
+
+import org.junit.jupiter.api.Test
+
+/**
+  * Tests for IDL functions.
+  */
+class NCIdlFunctionsStat extends NCIdlFunctions {
+    @Test
+    def test(): Unit =
+        test(
+             BoolFunc(bool = "max(list(1, 2, 3)) == 3"),
+             BoolFunc(bool = "min(list(1, 2, 3)) == 1")
+        )
+}
diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctionsStrings.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctionsStrings.scala
new file mode 100644
index 0000000..c2fd3b7
--- /dev/null
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctionsStrings.scala
@@ -0,0 +1,36 @@
+/*
+ * 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
+ *
+ *      http://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.model.intent.idl.compiler.functions
+
+import org.junit.jupiter.api.Test
+
+/**
+  * Tests for IDL functions.
+  */
+class NCIdlFunctionsStrings extends NCIdlFunctions {
+    @Test
+    def test(): Unit =
+        test(
+            BoolFunc(bool = "trim(' a b  ') == 'a b'"),
+            BoolFunc(bool = "strip(' a b  ') == 'a b'"),
+            BoolFunc(bool = "uppercase('aB') == 'AB'"),
+            BoolFunc(bool = "lowercase('aB') == 'ab'"),
+            BoolFunc(bool = "is_num('a') == false"),
+            BoolFunc(bool = "is_num('1') == true")
+        )
+}
diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctionsToken.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctionsToken.scala
new file mode 100644
index 0000000..1f5a823
--- /dev/null
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctionsToken.scala
@@ -0,0 +1,35 @@
+/*
+ * 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
+ *
+ *      http://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.model.intent.idl.compiler.functions
+
+import org.junit.jupiter.api.Test
+
+/**
+  * Tests for IDL functions.
+  */
+class NCIdlFunctionsToken extends NCIdlFunctions {
+    @Test
+    def test(): Unit =
+        test(
+            BoolFunc(bool = "id() == 'a'", "a"),
+            BoolFunc(
+                bool = "parent() == 'a'",
+                mkToken(parentId = "a")
+            )
+        )
+}
diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctionsUser.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctionsUser.scala
new file mode 100644
index 0000000..3c4560b
--- /dev/null
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/idl/compiler/functions/NCIdlFunctionsUser.scala
@@ -0,0 +1,72 @@
+/*
+ * 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
+ *
+ *      http://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.model.intent.idl.compiler.functions
+
+import org.apache.nlpcraft.model.NCUser
+import org.apache.nlpcraft.server.rest.NCRestSpec
+import org.junit.jupiter.api.{BeforeEach, Test}
+
+import java.util
+import java.util.Optional
+
+/**
+  * Tests for IDL functions.
+  */
+class NCIdlFunctionsUser extends NCRestSpec with NCIdlFunctions {
+    private var usr: NCUser = _
+
+    @BeforeEach
+    def setCompany(): Unit = {
+        var firstName: String = null
+        var lastName: String = null
+        var avatarUrl: String = null
+        var email: String = null
+        var adm: Boolean = false
+        var props: java.util.Map[String, AnyRef] = null
+
+        // Checks updated.
+        post("user/get")(
+            ("$.firstName", (v: String) ⇒ firstName = v),
+            ("$.lastName", (v: String) ⇒ lastName = v),
+            ("$.email", (v: String) ⇒ email = v),
+            ("$.avatarUrl", (v: String) ⇒ avatarUrl = v),
+            ("$.isAdmin", (v: Boolean) ⇒ adm = v),
+            ("$.properties", (v: java.util.Map[String, AnyRef]) ⇒ props = v)
+        )
+
+        usr = new NCUser {
+            override def getId: Long = -1  // TODO: No REST API data
+            override def getFirstName: Optional[String] = Optional.ofNullable(firstName)
+            override def getLastName: Optional[String] = Optional.ofNullable(lastName)
+            override def getEmail: Optional[String] = Optional.ofNullable(email)
+            override def getAvatarUrl: Optional[String] = Optional.ofNullable(avatarUrl)
+            override def isAdmin: Boolean = adm
+            override def getSignupTimestamp: Long = -1 // TODO: No REST API data
+            override def getMetadata: util.Map[String, AnyRef] = props
+        }
+    }
+
+    @Test
+    def test(): Unit =  {
+        val ctx = mkIdlContext(usr = usr)
+
+        test(
+            BoolFunc(s"user_email() == '${usr.getEmail.get()}'", ctx)
+        )
+    }
+}