package org.overture.vdm2jml.tests; import java.util.List; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.overture.ast.analysis.AnalysisException; import org.overture.ast.util.ClonableString; import org.overture.codegen.ir.declarations.AMethodDeclIR; import org.overture.codegen.ir.statements.AMetaStmIR; import org.overture.vdm2jml.tests.util.TestDataCollector; import org.overture.vdm2jml.tests.util.Update; public class ModuleStateInvTests extends AnnotationTestsBase { @BeforeClass public static void init() throws AnalysisException { AnnotationTestsBase.init("ModuleStateInv.vdmsl"); } public static void checkAssertion(String methodName, Update update, int noOfAsserts) throws org.overture.codegen.ir.analysis.AnalysisException { AMethodDeclIR assignSt = getMethod(genModule.getMethods(), methodName); Assert.assertTrue("Could not find method '" + methodName + "'", assignSt != null); TestDataCollector dataCollector = new TestDataCollector(); assignSt.apply(dataCollector); if (update == Update.ASSIGN) { Assert.assertTrue("Expected to find a single assignment in the '" + methodName + "' method", dataCollector.getAssignments().size() == 1); Assert.assertTrue("Expected to find no map seq updates in the '" + methodName + "' method", dataCollector.getMapSeqUpdates().isEmpty()); Assert.assertTrue("Expected to find no set calls in the '" + methodName + "' method", dataCollector.getSetCalls().isEmpty()); } else if (update == Update.MAP_SEQ_UPDATE) { Assert.assertTrue("Expected to find no assignments in the '" + methodName + "' method", dataCollector.getAssignments().isEmpty()); Assert.assertTrue("Expected to find a single map seq update in the '" + methodName + "' method", dataCollector.getMapSeqUpdates().size() == 1); Assert.assertTrue("Expected to find no set calls in the '" + methodName + "' method", dataCollector.getSetCalls().isEmpty()); } else { // Setter call Assert.assertTrue("Expected to find no assignments in the '" + methodName + "' method", dataCollector.getAssignments().isEmpty()); Assert.assertTrue("Expected to find no map seq updates in the '" + methodName + "' method", dataCollector.getMapSeqUpdates().isEmpty()); Assert.assertTrue("Expected to find a single set call in the '" + methodName + "' method", dataCollector.getSetCalls().size() == 1); } if (noOfAsserts > 0) { Assert.assertTrue("Expected to find " + noOfAsserts + " assertion(s) in the '" + methodName + "' method", dataCollector.getAssertions().size() == noOfAsserts); for (AMetaStmIR a : dataCollector.getAssertions()) { List<? extends ClonableString> metaData = a.getMetaData(); Assert.assertTrue("Expected only a single assertion", metaData.size() == 1); String assertStr = metaData.get(0).value; Assert.assertTrue("Got unexpected assertion in method '" + methodName + "': " + assertStr, assertStr.contains(".valid()") || assertStr.contains("!= null") || assertStr.contains(".is_")); } } else { Assert.assertTrue("Expected no assertions in the '" + methodName + "' method", dataCollector.getAssertions().isEmpty()); } } @Test public void updateEntireState() throws org.overture.codegen.ir.analysis.AnalysisException { checkAssertion("assignSt", Update.ASSIGN, 1); } @Test public void updateEntireStateAtomic() throws org.overture.codegen.ir.analysis.AnalysisException { // No need to assert since the violation will be picked up by the // atomicTmp var assignment checkAssertion("atomicAssignSt", Update.ASSIGN, 2); } @Test public void updateField() throws org.overture.codegen.ir.analysis.AnalysisException { checkAssertion("assignX", Update.SET_CALL, 1); } @Test public void updateFieldAtomic() throws org.overture.codegen.ir.analysis.AnalysisException { checkAssertion("atomicAssignX", Update.SET_CALL, 4); } @Test public void updateSeqElem() throws org.overture.codegen.ir.analysis.AnalysisException { checkAssertion("assignS", Update.MAP_SEQ_UPDATE, 5); } @Test public void updateSeqElemAtomic() throws org.overture.codegen.ir.analysis.AnalysisException { checkAssertion("atomicAssignS", Update.MAP_SEQ_UPDATE, 5); } @Test public void updateMapRng() throws org.overture.codegen.ir.analysis.AnalysisException { checkAssertion("assignM", Update.MAP_SEQ_UPDATE, 5); } @Test public void updateMapRngAtomic() throws org.overture.codegen.ir.analysis.AnalysisException { checkAssertion("atomicAssignM", Update.MAP_SEQ_UPDATE, 5); } }