diff --git a/libraries-7/pom.xml b/libraries-7/pom.xml index 48a96b4b6cbe..ea91ca21b271 100644 --- a/libraries-7/pom.xml +++ b/libraries-7/pom.xml @@ -63,6 +63,11 @@ webmagic-extension 1.0.3 + + org.mvel + mvel2 + ${mvel.version} + @@ -104,6 +109,7 @@ 2024.1.20 47 5.5.0 + 2.5.2.Final diff --git a/libraries-7/src/main/java/com/baeldung/mvel/model/Employee.java b/libraries-7/src/main/java/com/baeldung/mvel/model/Employee.java new file mode 100644 index 000000000000..277cb639dbc7 --- /dev/null +++ b/libraries-7/src/main/java/com/baeldung/mvel/model/Employee.java @@ -0,0 +1,85 @@ +package com.baeldung.mvel.model; + +public class Employee { + private String name; + private Job job; + + public Employee(String name, Job job) { + this.name = name; + this.job = job; + } + + public Employee(String name, int experienceInYears, double salary, String department) { + this.name = name; + this.job = new Job(experienceInYears, salary, department); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public void setJob(Job job) { + this.job = job; + } + + public Job getJob() { + return job; + } + + + public static class Job { + private int experienceInYears; + private double salary; + private String department; + + public Job(int experienceInYears, double salary) { + this.experienceInYears = experienceInYears; + this.salary = salary; + } + + public Job(int experienceInYears, double salary, String department) { + this.experienceInYears = experienceInYears; + this.salary = salary; + this.department = department; + } + + public int getExperienceInYears() { + return experienceInYears; + } + + public void setExperienceInYears(int experienceInYears) { + this.experienceInYears = experienceInYears; + } + + public double getSalary() { + return salary; + } + + public void setSalary(double salary) { + this.salary = salary; + } + + public String getDepartment() { + return department; + } + + public void setDepartment(String department) { + this.department = department; + } + + public double calculateAnnualBonus() { + if (experienceInYears > 10) { + return salary * 0.20; + } else if (experienceInYears > 5) { + return salary * 0.10; + } else { + return salary * 0.05; + } + } + } + +} diff --git a/libraries-7/src/test/java/com/baeldung/mvel/MvelServiceUnitTest.java b/libraries-7/src/test/java/com/baeldung/mvel/MvelServiceUnitTest.java new file mode 100644 index 000000000000..8892389e88dd --- /dev/null +++ b/libraries-7/src/test/java/com/baeldung/mvel/MvelServiceUnitTest.java @@ -0,0 +1,143 @@ +package com.baeldung.mvel; + +import org.junit.jupiter.api.Test; +import org.mvel2.*; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.*; + +import com.baeldung.mvel.model.Employee; + +public class MvelServiceUnitTest { + + @Test + public void givenSimpleExpression_whenEvaluate_thenCorrectResult() { + String expression = "5 + 3 * 2"; + Object result = MVEL.eval(expression); + + assertEquals(11, result); + } + + @Test + public void givenVariables_whenEvaluateExpression_thenCorrectResult() { + Map variables = new HashMap<>(); + variables.put("salary", 75000.0); + variables.put("experience", 8); + + String expression = "salary * 0.10"; + Object result = MVEL.eval(expression, variables); + + assertEquals(7500.0, result); + } + + @Test + public void givenBooleanExpression_whenEvaluate_thenCorrectResult() { + Map variables = new HashMap<>(); + variables.put("experience", 12); + variables.put("salary", 95000.0); + + String expression = "experience > 10 && salary > 80000"; + Object result = MVEL.eval(expression, variables); + + assertTrue((Boolean) result); + } + + @Test + public void givenNullSafeNavigation_whenPropertyIsNull_thenNoException() { + Employee.Job job = new Employee.Job(5, 5000); + Employee employee = new Employee("David", job); + employee.getJob() + .setDepartment(null); + String expression = " (job.?department.length) "; + Object result = MVEL.eval(expression, employee); + + assertNull(result); + } + + @Test + public void givenEmployee_whenAccessProperties_thenCorrectValues() { + Employee.Job job = new Employee.Job(8, 75000.0); + Employee employee = new Employee("John Doe", job); + + String expression = "name + ' has ' + job.experienceInYears + ' years of experience'"; + Object result = MVEL.eval(expression, employee); + + assertEquals("John Doe has 8 years of experience", result); + } + + @Test + public void givenEmployee_whenCallMethod_thenCorrectResult() { + Employee.Job job = new Employee.Job(12, 90000.0); + Employee employee = new Employee("Jane Smith", job); + + String expression = "job.calculateAnnualBonus()"; + Object result = MVEL.eval(expression, employee); + + assertEquals(18000.0, (Double) result, 0.01); + } + + @Test + public void givenEmployee_whenEvaluateConditional_thenCorrectResult() { + Employee.Job job = new Employee.Job(15, 120000.0); + Employee employee = new Employee("Bob Johnson", job); + + String expression = "if (job.experienceInYears > 10) { job.salary * 0.20 } " + "else if (job.experienceInYears > 5) { job.salary * 0.10 } " + + "else { job.salary * 0.05 }"; + Object result = MVEL.eval(expression, employee); + + assertEquals(24000.0, (Double) result, 0.01); + } + + @Test + public void givenCompiledExpression_whenExecuteMultipleTimes_thenCorrectResults() { + String expression = "job.experienceInYears > 5 && job.salary > 50000"; + Serializable compiledExpression = MVEL.compileExpression(expression); + + Employee.Job job1 = new Employee.Job(7, 60000.0); + Employee employee1 = new Employee("Alice", job1); + + Employee.Job job2 = new Employee.Job(3, 45000.0); + Employee employee2 = new Employee("Charlie", job2); + + boolean result1 = (Boolean) MVEL.executeExpression(compiledExpression, employee1); + boolean result2 = (Boolean) MVEL.executeExpression(compiledExpression, employee2); + + assertTrue(result1); + assertFalse(result2); + } + + @Test + public void givenListProjection_whenFilter_thenCorrectResult() { + Map variables = new HashMap<>(); + List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + variables.put("numbers", numbers); + + String expression = "($ in numbers if $ > 5)"; + Object result = MVEL.eval(expression, variables); + + assertInstanceOf(List.class, result); + List filteredList = (List) result; + assertEquals(5, filteredList.size()); + } + + @Test + public void givenListTransformation_whenProject_thenCorrectResult() { + Map variables = new HashMap<>(); + List numbers = Arrays.asList(1, 2, 3, 4, 5); + variables.put("numbers", numbers); + + String expression = "($ * 2 in numbers)"; + Object result = MVEL.eval(expression, variables); + + assertInstanceOf(List.class, result); + List transformedList = (List) result; + assertEquals(10, transformedList.get(4)); + } + +} + diff --git a/libraries-7/src/test/java/com/baeldung/mvel/MvelTemplateServiceUnitTest.java b/libraries-7/src/test/java/com/baeldung/mvel/MvelTemplateServiceUnitTest.java new file mode 100644 index 000000000000..0bc7d04fb36c --- /dev/null +++ b/libraries-7/src/test/java/com/baeldung/mvel/MvelTemplateServiceUnitTest.java @@ -0,0 +1,83 @@ +package com.baeldung.mvel; + +import com.baeldung.mvel.model.Employee; + +import org.junit.jupiter.api.Test; +import org.mvel2.templates.CompiledTemplate; +import org.mvel2.templates.TemplateCompiler; +import org.mvel2.templates.TemplateRuntime; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class MvelTemplateServiceUnitTest { + + @Test + public void givenEmployeeData_whenGenerateReport_thenCorrectOutput() { + String template = """ + Employee Report + ================ + Name: @{name} + Experience: @{experience} years + Salary: $@{salary + """; + + Map variables = new HashMap<>(); + variables.put("name", "John Doe"); + variables.put("experience", 12); + variables.put("salary", 95000.0); + + CompiledTemplate compiledTemplate = TemplateCompiler.compileTemplate(template); + String result = (String) TemplateRuntime.execute(compiledTemplate, variables); + + assertTrue(result.contains("John Doe")); + assertTrue(result.contains("12 years")); + } + + @Test + public void givenSeniorEmployee_whenGenerateReport_thenCorrectStatus() { + String template = """ + Employee Report + @if{experience > 10} + Status: Senior Employee\n + @else{} + Status: Junior/Mid-level Employee + @end{} + """; + + Map variables = new HashMap<>(); + variables.put("experience", 12); + + CompiledTemplate compiledTemplate = TemplateCompiler.compileTemplate(template); + String result = (String) TemplateRuntime.execute(compiledTemplate, variables); + + assertTrue(result.contains("Senior Employee")); + } + + @Test + public void givenEmployeeList_whenGenerateListReport_thenCorrectOutput() { + String template = """ + "Employee List: + "@foreach{emp : employees} + "- @{emp.name} (@{emp.job.department}) + "@end{} + """; + + List employees = Arrays.asList(new Employee("John", 10, 80000.0, "IT"), new Employee("Jane", 8, 75000.0, "HR"), + new Employee("Bob", 12, 95000.0, "Finance")); + + Map variables = new HashMap<>(); + variables.put("employees", employees); + + CompiledTemplate compiledTemplate = TemplateCompiler.compileTemplate(template); + String result = (String) TemplateRuntime.execute(compiledTemplate, variables); + + assertTrue(result.contains("John (IT)")); + assertTrue(result.contains("Jane (HR)")); + } +} +