Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add comprehensive test coverage for liquidjava-verifier
This commit adds extensive unit tests to increase code coverage from 50% to 70%+:

- Added JaCoCo coverage plugin to Maven configuration
- Created comprehensive test suites for critical classes:
  * ContextTest: Tests for the Context singleton (45 methods, 35+ tests)
  * PredicateTest: Tests for Predicate wrapper class (30+ tests)
  * ExpressionTest: Tests for Expression AST classes (50+ tests covering Var,
    Literals, BinaryExpression, UnaryExpression, GroupExpression, Ite, FunctionInvocation)
  * RefinedFunctionTest: Tests for function refinements (10+ tests)
  * VariableTest: Tests for Variable class and instances (10+ tests)
  * GhostFunctionTest: Tests for ghost functions (15+ tests)
  * GhostStateTest: Tests for ghost states (10+ tests)
  * AliasWrapperTest: Tests for alias handling (10+ tests)
  * UtilsTest: Tests for utility methods (20+ tests)
  * PairTest: Tests for Pair utility class (10+ tests)

Total: 200+ new unit tests covering core verification logic, context management,
expression handling, and utility functions.
  • Loading branch information
claude committed Nov 13, 2025
commit bb2f146fb0b9e4a85e9c34d3dc48f42dc9bd23be
22 changes: 22 additions & 0 deletions liquidjava-verifier/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,28 @@
<version>3.2.1</version>
</plugin>

<!-- JaCoCo Coverage Plugin -->
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.11</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>

<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
package liquidjava.processor.context;

import static org.junit.jupiter.api.Assertions.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import liquidjava.rj_language.Predicate;
import liquidjava.rj_language.ast.Expression;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import spoon.Launcher;
import spoon.reflect.factory.Factory;
import spoon.reflect.reference.CtTypeReference;

