All Downloads are FREE. Search and download functionalities are using the official Maven repository.

camundala.test.DmnTestRunner.scala Maven / Gradle / Ivy

There is a newer version: 0.6.2
Show newest version
package camundala
package test

import domain.*
import bpmn.*
import camundala.bpmn.{DecisionDmn, Process, ProcessNode}
import org.camunda.bpm.dmn.engine.{DmnDecision, DmnDecisionResult, DmnEngine}
import org.camunda.bpm.dmn.engine.test.DmnEngineRule
import org.camunda.bpm.engine.runtime.ProcessInstance
import org.camunda.bpm.engine.test.ProcessEngineRule
import org.camunda.bpm.engine.test.assertions.bpmn.BpmnAwareTests
import org.camunda.bpm.engine.test.assertions.bpmn.BpmnAwareTests.{assertThat, repositoryService, runtimeService, task}
import org.camunda.bpm.engine.test.mock.Mocks
import org.junit.Assert.{assertEquals, fail}
import org.junit.{Before, Rule}
import org.mockito.MockitoAnnotations
import os.{Path, ResourcePath}
import org.camunda.bpm.engine.variable.VariableMap
import org.camunda.bpm.engine.variable.Variables
import org.camunda.bpm.model.dmn.DmnModelInstance

import java.time.{LocalDateTime, ZonedDateTime}
import java.util.Date
import scala.collection.immutable
import scala.jdk.CollectionConverters.*
import scala.jdk.CollectionConverters.*
trait DmnTestRunner:

  def dmnPath: ResourcePath

  @Rule
  lazy val dmnEngineRule = new DmnEngineRule()

  lazy val dmnEngine: DmnEngine = dmnEngineRule.getDmnEngine

  lazy val dmnInputStream =
    new java.io.ByteArrayInputStream(os.read.bytes(dmnPath))

  def test[
      In <: Product: Encoder: Decoder,
      Out <: Product: Encoder: Decoder
  ](decisionDmn: => DecisionDmn[In, Out]): Unit =
    val variables: VariableMap = Variables.createVariables
    for (k, v) <- decisionDmn.inOutDescr.in.asDmnVars()
    yield variables.putValue(k, v)

    val cDecision: DmnDecision =
      dmnEngine.parseDecision(decisionDmn.decisionDefinitionKey, dmnInputStream)
    val result = dmnEngine.evaluateDecisionTable(cDecision, variables)

    decisionDmn.decisionResultType match
      case DecisionResultType.singleEntry => // SingleEntry
        val resultEntry: Any = result.getSingleEntry
        val expKey = decisionDmn.out.productElementNames.next()
        val expResult = decisionDmn.out.productIterator.next() match
          case e: scala.reflect.Enum => e.toString
          case ldt : LocalDateTime =>
            import java.time.ZoneId
            Date.from(ldt.atZone(ZoneId.systemDefault).toInstant)
          case zdt: ZonedDateTime =>
            Date.from(zdt.toInstant)
          case o => o
        println(s"assert $expKey: $resultEntry == $expResult")
        assert(resultEntry == expResult)
      case DecisionResultType.singleResult => // SingleResult
        val resultEntryMap = result.getSingleResult.getEntryMap.asScala

        val expResult: Seq[(String, Any)] =
          decisionDmn.out.productIterator.next() match
            case p: Product =>
              (p.productElementNames
                .zip(p.productIterator.toSeq map {
                  case e: scala.reflect.Enum => e.toString
                  case o => o
                }))
                .toSeq
            case o => Seq.empty

        assert(expResult.size == resultEntryMap.size)
        for (key, value) <- expResult
        yield
          println(s"assert $key: ${resultEntryMap(key)} == $value")
          assert(resultEntryMap(key) == value)
      case DecisionResultType.collectEntries => // CollectEntries
        val resultList = result.getResultList.asScala
        val expKey = decisionDmn.out.productElementNames.next()
        val expResults = decisionDmn.out.productIterator.next()
        assert(
          expResults.isInstanceOf[Iterable[?]],
          "For DecisionResultType.collectEntries you need to have Iterable[?] object."
        )
        val expResultDmn =
          expResults match
            case seq: Iterable[?] =>
              seq.map {
                case e: scala.reflect.Enum => e.toString
                case v => v
              }.toSeq
            case e => Seq("bad input" -> s"Expected Seq[?], but got $e")

        assert(expResultDmn.size == resultList.size)
        val sortedResult = resultList.flatMap(_.values.asScala.toSeq).sortBy(_.toString)
        val sortedExpected = expResultDmn.sortBy(_.toString)
        for i <- expResultDmn.indices
        yield
          val result = sortedResult(i)
          val expected = sortedExpected(i)
          println(s"assert: $result == $expected (expected)")
          assert(result == expected)

      case DecisionResultType.resultList => // ResultList
        val resultList = result.getResultList.asScala
        val expKey = decisionDmn.out.productElementNames.next()
        val expResults = decisionDmn.out.productIterator.next()

        val expResultDmn = expResults match
          case iterable: Iterable[?] =>
            iterable.map {
              case prod: Product =>
                prod.productElementNames
                  .zip(prod.productIterator)
                  .map {
                    case (k, e: scala.reflect.Enum) => k -> e.toString
                    case k -> o => k -> o
                  }
                  .toMap
              case e => fail(s"Expected Product, but got $e")

            }.toSeq
          case other =>
            fail(
              s"For DecisionResultType.collectEntries you need to have Iterable[?] object. But it was $other"
            )
            Seq.empty

        assert(expResultDmn.size == resultList.size)
        for (expMap, resMap) <- expResultDmn.zip(resultList)
        yield
          println(s"assert $expMap == ${resMap}")
          assert(expMap == resMap.asScala)




© 2015 - 2024 Weber Informatics LLC | Privacy Policy