content: /*
   * Copyright 2010-2025 Hyland Software, Inc. and its affiliates.
   *
   * Licensed 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.activiti.core.el;
  
  import static org.assertj.core.api.Assertions.assertThat;
  import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
  
  import jakarta.el.ELException;
  import jakarta.el.PropertyNotFoundException;
  import java.math.BigDecimal;
  import java.util.Collections;
  import java.util.Date;
  import java.util.List;
  import java.util.Map;
  import org.junit.jupiter.api.Test;
  
  public class JuelResolverTest {
  
      @Test
      public void should_returnNull_when_nullExpressionIsPassed() {
          //given
          ExpressionResolver expressionResolver = new JuelExpressionResolver();
  
          //when
          Object value = expressionResolver.resolveExpression(null, Collections.emptyMap(), Object.class);
  
          //then
          assertThat(value).isNull();
      }
  
      @Test
      public void should_returnSameValue_when_StringWithoutJuelExpressionIsPassed() {
          //given
          String expressionString = "string with no JUEL expression";
          ExpressionResolver expressionResolver = new JuelExpressionResolver();
  
          //when
          String value = expressionResolver.resolveExpression(expressionString, Collections.emptyMap(), String.class);
  
          //then
          assertThat(value).isEqualTo(expressionString);
      }
  
      @Test
      public void should_returnStringVariable_when_knownVariableIsReferenced() {
          //given
          Map<String, Object> availableVariables = Collections.singletonMap("name", "jon doe");
          String expressionString = "${name.toString()}";
          ExpressionResolver expressionResolver = new JuelExpressionResolver();
  
          //when
          String value = expressionResolver.resolveExpression(expressionString, availableVariables, String.class);
  
          //then
          assertThat(value).isEqualTo("jon doe");
      }
  
      @Test
      public void should_returnBoolean_when_expressionIsAPredicate() {
          //given
          String expressionString = "${1 > 0}";
          ExpressionResolver expressionResolver = new JuelExpressionResolver();
  
          //when
          boolean value = expressionResolver.resolveExpression(expressionString, Collections.emptyMap(), Boolean.class);
  
          //then
          assertThat(value).isTrue();
      }
  
      @Test
      public void should_throwException_when_unknownVariableIsReferenced() {
          //given
          Map<String, Object> availableVariables = Map.of("name", "jon doe");
          String expressionString = "${nameeee}";
          ExpressionResolver expressionResolver = new JuelExpressionResolver();
  
          //then
          assertThatExceptionOfType(PropertyNotFoundException.class)
              .as("Referencing an unknown variable")
              .isThrownBy(() -> expressionResolver.resolveExpression(expressionString, availableVariables, Object.class))
              .withMessage("Cannot resolve identifier 'nameeee'");
      }
  
      @Test
      public void should_returnDate_when_expressionIsNowFunction() {
          //given
          String expressionString = "${now()}";
          ExpressionResolver expressionResolver = new JuelExpressionResolver();
  
          //when
          Date value = expressionResolver.resolveExpression(expressionString, Collections.emptyMap(), Date.class);
  
          //then
          assertThat(value).isNotNull();
      }
  
      @Test
      public void should_throwException_when_unknownFunctionIsReferenced() {
          //given
          String expressionString = "${current()}";
          ExpressionResolver expressionResolver = new JuelExpressionResolver();
  
          //then
          assertThatExceptionOfType(ELException.class)
              .as("Referencing an unknown function")
              .isThrownBy(() ->
                  expressionResolver.resolveExpression(expressionString, Collections.emptyMap(), Date.class)
              )
              .withMessage("Could not resolve function 'current'");
      }
  
      @Test
      public void should_returnList_when_expressionIsListFunction() {
          //given
          String expressionString = "${list(1,'item',3)}";
          ExpressionResolver expressionResolver = new JuelExpressionResolver();
  
          //when
          List<Object> result = expressionResolver.resolveExpression(
              expressionString,
              Collections.emptyMap(),
              List.class
          );
  
          //then
          assertThat(result).contains(1l, "item", 3l);
      }
  
      @Test
      public void should_resolveExpression_withBigDecimalVariables() {
          //given
          String expressionString = "${bigDecimal1 + bigDecimal2}";
          ExpressionResolver expressionResolver = new JuelExpressionResolver();
  
          BigDecimal bigDecimal1 = new BigDecimal("1.2");
          BigDecimal bigDecimal2 = new BigDecimal("2.3");
          Map<String, Object> variables = Map.of("bigDecimal1", bigDecimal1, "bigDecimal2", bigDecimal2);
  
          //when
          BigDecimal result = expressionResolver.resolveExpression(expressionString, variables, BigDecimal.class);
  
          //then
          assertThat(result).isEqualTo(bigDecimal1.add(bigDecimal2));
      }
  }
  