package com.sap.ide.refactoring.core.textual;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.List;
import ngpm.NgpmPackage;
import org.eclipse.core.runtime.Path;
import org.junit.Test;
import textblocks.TextBlock;
import behavioral.actions.Block;
import behavioral.actions.Statement;
import com.sap.ide.refactoring.core.textual.ModelElementDocumentNodeChangeDescriptor.ChangeType;
import com.sap.ide.refactoring.test.RefactoringBaseTest;
import com.sap.mi.fwk.ModelManager;
import com.sap.tc.moin.repository.mmi.reflect.RefObject;
import data.classes.MethodSignature;
import data.classes.SapClass;
public class TestTextBlockInChangeCalculator extends RefactoringBaseTest {
/**
* System under test
*/
private TextBlockInChangeCalculator sut;
private RefactoringEditorFacade facade;
@Test
public void testRootObjectChanged() {
sut = new TextBlockInChangeCalculator();
facade = createEditorFacadeForRunletClass("Class1");
RefObject rootObject = facade.getDecoratedDomainRootObject();
RootElementTextBlockTuple rootTuple = new RootElementTextBlockTuple(rootObject, facade.getTextBlocksModel().getRoot());
TextBlock rootBlock = facade.getTextBlocksModel().getRoot();
sut.add(rootObject, ChangeType.CHANGED);
assertTextBlockInTupleList("If the root block has changed, the corresponding root textblock needs pretty printing", sut
.getTextBlocksNeedingPrettyPrinting().get(rootTuple), rootBlock);
assertEquals("Class1 has no overlapping views on it.", 1, sut.getTextBlocksNeedingPrettyPrinting().size());
assertEquals("Class1 is only references by the token that holds its name in the TB model", 1, sut
.getTextBlocksNeedingShortPrettyPrinting().get(rootTuple).size());
}
@Test
public void testRootObjectAndCompositeChanged1() {
sut = new TextBlockInChangeCalculator();
facade = createEditorFacadeForRunletClass("Class1");
RefObject rootObject = facade.getDecoratedDomainRootObject();
RootElementTextBlockTuple rootTuple = new RootElementTextBlockTuple(rootObject, facade.getTextBlocksModel().getRoot());
RefObject compositeChild = ((SapClass) rootObject).getOwnedSignatures().iterator().next();
TextBlock rootBlock = facade.getTextBlocksModel().getRoot();
// Variant 1: First add the root
sut.add(rootObject, ChangeType.CHANGED);
sut.add(compositeChild, ChangeType.CHANGED);
assertTextBlockInTupleList(sut.getTextBlocksNeedingPrettyPrinting().get(rootTuple), rootBlock);
assertEquals("If the parent block is in, the composite child must have been filtered.",
1, sut.getTextBlocksNeedingPrettyPrinting().get(rootTuple).size());
}
@Test
public void testRootObjectAndCompositeChanged2() {
sut = new TextBlockInChangeCalculator();
facade = createEditorFacadeForRunletClass("Class1");
RefObject rootObject = facade.getDecoratedDomainRootObject();
RootElementTextBlockTuple rootTuple = new RootElementTextBlockTuple(rootObject, facade.getTextBlocksModel().getRoot());
RefObject compositeChild = ((SapClass) rootObject).getOwnedSignatures().iterator().next();
TextBlock rootBlock = facade.getTextBlocksModel().getRoot();
// Variant 2: First add the child, then the root
sut.add(compositeChild, ChangeType.CHANGED);
sut.add(rootObject, ChangeType.CHANGED);
assertTextBlockInTupleList(sut.getTextBlocksNeedingPrettyPrinting().get(rootTuple), rootBlock);
assertEquals("If the parent block is in, the composite child must have been filtered.",
1, sut.getTextBlocksNeedingPrettyPrinting().get(rootTuple).size());
}
@Test
public void testComplexMergeExample() {
sut = new TextBlockInChangeCalculator();
facade = createEditorFacadeForRunletClass("AddTwoParametersTest");
SapClass rootObject = (SapClass) facade.getDecoratedDomainRootObject();
RootElementTextBlockTuple rootTuple = new RootElementTextBlockTuple(rootObject, facade.getTextBlocksModel().getRoot());
MethodSignature firstMethod = rootObject.getOwnedSignatures().iterator().next();
MethodSignature secondMethod = rootObject.getOwnedSignatures().iterator().next();
Block firstMethodImpl = (Block) firstMethod.getImplementation();
Statement firstStatementInFirstMethod = firstMethodImpl.getStatements().iterator().next();
sut.add(firstStatementInFirstMethod, ChangeType.CHANGED);
sut.add(secondMethod, ChangeType.CHANGED);
assertEquals("Expect to find the statement and the second method.", 2,
sut.getTextBlocksNeedingPrettyPrinting().get(rootTuple).size());
sut.add(firstMethodImpl, ChangeType.CHANGED);
assertEquals("Expect to find one method and one method body.", 2,
sut.getTextBlocksNeedingPrettyPrinting().get(rootTuple).size());
// double inserts should do no harm
sut.add(firstMethodImpl, ChangeType.CHANGED);
sut.add(firstStatementInFirstMethod, ChangeType.CHANGED);
sut.add(secondMethod, ChangeType.CHANGED);
sut.add(firstMethod, ChangeType.CHANGED); // should lead to removeal of the body and the statement
assertEquals("Expect to find both methods.", 2,
sut.getTextBlocksNeedingPrettyPrinting().get(rootTuple).size());
sut.add(rootObject, ChangeType.CHANGED);
assertEquals("Expect to find just the root tb.", 1,
sut.getTextBlocksNeedingPrettyPrinting().get(rootTuple).size());
TextBlock rootBlock = facade.getTextBlocksModel().getRoot();
assertTextBlockInTupleList(sut.getTextBlocksNeedingPrettyPrinting().get(rootTuple), rootBlock);
}
/**
* For now we expect new top level elements do not get a new view automatically
*
* If anyone has a good reasons to change it, we will.
*/
@Test
public void testCreateNewRootElement() {
sut = new TextBlockInChangeCalculator();
// create a new class (a class which does not have any associated textblocks!)
NgpmPackage rootPkg = connection.getPackage(NgpmPackage.PACKAGE_DESCRIPTOR);
final SapClass newclazz = (SapClass) rootPkg.getData().getClasses().getSapClass().refCreateInstanceInPartition(
ModelManager.getPartitionService().getPartition(connection, getProject(),
new Path("src/Package1235568260162.types")));
newclazz.setName("NewClass");
sut.add(newclazz, ChangeType.CREATED);
assertTrue(sut.getTextBlocksNeedingPrettyPrinting().isEmpty());
}
private void assertTextBlockInTupleList(List<ModelElementDocumentNodeChangeDescriptor> tuples, TextBlock tb) {
boolean found = tuples != null && findTextBlockInTupleList(tuples, tb);
assertTrue(found);
}
private void assertTextBlockInTupleList(String message, List<ModelElementDocumentNodeChangeDescriptor> tuples, TextBlock tb) {
boolean found = tuples != null && findTextBlockInTupleList(tuples, tb);
assertTrue(message, found);
}
private boolean findTextBlockInTupleList(List<ModelElementDocumentNodeChangeDescriptor> tuples, TextBlock tb) {
boolean found = false;
for (ModelElementDocumentNodeChangeDescriptor tuple : tuples) {
if (tuple.documentNode.equals(tb)) {
found = true;
}
}
return found;
}
}