/**
* <copyright> Copyright (c) 2008-2009 Jonas Helming, Maximilian Koegel. All rights reserved. This program and the
* accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this
* distribution, and is available at http://www.eclipse.org/legal/epl-v10.html </copyright>
*/
package org.eclipse.emf.emfstore.client.test.changeTracking.topology;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.List;
import org.eclipse.emf.emfstore.client.model.exceptions.UnsupportedNotificationException;
import org.eclipse.emf.emfstore.client.test.model.document.DocumentFactory;
import org.eclipse.emf.emfstore.client.test.model.document.LeafSection;
import org.eclipse.emf.emfstore.client.test.model.rationale.Issue;
import org.eclipse.emf.emfstore.client.test.model.rationale.RationaleFactory;
import org.eclipse.emf.emfstore.client.test.model.rationale.Solution;
import org.eclipse.emf.emfstore.common.model.ModelElementId;
import org.eclipse.emf.emfstore.common.model.util.ModelUtil;
import org.eclipse.emf.emfstore.server.model.versioning.operations.AbstractOperation;
import org.eclipse.emf.emfstore.server.model.versioning.operations.CompositeOperation;
import org.eclipse.emf.emfstore.server.model.versioning.operations.MultiReferenceOperation;
import org.eclipse.emf.emfstore.server.model.versioning.operations.SingleReferenceOperation;
import org.junit.Test;
/**
* Tests operations in 1:1 topologies.
*
* @author chodnick
*/
public class Topology1to1Test extends TopologyTest {
/**
* Change an containment attribute from null to some reference, and check resulting op.
*
* @throws UnsupportedOperationException on test fail
* @throws UnsupportedNotificationException on test fail
*/
@Test
public void containmentNullToValueNotContainedAlreadyOperateOnParent() throws UnsupportedOperationException,
UnsupportedNotificationException {
Issue issue = RationaleFactory.eINSTANCE.createIssue();
Solution solution = RationaleFactory.eINSTANCE.createSolution();
assertEquals(issue.getSolution(), null);
getProject().addModelElement(issue);
getProject().addModelElement(solution);
clearOperations();
issue.setSolution(solution);
assertSame(solution, issue.getSolution());
List<AbstractOperation> operations = getProjectSpace().getOperations();
assertEquals(1, operations.size());
AbstractOperation operation = operations.get(0);
assertEquals(true, operation instanceof CompositeOperation);
List<AbstractOperation> subOperations = ((CompositeOperation) operation).getSubOperations();
assertEquals(2, subOperations.size());
ModelElementId issueId = ModelUtil.getProject(issue).getModelElementId(issue);
ModelElementId solutionId = ModelUtil.getProject(solution).getModelElementId(solution);
AbstractOperation op = subOperations.get(0);
assertEquals(true, op instanceof SingleReferenceOperation);
SingleReferenceOperation op0 = (SingleReferenceOperation) op;
assertEquals(null, op0.getOldValue());
assertEquals(issueId, op0.getNewValue());
assertEquals("issue", op0.getFeatureName());
assertEquals(solutionId, op0.getModelElementId());
op = subOperations.get(1);
assertEquals(true, op instanceof SingleReferenceOperation);
SingleReferenceOperation op1 = (SingleReferenceOperation) op;
assertEquals(null, op1.getOldValue());
assertEquals(solutionId, op1.getNewValue());
assertEquals("solution", op1.getFeatureName());
assertEquals(issueId, op1.getModelElementId());
}
/**
* Change an containment attribute from null to some reference, and check resulting op.
*
* @throws UnsupportedOperationException on test fail
* @throws UnsupportedNotificationException on test fail
*/
@Test
public void containmentNullToValueNotContainedAlreadyOperateOnChild() throws UnsupportedOperationException,
UnsupportedNotificationException {
Issue issue = RationaleFactory.eINSTANCE.createIssue();
Solution solution = RationaleFactory.eINSTANCE.createSolution();
assertEquals(issue.getSolution(), null);
getProject().addModelElement(issue);
getProject().addModelElement(solution);
clearOperations();
solution.setIssue(issue);
assertSame(solution, issue.getSolution());
List<AbstractOperation> operations = getProjectSpace().getOperations();
assertEquals(1, operations.size());
AbstractOperation operation = operations.get(0);
assertEquals(true, operation instanceof CompositeOperation);
List<AbstractOperation> subOperations = ((CompositeOperation) operation).getSubOperations();
assertEquals(2, subOperations.size());
ModelElementId solutionId = ModelUtil.getProject(solution).getModelElementId(solution);
ModelElementId issueId = ModelUtil.getProject(issue).getModelElementId(issue);
AbstractOperation op = subOperations.get(0);
assertEquals(true, op instanceof SingleReferenceOperation);
SingleReferenceOperation op0 = (SingleReferenceOperation) op;
assertEquals(null, op0.getOldValue());
assertEquals(solutionId, op0.getNewValue());
assertEquals("solution", op0.getFeatureName());
assertEquals(issueId, op0.getModelElementId());
op = subOperations.get(1);
assertEquals(true, op instanceof SingleReferenceOperation);
SingleReferenceOperation op1 = (SingleReferenceOperation) op;
assertEquals(null, op1.getOldValue());
assertEquals(issueId, op1.getNewValue());
assertEquals("issue", op1.getFeatureName());
assertEquals(solutionId, op1.getModelElementId());
}
/**
* Change an containment attribute from some reference to some other reference, and check resulting op.
*
* @throws UnsupportedOperationException on test fail
* @throws UnsupportedNotificationException on test fail
*/
@Test
public void containmentValueToOtherValueNotContainedAlreadyOperateOnParent() throws UnsupportedOperationException,
UnsupportedNotificationException {
Issue issue = RationaleFactory.eINSTANCE.createIssue();
Solution solutionOld = RationaleFactory.eINSTANCE.createSolution();
Solution solutionNew = RationaleFactory.eINSTANCE.createSolution();
getProject().addModelElement(issue);
getProject().addModelElement(solutionOld);
getProject().addModelElement(solutionNew);
issue.setSolution(solutionOld);
assertEquals(issue.getSolution(), solutionOld);
clearOperations();
// fetch id here, before oldSolution is removed from project
ModelElementId solutionOldId = ModelUtil.getProject(solutionOld).getModelElementId(solutionOld);
issue.setSolution(solutionNew);
assertSame(solutionNew, issue.getSolution());
List<AbstractOperation> operations = getProjectSpace().getOperations();
assertEquals(1, operations.size());
AbstractOperation operation = operations.get(0);
assertEquals(true, operation instanceof CompositeOperation);
List<AbstractOperation> subOperations = ((CompositeOperation) operation).getSubOperations();
assertEquals(3, subOperations.size());
ModelElementId solutionNewId = ModelUtil.getProject(solutionNew).getModelElementId(solutionNew);
ModelElementId issueId = ModelUtil.getProject(issue).getModelElementId(issue);
AbstractOperation op = subOperations.get(0);
assertEquals(true, op instanceof SingleReferenceOperation);
SingleReferenceOperation op0 = (SingleReferenceOperation) op;
assertEquals(issueId, op0.getOldValue());
assertEquals(null, op0.getNewValue());
assertEquals("issue", op0.getFeatureName());
assertEquals(solutionOldId, op0.getModelElementId());
op = subOperations.get(1);
assertEquals(true, op instanceof SingleReferenceOperation);
SingleReferenceOperation op1 = (SingleReferenceOperation) op;
assertEquals(null, op1.getOldValue());
assertEquals(issueId, op1.getNewValue());
assertEquals("issue", op1.getFeatureName());
assertEquals(solutionNewId, op1.getModelElementId());
op = subOperations.get(2);
assertEquals(true, op instanceof SingleReferenceOperation);
SingleReferenceOperation op2 = (SingleReferenceOperation) op;
assertEquals(solutionOldId, op2.getOldValue());
assertEquals(solutionNewId, op2.getNewValue());
assertEquals("solution", op2.getFeatureName());
assertEquals(issueId, op2.getModelElementId());
}
/**
* Change an containment attribute from some reference to some other reference, and check resulting op.
*
* @throws UnsupportedOperationException on test fail
* @throws UnsupportedNotificationException on test fail
*/
@Test
public void containmentValueToOtherValueNotContainedAlreadyOperateOnChild() throws UnsupportedOperationException,
UnsupportedNotificationException {
Issue issue = RationaleFactory.eINSTANCE.createIssue();
Solution solutionOld = RationaleFactory.eINSTANCE.createSolution();
Solution solutionNew = RationaleFactory.eINSTANCE.createSolution();
getProject().addModelElement(issue);
getProject().addModelElement(solutionOld);
getProject().addModelElement(solutionNew);
ModelElementId solutionOldId = ModelUtil.getProject(solutionOld).getModelElementId(solutionOld);
issue.setSolution(solutionOld);
assertEquals(issue.getSolution(), solutionOld);
clearOperations();
solutionNew.setIssue(issue);
assertSame(solutionNew, issue.getSolution());
List<AbstractOperation> operations = getProjectSpace().getOperations();
// expecting a composite operation here
assertEquals(1, operations.size());
if (operations.get(0) instanceof CompositeOperation) {
operations = ((CompositeOperation) operations.get(0)).getSubOperations();
} else {
fail("composite operation expected");
}
// please note: the perspective (operation called on containee) implies the following EMF notifications:
// OldSolution: SET issue from issue to null
// Issue: SET solution from oldSolution to newSolution
// NewSolution: SET issue from null to issue
//
// Since we are operating on newSolution we expect an operation :
// solutionNew: got new Issue
//
// we need to preserve the fact, that "oldSolution" was the former solution of "issue"
// following the "last bidirectional message wins" rule, the first message has to
// go away, since it is the bidirectional of the second message
// refactor: bidirectional filter is disabled
assertEquals(3, operations.size());
ModelElementId solutionNewId = ModelUtil.getProject(solutionNew).getModelElementId(solutionNew);
ModelElementId issueId = ModelUtil.getProject(issue).getModelElementId(issue);
AbstractOperation op0 = operations.get(0);
assertEquals(true, op0 instanceof SingleReferenceOperation);
SingleReferenceOperation refOp0 = (SingleReferenceOperation) op0;
assertEquals(solutionOldId, refOp0.getModelElementId());
assertEquals(issueId, refOp0.getOldValue());
assertEquals(null, refOp0.getNewValue());
assertEquals("issue", refOp0.getFeatureName());
AbstractOperation op1 = operations.get(1);
assertEquals(true, op1 instanceof SingleReferenceOperation);
SingleReferenceOperation refOp1 = (SingleReferenceOperation) op1;
assertEquals(issueId, refOp1.getModelElementId());
assertEquals(solutionOldId, refOp1.getOldValue());
assertEquals(solutionNewId, refOp1.getNewValue());
assertEquals("solution", refOp1.getFeatureName());
AbstractOperation op2 = operations.get(2);
assertEquals(true, op2 instanceof SingleReferenceOperation);
SingleReferenceOperation refOp2 = (SingleReferenceOperation) op2;
assertEquals(solutionNewId, refOp2.getModelElementId());
assertEquals(issueId, refOp2.getNewValue());
assertNull(refOp2.getOldValue());
assertEquals("issue", refOp2.getFeatureName());
}
/**
* Change an containment attribute from some reference to some other reference, and check resulting op.
*
* @throws UnsupportedOperationException on test fail
* @throws UnsupportedNotificationException on test fail
*/
@Test
public void containmentValueToOtherValueContainedAlready1OperateOnParent() throws UnsupportedOperationException,
UnsupportedNotificationException {
Issue issue1 = RationaleFactory.eINSTANCE.createIssue();
Issue issue2 = RationaleFactory.eINSTANCE.createIssue();
Solution solution1 = RationaleFactory.eINSTANCE.createSolution();
Solution solution2 = RationaleFactory.eINSTANCE.createSolution();
getProject().addModelElement(issue1);
getProject().addModelElement(issue2);
getProject().addModelElement(solution1);
getProject().addModelElement(solution2);
issue1.setSolution(solution1);
issue2.setSolution(solution2);
assertEquals(issue1.getSolution(), solution1);
assertEquals(issue2.getSolution(), solution2);
ModelElementId solution1Id = ModelUtil.getProject(solution1).getModelElementId(solution1);
clearOperations();
issue1.setSolution(solution2);
assertSame(solution2, issue1.getSolution());
assertNull(issue2.getSolution());
List<AbstractOperation> operations = getProjectSpace().getOperations();
// expecting a composite operation here
assertEquals(1, operations.size());
if (operations.get(0) instanceof CompositeOperation) {
operations = ((CompositeOperation) operations.get(0)).getSubOperations();
} else {
fail("composite operation expected");
}
assertEquals(4, operations.size());
AbstractOperation op1 = operations.get(0);
AbstractOperation op2 = operations.get(1);
AbstractOperation op3 = operations.get(2);
AbstractOperation op4 = operations.get(3);
assertEquals(true, op1 instanceof SingleReferenceOperation);
assertEquals(true, op2 instanceof SingleReferenceOperation);
assertEquals(true, op3 instanceof SingleReferenceOperation);
assertEquals(true, op4 instanceof SingleReferenceOperation);
SingleReferenceOperation refOp1 = (SingleReferenceOperation) op1;
SingleReferenceOperation refOp2 = (SingleReferenceOperation) op2;
SingleReferenceOperation refOp3 = (SingleReferenceOperation) op3;
SingleReferenceOperation refOp4 = (SingleReferenceOperation) op4;
// please note: 2 ops are necessary, this is because the oldvalues are necessary for
// the ops to be reversible! we need to track the parent of solution 2!
// 4 due to refactoring
ModelElementId solution2Id = ModelUtil.getProject(solution2).getModelElementId(solution2);
ModelElementId issue1Id = ModelUtil.getProject(issue1).getModelElementId(issue1);
ModelElementId issue2Id = ModelUtil.getProject(issue2).getModelElementId(issue2);
assertEquals(issue1Id, refOp1.getOldValue());
assertEquals(null, refOp1.getNewValue());
assertEquals("issue", refOp1.getFeatureName());
assertEquals(solution1Id, refOp1.getModelElementId());
assertEquals(solution2Id, refOp2.getOldValue());
assertEquals(null, refOp2.getNewValue());
assertEquals("solution", refOp2.getFeatureName());
assertEquals(issue2Id, refOp2.getModelElementId());
assertEquals(issue2Id, refOp3.getOldValue());
assertEquals(issue1Id, refOp3.getNewValue());
assertEquals("issue", refOp3.getFeatureName());
assertEquals(solution2Id, refOp3.getModelElementId());
assertEquals(solution1Id, refOp4.getOldValue());
assertEquals(solution2Id, refOp4.getNewValue());
assertEquals("solution", refOp4.getFeatureName());
assertEquals(issue1Id, refOp4.getModelElementId());
}
/**
* Change an containment attribute from some reference to some other reference, and check resulting op.
*
* @throws UnsupportedOperationException on test fail
* @throws UnsupportedNotificationException on test fail
*/
@Test
public void containmentValueToOtherValueContainedAlready1OperateOnChild() throws UnsupportedOperationException,
UnsupportedNotificationException {
Issue issue1 = RationaleFactory.eINSTANCE.createIssue();
Issue issue2 = RationaleFactory.eINSTANCE.createIssue();
Solution solution1 = RationaleFactory.eINSTANCE.createSolution();
Solution solution2 = RationaleFactory.eINSTANCE.createSolution();
getProject().addModelElement(issue1);
getProject().addModelElement(issue2);
getProject().addModelElement(solution1);
getProject().addModelElement(solution2);
issue1.setSolution(solution1);
issue2.setSolution(solution2);
assertEquals(issue1.getSolution(), solution1);
assertEquals(issue2.getSolution(), solution2);
clearOperations();
ModelElementId solution1Id = ModelUtil.getProject(solution1).getModelElementId(solution1);
solution2.setIssue(issue1);
assertSame(solution2, issue1.getSolution());
assertNull(issue2.getSolution());
List<AbstractOperation> operations = getProjectSpace().getOperations();
// expecting a composite operation here
assertEquals(1, operations.size());
if (operations.get(0) instanceof CompositeOperation) {
operations = ((CompositeOperation) operations.get(0)).getSubOperations();
} else {
fail("composite operation expected");
}
assertEquals(4, operations.size());
AbstractOperation op1 = operations.get(0);
AbstractOperation op2 = operations.get(1);
AbstractOperation op3 = operations.get(2);
AbstractOperation op4 = operations.get(3);
assertEquals(true, op1 instanceof SingleReferenceOperation);
assertEquals(true, op2 instanceof SingleReferenceOperation);
assertEquals(true, op3 instanceof SingleReferenceOperation);
assertEquals(true, op4 instanceof SingleReferenceOperation);
SingleReferenceOperation refOp1 = (SingleReferenceOperation) op1;
SingleReferenceOperation refOp2 = (SingleReferenceOperation) op2;
SingleReferenceOperation refOp3 = (SingleReferenceOperation) op3;
SingleReferenceOperation refOp4 = (SingleReferenceOperation) op4;
// please note: 2 ops are necessary, this is because the oldvalues are necessary for
// the ops to be reversible! we need to track the parent of solution 2!
// 4 due to refactoring
ModelElementId solution2Id = ModelUtil.getProject(solution2).getModelElementId(solution2);
ModelElementId issue1Id = ModelUtil.getProject(issue1).getModelElementId(issue1);
ModelElementId issue2Id = ModelUtil.getProject(issue2).getModelElementId(issue2);
assertEquals(solution2Id, refOp1.getOldValue());
assertEquals(null, refOp1.getNewValue());
assertEquals("solution", refOp1.getFeatureName());
assertEquals(issue2Id, refOp1.getModelElementId());
assertEquals(issue1Id, refOp2.getOldValue());
assertEquals(null, refOp2.getNewValue());
assertEquals("issue", refOp2.getFeatureName());
assertEquals(solution1Id, refOp2.getModelElementId());
assertEquals(solution1Id, refOp3.getOldValue());
assertEquals(solution2Id, refOp3.getNewValue());
assertEquals("solution", refOp3.getFeatureName());
assertEquals(issue1Id, refOp3.getModelElementId());
assertEquals(issue2Id, refOp4.getOldValue());
assertEquals(issue1Id, refOp4.getNewValue());
assertEquals("issue", refOp4.getFeatureName());
assertEquals(solution2Id, refOp4.getModelElementId());
}
/**
* Change an containment attribute from some reference to some other reference, and check resulting op.
*
* @throws UnsupportedOperationException on test fail
* @throws UnsupportedNotificationException on test fail
*/
@Test
public void containmentNullToOtherValueContainedAlready1OperateOnChild() throws UnsupportedOperationException,
UnsupportedNotificationException {
Issue issue1 = RationaleFactory.eINSTANCE.createIssue();
Issue issue2 = RationaleFactory.eINSTANCE.createIssue();
Solution solution = RationaleFactory.eINSTANCE.createSolution();
getProject().addModelElement(issue1);
getProject().addModelElement(issue2);
getProject().addModelElement(solution);
issue1.setSolution(solution);
assertEquals(issue1.getSolution(), solution);
clearOperations();
solution.setIssue(issue2);
assertNull(issue1.getSolution());
assertSame(issue2.getSolution(), solution);
List<AbstractOperation> operations = getProjectSpace().getOperations();
assertEquals(1, operations.size());
AbstractOperation operation = operations.get(0);
assertEquals(true, operation instanceof CompositeOperation);
List<AbstractOperation> subOperations = ((CompositeOperation) operation).getSubOperations();
assertEquals(3, subOperations.size());
ModelElementId solutionId = ModelUtil.getProject(solution).getModelElementId(solution);
ModelElementId issue1Id = ModelUtil.getProject(issue1).getModelElementId(issue1);
ModelElementId issue2Id = ModelUtil.getProject(issue2).getModelElementId(issue2);
AbstractOperation op = subOperations.get(0);
assertEquals(true, op instanceof SingleReferenceOperation);
SingleReferenceOperation op0 = (SingleReferenceOperation) op;
assertEquals(solutionId, op0.getOldValue());
assertEquals(null, op0.getNewValue());
assertEquals("solution", op0.getFeatureName());
assertEquals(issue1Id, op0.getModelElementId());
op = subOperations.get(1);
assertEquals(true, op instanceof SingleReferenceOperation);
SingleReferenceOperation op1 = (SingleReferenceOperation) op;
assertEquals(null, op1.getOldValue());
assertEquals(solutionId, op1.getNewValue());
assertEquals("solution", op1.getFeatureName());
assertEquals(issue2Id, op1.getModelElementId());
op = subOperations.get(2);
assertTrue(op instanceof SingleReferenceOperation);
SingleReferenceOperation op2 = (SingleReferenceOperation) op;
assertEquals(solutionId, op2.getModelElementId());
assertEquals("issue", op2.getFeatureName());
assertEquals(issue1Id, op2.getOldValue());
assertEquals(issue2Id, op2.getNewValue());
}
/**
* Change an containment attribute from some reference to some other reference, and check resulting op.
*
* @throws UnsupportedOperationException on test fail
* @throws UnsupportedNotificationException on test fail
*/
@Test
public void containmentNullToOtherValueContainedAlready1OperateOnParent() throws UnsupportedOperationException,
UnsupportedNotificationException {
Issue issue1 = RationaleFactory.eINSTANCE.createIssue();
Issue issue2 = RationaleFactory.eINSTANCE.createIssue();
Solution solution = RationaleFactory.eINSTANCE.createSolution();
getProject().addModelElement(issue1);
getProject().addModelElement(issue2);
getProject().addModelElement(solution);
issue1.setSolution(solution);
assertEquals(issue1.getSolution(), solution);
clearOperations();
issue2.setSolution(solution);
assertNull(issue1.getSolution());
assertSame(issue2.getSolution(), solution);
List<AbstractOperation> operations = getProjectSpace().getOperations();
// expecting a composite operation here
assertEquals(1, operations.size());
if (operations.get(0) instanceof CompositeOperation) {
operations = ((CompositeOperation) operations.get(0)).getSubOperations();
} else {
fail("composite operation expected");
}
assertEquals(3, operations.size());
AbstractOperation op0 = operations.get(0);
assertTrue(op0 instanceof SingleReferenceOperation);
SingleReferenceOperation refOp0 = (SingleReferenceOperation) op0;
ModelElementId solutionId = ModelUtil.getProject(solution).getModelElementId(solution);
ModelElementId issue1Id = ModelUtil.getProject(issue1).getModelElementId(issue1);
ModelElementId issue2Id = ModelUtil.getProject(issue2).getModelElementId(issue2);
assertEquals(issue1Id, refOp0.getModelElementId());
assertEquals("solution", refOp0.getFeatureName());
assertEquals(solutionId, refOp0.getOldValue());
assertEquals(null, refOp0.getNewValue());
AbstractOperation op1 = operations.get(1);
assertTrue(op1 instanceof SingleReferenceOperation);
SingleReferenceOperation refOp1 = (SingleReferenceOperation) op1;
assertEquals(solutionId, refOp1.getModelElementId());
assertEquals("issue", refOp1.getFeatureName());
assertEquals(issue1Id, refOp1.getOldValue());
assertEquals(issue2Id, refOp1.getNewValue());
AbstractOperation op2 = operations.get(2);
assertTrue(op2 instanceof SingleReferenceOperation);
SingleReferenceOperation refOp2 = (SingleReferenceOperation) op2;
assertEquals(issue2Id, refOp2.getModelElementId());
assertEquals("solution", refOp2.getFeatureName());
assertNull(refOp2.getOldValue());
assertEquals(solutionId, refOp2.getNewValue());
}
/**
* Change an containment attribute from some reference to some other reference, and check resulting op.
*
* @throws UnsupportedOperationException on test fail
* @throws UnsupportedNotificationException on test fail
*/
@Test
public void containmentValueToOtherValueContainedAlreadyNOperateOnParent() throws UnsupportedOperationException,
UnsupportedNotificationException {
Issue issue = RationaleFactory.eINSTANCE.createIssue();
LeafSection leafSection = DocumentFactory.eINSTANCE.createLeafSection();
Solution solution1 = RationaleFactory.eINSTANCE.createSolution();
Solution solution2 = RationaleFactory.eINSTANCE.createSolution();
getProject().addModelElement(issue);
getProject().addModelElement(leafSection);
getProject().addModelElement(solution1);
getProject().addModelElement(solution2);
leafSection.getModelElements().add(solution2);
issue.setSolution(solution1);
assertEquals(issue.getSolution(), solution1);
assertTrue(leafSection.getModelElements().contains(solution2));
clearOperations();
ModelElementId solution1Id = ModelUtil.getProject(solution1).getModelElementId(solution1);
issue.setSolution(solution2);
assertSame(solution2, issue.getSolution());
assertTrue(leafSection.getModelElements().isEmpty());
List<AbstractOperation> operations = getProjectSpace().getOperations();
// expecting a composite operation here
assertEquals(1, operations.size());
if (operations.get(0) instanceof CompositeOperation) {
operations = ((CompositeOperation) operations.get(0)).getSubOperations();
} else {
fail("composite operation expected");
}
assertEquals(5, operations.size());
AbstractOperation op0 = operations.get(0);
AbstractOperation op1 = operations.get(1);
AbstractOperation op2 = operations.get(2);
AbstractOperation op3 = operations.get(3);
AbstractOperation op4 = operations.get(4);
assertEquals(true, op0 instanceof SingleReferenceOperation);
assertEquals(true, op1 instanceof MultiReferenceOperation);
assertEquals(true, op2 instanceof SingleReferenceOperation);
assertEquals(true, op3 instanceof SingleReferenceOperation);
assertEquals(true, op4 instanceof SingleReferenceOperation);
SingleReferenceOperation refOp0 = (SingleReferenceOperation) op0;
MultiReferenceOperation refOp1 = (MultiReferenceOperation) op1;
SingleReferenceOperation refOp2 = (SingleReferenceOperation) op2;
SingleReferenceOperation refOp3 = (SingleReferenceOperation) op3;
SingleReferenceOperation refOp4 = (SingleReferenceOperation) op4;
// please note: 3 ops are necessary, this is because the oldvalues are necessary for
// the ops to be reversible! we also need track the index of issue 2 inside its former parent!
ModelElementId solution2Id = ModelUtil.getProject(solution2).getModelElementId(solution2);
ModelElementId issueId = ModelUtil.getProject(issue).getModelElementId(issue);
ModelElementId leafSectionId = ModelUtil.getProject(leafSection).getModelElementId(leafSection);
assertEquals(issueId, refOp0.getOldValue());
assertNull(refOp0.getNewValue());
assertEquals("issue", refOp0.getFeatureName());
assertEquals(solution1Id, refOp0.getModelElementId());
// leaf section annouces loss of solution2 at index 0
assertEquals("modelElements", refOp1.getFeatureName());
assertEquals(leafSectionId, refOp1.getModelElementId());
assertFalse(refOp1.isAdd());
assertEquals(1, refOp1.getReferencedModelElements().size());
assertEquals(refOp1.getReferencedModelElements().get(0), solution2Id);
assertEquals(leafSectionId, refOp2.getOldValue());
assertNull(refOp2.getNewValue());
assertEquals("leafSection", refOp2.getFeatureName());
assertEquals(solution2Id, refOp2.getModelElementId());
assertEquals(solution2Id, refOp3.getModelElementId());
assertEquals(null, refOp3.getOldValue());
assertEquals(issueId, refOp3.getNewValue());
assertEquals("issue", refOp3.getFeatureName());
// the issue 1 is getting its new child
assertEquals(solution1Id, refOp4.getOldValue());
assertEquals(solution2Id, refOp4.getNewValue());
assertEquals("solution", refOp4.getFeatureName());
assertEquals(issueId, refOp4.getModelElementId());
}
/**
* Change an containment attribute from some reference to some other reference, and check resulting op.
*
* @throws UnsupportedOperationException on test fail
* @throws UnsupportedNotificationException on test fail
*/
@Test
public void containmentValueToOtherValueContainedAlreadyNOperateOnChild() throws UnsupportedOperationException,
UnsupportedNotificationException {
Issue issue = RationaleFactory.eINSTANCE.createIssue();
LeafSection leafSection = DocumentFactory.eINSTANCE.createLeafSection();
Solution solution1 = RationaleFactory.eINSTANCE.createSolution();
Solution solution2 = RationaleFactory.eINSTANCE.createSolution();
getProject().addModelElement(issue);
getProject().addModelElement(leafSection);
getProject().addModelElement(solution1);
getProject().addModelElement(solution2);
leafSection.getModelElements().add(solution2);
issue.setSolution(solution1);
assertEquals(issue.getSolution(), solution1);
assertTrue(leafSection.getModelElements().contains(solution2));
clearOperations();
ModelElementId solution1Id = ModelUtil.getProject(solution1).getModelElementId(solution1);
solution2.setIssue(issue);
assertSame(solution2, issue.getSolution());
assertTrue(leafSection.getModelElements().isEmpty());
List<AbstractOperation> operations = getProjectSpace().getOperations();
// expecting a composite operation here
assertEquals(1, operations.size());
if (operations.get(0) instanceof CompositeOperation) {
operations = ((CompositeOperation) operations.get(0)).getSubOperations();
} else {
fail("composite operation expected");
}
assertEquals(5, operations.size());
AbstractOperation op0 = operations.get(0);
AbstractOperation op1 = operations.get(1);
AbstractOperation op2 = operations.get(2);
AbstractOperation op3 = operations.get(3);
AbstractOperation op4 = operations.get(4);
assertEquals(true, op0 instanceof MultiReferenceOperation);
assertEquals(true, op1 instanceof SingleReferenceOperation);
assertEquals(true, op2 instanceof SingleReferenceOperation);
assertEquals(true, op3 instanceof SingleReferenceOperation);
assertEquals(true, op4 instanceof SingleReferenceOperation);
MultiReferenceOperation refOp0 = (MultiReferenceOperation) op0;
SingleReferenceOperation refOp1 = (SingleReferenceOperation) op1;
SingleReferenceOperation refOp2 = (SingleReferenceOperation) op2;
SingleReferenceOperation refOp3 = (SingleReferenceOperation) op3;
SingleReferenceOperation refOp4 = (SingleReferenceOperation) op4;
// due to refactoring additional operation
// please note: 4 ops are necessary from this perspective
// 0. index inside old parent of solution 2 must be tracked (index inside leafsection.modelElements)
// 1. old solution of issue must be tracked
// 2. old parent of solution 2 must be tracked (the leafsection)
// 3. solution2 must announce its new issue
ModelElementId solution2Id = ModelUtil.getProject(solution2).getModelElementId(solution2);
ModelElementId issueId = ModelUtil.getProject(issue).getModelElementId(issue);
ModelElementId leafSectionId = ModelUtil.getProject(leafSection).getModelElementId(leafSection);
// leaf section annouces loss of solution2 at index 0
assertEquals("modelElements", refOp0.getFeatureName());
assertEquals(leafSectionId, refOp0.getModelElementId());
assertFalse(refOp0.isAdd());
assertEquals(1, refOp0.getReferencedModelElements().size());
assertEquals(refOp0.getReferencedModelElements().get(0), solution2Id);
assertEquals(solution1Id, refOp1.getModelElementId());
assertEquals("issue", refOp1.getFeatureName());
assertEquals(issueId, refOp1.getOldValue());
assertEquals(null, refOp1.getNewValue());
assertEquals(issueId, refOp2.getModelElementId());
assertEquals("solution", refOp2.getFeatureName());
assertEquals(solution1Id, refOp2.getOldValue());
assertEquals(solution2Id, refOp2.getNewValue());
assertEquals(solution2Id, refOp3.getModelElementId());
assertEquals("leafSection", refOp3.getFeatureName());
assertEquals(leafSectionId, refOp3.getOldValue());
assertNull(refOp3.getNewValue());
assertEquals(solution2Id, refOp4.getModelElementId());
assertEquals("issue", refOp4.getFeatureName());
assertNull(refOp4.getOldValue());
assertEquals(issueId, refOp4.getNewValue());
}
/**
* Change an containment attribute from some reference to some other reference, and check resulting op.
*
* @throws UnsupportedOperationException on test fail
* @throws UnsupportedNotificationException on test fail
*/
@Test
public void containmentNullToValueContainedAlreadyNOperateOnParent() throws UnsupportedOperationException,
UnsupportedNotificationException {
Issue issue = RationaleFactory.eINSTANCE.createIssue();
LeafSection leafSection = DocumentFactory.eINSTANCE.createLeafSection();
Solution solution = RationaleFactory.eINSTANCE.createSolution();
getProject().addModelElement(issue);
getProject().addModelElement(leafSection);
getProject().addModelElement(solution);
leafSection.getModelElements().add(solution);
assertTrue(leafSection.getModelElements().contains(solution));
clearOperations();
issue.setSolution(solution);
assertSame(solution, issue.getSolution());
assertTrue(leafSection.getModelElements().isEmpty());
List<AbstractOperation> operations = getProjectSpace().getOperations();
// expecting a composite operation here
assertEquals(1, operations.size());
if (operations.get(0) instanceof CompositeOperation) {
operations = ((CompositeOperation) operations.get(0)).getSubOperations();
} else {
fail("composite operation expected");
}
assertEquals(4, operations.size());
AbstractOperation op0 = operations.get(0);
AbstractOperation op1 = operations.get(1);
AbstractOperation op2 = operations.get(2);
AbstractOperation op3 = operations.get(3);
assertEquals(true, op0 instanceof MultiReferenceOperation);
assertEquals(true, op1 instanceof SingleReferenceOperation);
assertEquals(true, op2 instanceof SingleReferenceOperation);
assertEquals(true, op3 instanceof SingleReferenceOperation);
MultiReferenceOperation refOp0 = (MultiReferenceOperation) op0;
SingleReferenceOperation refOp1 = (SingleReferenceOperation) op1;
SingleReferenceOperation refOp2 = (SingleReferenceOperation) op2;
SingleReferenceOperation refOp3 = (SingleReferenceOperation) op3;
// due to refactoring one addtional operation
// please note: 3 ops are necessary, this is because the oldvalues are necessary for
// the ops to be reversible! we also need track the index of issue 2 inside its former parent!
ModelElementId solutionId = ModelUtil.getProject(solution).getModelElementId(solution);
ModelElementId issueId = ModelUtil.getProject(issue).getModelElementId(issue);
ModelElementId leafSectionId = ModelUtil.getProject(leafSection).getModelElementId(leafSection);
// leaf section announces loss of solution2 at index 0
assertEquals("modelElements", refOp0.getFeatureName());
assertEquals(leafSectionId, refOp0.getModelElementId());
assertFalse(refOp0.isAdd());
assertEquals(1, refOp0.getReferencedModelElements().size());
assertEquals(refOp0.getReferencedModelElements().get(0), solutionId);
// first solution is losing its old leaf section parent
assertEquals(solutionId, refOp1.getModelElementId());
assertEquals("leafSection", refOp1.getFeatureName());
assertEquals(leafSectionId, refOp1.getOldValue());
assertNull(refOp1.getNewValue());
assertEquals(solutionId, refOp2.getModelElementId());
assertEquals("issue", refOp2.getFeatureName());
assertEquals(null, refOp2.getOldValue());
assertEquals(issueId, refOp2.getNewValue());
// second the solution is getting its new issue
assertEquals(issueId, refOp3.getModelElementId());
assertEquals("solution", refOp3.getFeatureName());
assertNull(refOp3.getOldValue());
assertEquals(solutionId, refOp3.getNewValue());
}
/**
* Change an containment attribute from some reference to some other reference, and check resulting op.
*
* @throws UnsupportedOperationException on test fail
* @throws UnsupportedNotificationException on test fail
*/
@Test
public void containmentNullToValueContainedAlreadyNOperateOnChild() throws UnsupportedOperationException,
UnsupportedNotificationException {
Issue issue = RationaleFactory.eINSTANCE.createIssue();
LeafSection leafSection = DocumentFactory.eINSTANCE.createLeafSection();
Solution solution = RationaleFactory.eINSTANCE.createSolution();
getProject().addModelElement(issue);
getProject().addModelElement(leafSection);
getProject().addModelElement(solution);
leafSection.getModelElements().add(solution);
assertTrue(leafSection.getModelElements().contains(solution));
clearOperations();
solution.setIssue(issue);
assertSame(solution, issue.getSolution());
assertTrue(leafSection.getModelElements().isEmpty());
List<AbstractOperation> operations = getProjectSpace().getOperations();
// expecting a composite operation here
assertEquals(1, operations.size());
if (operations.get(0) instanceof CompositeOperation) {
operations = ((CompositeOperation) operations.get(0)).getSubOperations();
} else {
fail("composite operation expected");
}
assertEquals(4, operations.size());
AbstractOperation op0 = operations.get(0);
AbstractOperation op1 = operations.get(1);
AbstractOperation op2 = operations.get(2);
AbstractOperation op3 = operations.get(3);
assertEquals(true, op0 instanceof MultiReferenceOperation);
assertEquals(true, op1 instanceof SingleReferenceOperation);
assertEquals(true, op2 instanceof SingleReferenceOperation);
assertEquals(true, op3 instanceof SingleReferenceOperation);
MultiReferenceOperation refOp0 = (MultiReferenceOperation) op0;
SingleReferenceOperation refOp1 = (SingleReferenceOperation) op1;
SingleReferenceOperation refOp2 = (SingleReferenceOperation) op2;
SingleReferenceOperation refOp3 = (SingleReferenceOperation) op3;
// due to refactoring one additional operation
// please note: 3 ops are necessary, this is because the oldvalues are necessary for
// the ops to be reversible! we also need track the index of issue 2 inside its former parent!
// please note: 3 ops are necessary from this perspective
// 1. old solution of issue must be tracked
// 2. old parent of solution 2 must be tracked (the leafsection)
// 3. solution2 must announce its new issue
ModelElementId solutionId = ModelUtil.getProject(solution).getModelElementId(solution);
ModelElementId issueId = ModelUtil.getProject(issue).getModelElementId(issue);
ModelElementId leafSectionId = ModelUtil.getProject(leafSection).getModelElementId(leafSection);
// leaf section announces loss of solution at index 0
assertEquals("modelElements", refOp0.getFeatureName());
assertEquals(leafSectionId, refOp0.getModelElementId());
assertFalse(refOp0.isAdd());
assertEquals(1, refOp0.getReferencedModelElements().size());
assertEquals(refOp0.getReferencedModelElements().get(0), solutionId);
assertEquals(issueId, refOp1.getModelElementId());
assertEquals("solution", refOp1.getFeatureName());
assertEquals(solutionId, refOp1.getNewValue());
assertEquals(null, refOp1.getOldValue());
assertEquals(solutionId, refOp2.getModelElementId());
assertEquals("leafSection", refOp2.getFeatureName());
assertNull(refOp2.getNewValue());
assertEquals(leafSectionId, refOp2.getOldValue());
assertEquals(solutionId, refOp3.getModelElementId());
assertEquals("issue", refOp3.getFeatureName());
assertNull(refOp3.getOldValue());
assertEquals(issueId, refOp3.getNewValue());
}
/**
* Change an containment attribute from some reference to null, and check resulting op.
*
* @throws UnsupportedOperationException on test fail
* @throws UnsupportedNotificationException on test fail
*/
@Test
public void containmentValueToNullOperateOnParent() throws UnsupportedOperationException,
UnsupportedNotificationException {
Issue issue = RationaleFactory.eINSTANCE.createIssue();
Solution solution = RationaleFactory.eINSTANCE.createSolution();
assertEquals(issue.getSolution(), null);
getProject().addModelElement(issue);
getProject().addModelElement(solution);
issue.setSolution(solution);
clearOperations();
assertSame(solution, issue.getSolution());
ModelElementId solutionId = ModelUtil.getProject(solution).getModelElementId(solution);
issue.setSolution(null);
List<AbstractOperation> operations = getProjectSpace().getOperations();
assertEquals(1, operations.size());
AbstractOperation operation = operations.get(0);
assertEquals(true, operation instanceof CompositeOperation);
List<AbstractOperation> subOperations = ((CompositeOperation) operation).getSubOperations();
assertEquals(2, subOperations.size());
ModelElementId issueId = ModelUtil.getProject(issue).getModelElementId(issue);
AbstractOperation op = subOperations.get(0);
assertEquals(true, op instanceof SingleReferenceOperation);
SingleReferenceOperation refOp0 = (SingleReferenceOperation) op;
assertEquals(null, refOp0.getNewValue());
assertEquals(issueId, refOp0.getOldValue());
assertEquals("issue", refOp0.getFeatureName());
assertEquals(solutionId, refOp0.getModelElementId());
op = subOperations.get(1);
assertEquals(true, op instanceof SingleReferenceOperation);
SingleReferenceOperation refOp1 = (SingleReferenceOperation) op;
assertEquals(null, refOp1.getNewValue());
assertEquals(solutionId, refOp1.getOldValue());
assertEquals("solution", refOp1.getFeatureName());
assertEquals(issueId, refOp1.getModelElementId());
}
/**
* Change an containment attribute from some reference to null, and check resulting op.
*
* @throws UnsupportedOperationException on test fail
* @throws UnsupportedNotificationException on test fail
*/
@Test
public void containmentValueToNullOperateOnChild() throws UnsupportedOperationException,
UnsupportedNotificationException {
Issue issue = RationaleFactory.eINSTANCE.createIssue();
Solution solution = RationaleFactory.eINSTANCE.createSolution();
assertEquals(issue.getSolution(), null);
getProject().addModelElement(issue);
getProject().addModelElement(solution);
issue.setSolution(solution);
clearOperations();
assertSame(solution, issue.getSolution());
ModelElementId solutionId = ModelUtil.getProject(solution).getModelElementId(solution);
solution.setIssue(null);
List<AbstractOperation> operations = getProjectSpace().getOperations();
assertEquals(1, operations.size());
AbstractOperation operation = operations.get(0);
assertEquals(true, operation instanceof CompositeOperation);
List<AbstractOperation> subOperations = ((CompositeOperation) operation).getSubOperations();
ModelElementId issueId = ModelUtil.getProject(issue).getModelElementId(issue);
assertEquals(2, subOperations.size());
AbstractOperation op = subOperations.get(0);
assertEquals(true, op instanceof SingleReferenceOperation);
SingleReferenceOperation refOp0 = (SingleReferenceOperation) op;
assertEquals(null, refOp0.getNewValue());
assertEquals(solutionId, refOp0.getOldValue());
assertEquals("solution", refOp0.getFeatureName());
assertEquals(issueId, refOp0.getModelElementId());
op = subOperations.get(1);
assertEquals(true, op instanceof SingleReferenceOperation);
SingleReferenceOperation refOp1 = (SingleReferenceOperation) op;
assertEquals(null, refOp1.getNewValue());
assertEquals(issueId, refOp1.getOldValue());
assertEquals("issue", refOp1.getFeatureName());
assertEquals(solutionId, refOp1.getModelElementId());
}
}