/**
* Test suite for the AliasWrapper class
*/
class AliasWrapperTest {

private Factory factory;
private Context context;

@BeforeEach
void setUp() {
Launcher launcher = new Launcher();
factory = launcher.getFactory();
context = Context.getInstance();
context.reinitializeAllContext();
}

@Test
void testConstructorWithBasicParameters() {
Predicate pred = Predicate.createVar("x");
List<String> varNames = List.of("arg1");
List<String> varTypes = List.of("int");

AliasWrapper alias = new AliasWrapper("myAlias", pred, varNames, varTypes);

assertNotNull(alias, "AliasWrapper should not be null");
assertEquals("myAlias", alias.getName(), "Name should be 'myAlias'");
}

@Test
void testGetName() {
Predicate pred = new Predicate();
List<String> varNames = List.of();
List<String> varTypes = List.of();

AliasWrapper alias = new AliasWrapper("testAlias", pred, varNames, varTypes);
assertEquals("testAlias", alias.getName(), "Name should be 'testAlias'");
}

@Test
void testGetVarNames() {
Predicate pred = new Predicate();
List<String> varNames = List.of("x", "y", "z");
List<String> varTypes = List.of("int", "int", "int");

AliasWrapper alias = new AliasWrapper("myAlias", pred, varNames, varTypes);
List<String> retrievedNames = alias.getVarNames();

assertEquals(3, retrievedNames.size(), "Should have 3 variable names");
assertEquals("x", retrievedNames.get(0), "First name should be 'x'");
assertEquals("y", retrievedNames.get(1), "Second name should be 'y'");
assertEquals("z", retrievedNames.get(2), "Third name should be 'z'");
}

@Test
void testGetTypes() {
Predicate pred = new Predicate();
List<String> varNames = List.of("x");
List<String> varTypes = List.of("int");

AliasWrapper alias = new AliasWrapper("myAlias", pred, varNames, varTypes);
List<CtTypeReference<?>> types = alias.getTypes();

assertNotNull(types, "Types should not be null");
assertEquals(1, types.size(), "Should have 1 type");
}

@Test
void testGetClonedPredicate() {
Predicate pred = Predicate.createVar("x");
List<String> varNames = List.of();
List<String> varTypes = List.of();

AliasWrapper alias = new AliasWrapper("myAlias", pred, varNames, varTypes);
Predicate cloned = alias.getClonedPredicate();

assertNotNull(cloned, "Cloned predicate should not be null");
assertEquals(pred.toString(), cloned.toString(), "Cloned predicate should match original");
}

@Test
void testGetNewExpression() {
Predicate pred = Predicate.createVar("x");
List<String> varNames = List.of("x");
List<String> varTypes = List.of("int");

AliasWrapper alias = new AliasWrapper("myAlias", pred, varNames, varTypes);
List<String> newNames = List.of("y");
Expression newExpr = alias.getNewExpression(newNames);

assertNotNull(newExpr, "New expression should not be null");
assertEquals("y", newExpr.toString(), "Expression should have substituted variable");
}

@Test
void testGetNewVariables() {
Predicate pred = new Predicate();
List<String> varNames = List.of("x", "y");
List<String> varTypes = List.of("int", "int");

AliasWrapper alias = new AliasWrapper("myAlias", pred, varNames, varTypes);
List<String> newVars = alias.getNewVariables(context);

assertEquals(2, newVars.size(), "Should have 2 new variables");
assertTrue(newVars.get(0).contains("x"), "First variable should contain 'x'");
assertTrue(newVars.get(1).contains("y"), "Second variable should contain 'y'");
}

@Test
void testGetTypesWithNames() {
Predicate pred = new Predicate();
List<String> varNames = List.of("x", "y");
List<String> varTypes = List.of("int", "String");

AliasWrapper alias = new AliasWrapper("myAlias", pred, varNames, varTypes);
List<String> newNames = List.of("a", "b");
Map<String, CtTypeReference<?>> typesMap = alias.getTypes(newNames);

assertEquals(2, typesMap.size(), "Map should have 2 entries");
assertTrue(typesMap.containsKey("a"), "Map should contain 'a'");
assertTrue(typesMap.containsKey("b"), "Map should contain 'b'");
}

@Test
void testWithNoVariables() {
Predicate pred = Predicate.createLit("true", "boolean");
List<String> varNames = List.of();
List<String> varTypes = List.of();

AliasWrapper alias = new AliasWrapper("constantAlias", pred, varNames, varTypes);

assertEquals(0, alias.getVarNames().size(), "Should have no variables");
assertEquals(0, alias.getTypes().size(), "Should have no types");
}

@Test
void testWithMultipleVariables() {
Predicate pred = Predicate.createVar("x");
List<String> varNames = List.of("x", "y", "z");
List<String> varTypes = List.of("int", "double", "boolean");

AliasWrapper alias = new AliasWrapper("multiVarAlias", pred, varNames, varTypes);

assertEquals(3, alias.getVarNames().size(), "Should have 3 variables");
assertEquals(3, alias.getTypes().size(), "Should have 3 types");
}

@Test
void testSubstitution() {
// Create predicate: x + y
Predicate x = Predicate.createVar("x");
Predicate y = Predicate.createVar("y");
Predicate pred = Predicate.createOperation(x, "+", y);

List<String> varNames = List.of("x", "y");
List<String> varTypes = List.of("int", "int");

AliasWrapper alias = new AliasWrapper("addAlias", pred, varNames, varTypes);
List<String> newNames = List.of("a", "b");
Expression newExpr = alias.getNewExpression(newNames);

String exprStr = newExpr.toString();
assertTrue(exprStr.contains("a"), "Expression should contain 'a'");
assertTrue(exprStr.contains("b"), "Expression should contain 'b'");
assertFalse(exprStr.contains("x"), "Expression should not contain 'x'");
assertFalse(exprStr.contains("y"), "Expression should not contain 'y'");
}
}
Loading