blob: 706c06414b93fb8de018c71ea336a61408b7e637 [file] [log] [blame]
/*
* 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.annotations.*
import org.apache.nlpcraft.nlp.entity.parser.*
import org.apache.nlpcraft.nlp.entity.parser.semantic.*
import org.apache.nlpcraft.nlp.util.*
import org.junit.jupiter.api.*
import scala.jdk.CollectionConverters.*
import scala.util.Using
/**
*
*/
class NCModelCallbacksSpec:
enum State:
case
MatchFalse, VariantFalse,
ContextNotNull, ResultNotNull, RejectionNotNull, ErrorNotNull,
IntentError, IntentReject
import State.*
private val states = collection.mutable.HashSet.empty[State]
private val RESULT_INTENT = NCResult("result-intent", NCResultType.ASK_RESULT)
private val RESULT_CONTEXT = NCResult("result-context", NCResultType.ASK_RESULT)
private val RESULT_RESULT = NCResult("result-result", NCResultType.ASK_RESULT)
private val RESULT_REJECTION = NCResult("result-rejection", NCResultType.ASK_RESULT)
private val RESULT_ERROR = NCResult("result-error", NCResultType.ASK_RESULT)
private val MDL: NCTestModelAdapter =
new NCTestModelAdapter():
@NCIntent("intent=x term(x)={# == 'x'}")
def intent(ctx: NCContext, 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: NCContext, im: NCIntentMatch): Boolean = getOrElse(MatchFalse, false, true)
override def onVariant(vrn: NCVariant): Boolean = getOrElse(VariantFalse, false, true)
override def onContext(ctx: NCContext): Option[NCResult] = getOrElse(ContextNotNull, Some(RESULT_CONTEXT), None)
override def onResult(ctx: NCContext, im: NCIntentMatch, res: NCResult): Option[NCResult] = getOrElse(ResultNotNull, Some(RESULT_RESULT), None)
override def onRejection(ctx: NCContext, im: Option[NCIntentMatch], e: NCRejection): Option[NCResult] = getOrElse(RejectionNotNull, Some(RESULT_REJECTION), None)
override def onError(ctx: NCContext, e: Throwable): Option[NCResult] = getOrElse(ErrorNotNull, Some(RESULT_ERROR), None)
MDL.pipeline.entParsers += NCTestUtils.mkEnSemanticParser(List(NCSemanticTestElement("x")))
/**
*
* @param s
* @return
*/
private def has(s: State): Boolean = states.synchronized { states.contains(s) }
/**
*
* @param s
* @param v
* @param dtlt
* @tparam T
* @return
*/
private def getOrElse[T](s: State, v: T, dtlt: => T): T = if has(s) then v else dtlt
/**
*
* @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*)
require(client.ask("x", "userId").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)
// To avoid endless loop.
val threadReset =
new Thread("reset-thread"):
override def run(): Unit =
Thread.sleep(500)
states.clear()
threadReset.start()
testOk(client, RESULT_INTENT, MatchFalse)
}