/**
* Copyright (c) 2004-2006 IBM Corporation and others.
* 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
*
* Contributors:
* IBM - Initial API and implementation
*/
package org.eclipse.emf.test.edit.command;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import org.eclipse.emf.common.command.BasicCommandStack;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CommandStack;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.edit.command.RemoveCommand;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.test.models.ref.A;
import org.eclipse.emf.test.models.ref.B;
import org.eclipse.emf.test.models.ref.C;
import org.eclipse.emf.test.models.ref.D;
import org.eclipse.emf.test.models.ref.E;
import org.eclipse.emf.test.models.ref.RefFactory;
import org.eclipse.emf.test.models.ref.RefPackage;
import org.eclipse.emf.test.models.ref.provider.RefItemProviderAdapterFactory;
import org.junit.Before;
import org.junit.Test;
/**
* Tests for SetCommand.
* This exercises the cases in {@link SetCommand#create(EditingDomain, Object, Object, Object, int) SetCommand.create} for which different
* command may be returned. In each case, the model is built, the command is created, executed, undone, and redone.
* The state of the model and the executability/undoability/redoability of the command are tested between each step.
*/
public class SetCommandTest
{
/**
* The Ref test package, which includes all the various combinations of bidirectionality, multiplicity, and
* containment in references.
*/
protected RefPackage refPackage;
/**
* The Ref factory.
*/
protected RefFactory refFactory;
/**
* And editing domain for for these tests.
*/
protected EditingDomain editingDomain;
@Before
public void setUp() throws Exception
{
refPackage = RefPackage.eINSTANCE;
refFactory = refPackage.getRefFactory();
AdapterFactory adapterFactory = new RefItemProviderAdapterFactory();
CommandStack commandStack = new BasicCommandStack();
editingDomain = new AdapterFactoryEditingDomain(adapterFactory, commandStack);
}
@Test
public void testDuplicate()
{
C c = refFactory.createC();
D d0 = refFactory.createD();
D d1 = refFactory.createD();
D d2 = refFactory.createD();
EList<D> d = c.getD();
d.add(d0);
d.add(d1);
d.add(d2);
Command set = SetCommand.create(editingDomain, c, refPackage.getC_D(), d2, 0);
assertFalse(set.canExecute());
}
@Test
public void testDuplicateInUniqueAttribute()
{
E e = refFactory.createE();
String s0 = "0";
String s1 = "1";
String s2 = "2";
EList<String> ids = e.getIds();
ids.add(s0);
ids.add(s1);
ids.add(s2);
Command set = SetCommand.create(editingDomain, e, refPackage.getE_Ids(), s2, 0);
assertFalse(set.canExecute());
}
@Test
public void testDuplicateInAttribute()
{
E e = refFactory.createE();
String s0 = "0";
String s1 = "1";
String s2 = "2";
EList<String> labels = e.getLabels();
labels.add(s0);
labels.add(s1);
labels.add(s2);
Command set = SetCommand.create(editingDomain, e, refPackage.getE_Labels(), s2, 0);
assertEquals(s0, labels.get(0));
assertTrue(set.canExecute());
CommandStack stack = editingDomain.getCommandStack();
stack.execute(set);
assertEquals(s2, labels.get(0));
assertTrue(stack.canUndo());
stack.undo();
assertEquals(s0, labels.get(0));
assertTrue(stack.canRedo());
stack.redo();
assertEquals(s2, labels.get(0));
assertTrue(stack.canUndo());
}
@Test
public void testManyToManySimple()
{
D d0 = refFactory.createD();
D d1 = refFactory.createD();
E e0 = refFactory.createE();
E e1 = refFactory.createE();
E e2 = refFactory.createE();
E e3 = refFactory.createE();
d0.getE().add(e0);
d1.getE().add(e1);
d0.getE().add(e1);
d0.getE().add(e2);
Command set = SetCommand.create(editingDomain, d0, refPackage.getD_E(), e3, 1);
assertEquals(e1, d0.getE().get(1));
assertEquals(d0, e1.getD().get(1));
assertTrue(e3.getD().isEmpty());
assertTrue(set.canExecute());
CommandStack stack = editingDomain.getCommandStack();
stack.execute(set);
assertEquals(e3, d0.getE().get(1));
assertEquals(d0, e3.getD().get(0));
assertEquals(1, e1.getD().size());
assertEquals(d1, e1.getD().get(0));
assertEquals(e1, d1.getE().get(0));
assertTrue(stack.canUndo());
stack.undo();
assertEquals(e1, d0.getE().get(1));
assertEquals(d0, e1.getD().get(1));
assertTrue(e3.getD().isEmpty());
assertTrue(set.canExecute());
stack.redo();
assertEquals(e3, d0.getE().get(1));
assertEquals(d0, e3.getD().get(0));
assertEquals(1, e1.getD().size());
assertEquals(d1, e1.getD().get(0));
assertEquals(e1, d1.getE().get(0));
}
@Test
public void testManyToMany()
{
D d0 = refFactory.createD();
D d1 = refFactory.createD();
E e0 = refFactory.createE();
E e1 = refFactory.createE();
E e2 = refFactory.createE();
E e3 = refFactory.createE();
d0.getE().add(e0);
d0.getE().add(e1);
d0.getE().add(e2);
d1.getE().add(e2);
Command set = SetCommand.create(editingDomain, d0, refPackage.getD_E(), e3, 2);
assertEquals(e2, d0.getE().get(2));
assertEquals(d0, e2.getD().get(0));
assertTrue(e3.getD().isEmpty());
assertTrue(set.canExecute());
CommandStack stack = editingDomain.getCommandStack();
stack.execute(set);
assertEquals(e3, d0.getE().get(2));
assertEquals(d0, e3.getD().get(0));
assertEquals(d1, e2.getD().get(0));
assertEquals(e2, d1.getE().get(0));
assertTrue(stack.canUndo());
stack.undo();
assertEquals(e2, d0.getE().get(2));
assertEquals(d0, e2.getD().get(0));
assertTrue(e3.getD().isEmpty());
assertTrue(set.canExecute());
stack.redo();
assertEquals(e3, d0.getE().get(2));
assertEquals(d0, e3.getD().get(0));
assertEquals(d1, e2.getD().get(0));
assertEquals(e2, d1.getE().get(0));
}
@Test
public void testManyToManyNonUndoable()
{
D d0 = refFactory.createD();
D d1 = refFactory.createD();
E e0 = refFactory.createE();
E e1 = refFactory.createE();
E e2 = refFactory.createE();
E e3 = refFactory.createE();
d0.getE().add(e0);
d0.getE().add(e1);
d0.getE().add(e2);
d1.getE().add(e1);
Command set = SetCommand.create(editingDomain, d0, refPackage.getD_E(), e3, 1);
assertEquals(e1, d0.getE().get(1));
assertEquals(d0, e1.getD().get(0));
assertTrue(e3.getD().isEmpty());
assertTrue(set.canExecute());
CommandStack stack = editingDomain.getCommandStack();
stack.execute(set);
assertEquals(e3, d0.getE().get(1));
assertEquals(d0, e3.getD().get(0));
assertEquals(1, e1.getD().size());
assertEquals(d1, e1.getD().get(0));
assertEquals(e1, d1.getE().get(0));
assertTrue(stack.canUndo());
stack.undo();
assertEquals(e1, d0.getE().get(1));
assertEquals(d0, e1.getD().get(0));
assertTrue(e3.getD().isEmpty());
}
@Test
public void testOneToManyStayNull()
{
D d0 = refFactory.createD();
Command set = SetCommand.create(editingDomain, d0, refPackage.getD_C(), null);
assertNull(d0.getC());
assertTrue(set.canExecute());
CommandStack stack = editingDomain.getCommandStack();
stack.execute(set);
assertNull(d0.getC());
assertTrue(stack.canUndo());
stack.undo();
assertNull(d0.getC());
assertTrue(stack.canRedo());
stack.redo();
assertNull(d0.getC());
}
@Test
public void testOneToManyNull()
{
D d0 = refFactory.createD();
D d1 = refFactory.createD();
D d2 = refFactory.createD();
C c0 = refFactory.createC();
d0.setC(c0);
d1.setC(c0);
d2.setC(c0);
Command set = SetCommand.create(editingDomain, d1, refPackage.getD_C(), null);
assertEquals(c0, d1.getC());
assertEquals(d1, c0.getD().get(1));
assertTrue(set.canExecute());
CommandStack stack = editingDomain.getCommandStack();
stack.execute(set);
assertEquals(null, d1.getC());
assertEquals(d2, c0.getD().get(1));
assertTrue(stack.canUndo());
stack.undo();
assertEquals(c0, d1.getC());
assertEquals(d1, c0.getD().get(1));
assertTrue(stack.canRedo());
stack.redo();
assertEquals(null, d1.getC());
assertEquals(d2, c0.getD().get(1));
}
@Test
public void testOneToManySimple()
{
D d0 = refFactory.createD();
D d1 = refFactory.createD();
C c0 = refFactory.createC();
d0.setC(c0);
Command set = SetCommand.create(editingDomain, d1, refPackage.getD_C(), c0);
assertNull(d1.getC());
assertEquals(1, c0.getD().size());
assertTrue(set.canExecute());
CommandStack stack = editingDomain.getCommandStack();
stack.execute(set);
assertEquals(c0, d1.getC());
assertEquals(d1, c0.getD().get(1));
assertTrue(stack.canUndo());
stack.undo();
assertNull(d1.getC());
assertEquals(1, c0.getD().size());
assertTrue(set.canExecute());
stack.redo();
assertEquals(c0, d1.getC());
assertEquals(d1, c0.getD().get(1));
}
@Test
public void testOneToMany()
{
D d0 = refFactory.createD();
D d1 = refFactory.createD();
C c0 = refFactory.createC();
C c1 = refFactory.createC();
d0.setC(c0);
d1.setC(c0);
Command set = SetCommand.create(editingDomain, d0, refPackage.getD_C(), c1);
assertEquals(c0, d0.getC());
assertEquals(d0, c0.getD().get(0));
assertTrue(c1.getD().isEmpty());
assertTrue(set.canExecute());
CommandStack stack = editingDomain.getCommandStack();
stack.execute(set);
assertEquals(c1, d0.getC());
assertEquals(d0, c1.getD().get(0));
assertEquals(d1, c0.getD().get(0));
assertTrue(stack.canUndo());
stack.undo();
assertEquals(c0, d0.getC());
assertEquals(d0, c0.getD().get(0));
assertTrue(c1.getD().isEmpty());
assertTrue(stack.canRedo());
stack.redo();
assertEquals(c1, d0.getC());
assertEquals(d0, c1.getD().get(0));
assertEquals(d1, c0.getD().get(0));
}
@Test
public void testManyToOneSimple()
{
C c0 = refFactory.createC();
D d0 = refFactory.createD();
D d1 = refFactory.createD();
D d2 = refFactory.createD();
D d3 = refFactory.createD();
c0.getD().add(d0);
c0.getD().add(d1);
c0.getD().add(d2);
Command set = SetCommand.create(editingDomain, c0, refPackage.getC_D(), d3, 1);
assertEquals(d1, c0.getD().get(1));
assertEquals(c0, d1.getC());
assertNull(d3.getC());
assertTrue(set.canExecute());
CommandStack stack = editingDomain.getCommandStack();
stack.execute(set);
assertEquals(d3, c0.getD().get(1));
assertEquals(c0, d3.getC());
assertNull(d1.getC());
assertTrue(stack.canUndo());
stack.undo();
assertEquals(d1, c0.getD().get(1));
assertEquals(c0, d1.getC());
assertNull(d3.getC());
assertTrue(stack.canRedo());
stack.redo();
assertEquals(d3, c0.getD().get(1));
assertEquals(c0, d3.getC());
assertNull(d1.getC());
}
@Test
public void testManyToOne()
{
C c0 = refFactory.createC();
C c1 = refFactory.createC();
D d0 = refFactory.createD();
D d1 = refFactory.createD();
D d2 = refFactory.createD();
D d3 = refFactory.createD();
D d4 = refFactory.createD();
c0.getD().add(d0);
c0.getD().add(d1);
c0.getD().add(d2);
c1.getD().add(d3);
c1.getD().add(d4);
Command set = SetCommand.create(editingDomain, c0, refPackage.getC_D(), d3, 1);
assertEquals(d1, c0.getD().get(1));
assertEquals(c0, d1.getC());
assertEquals(d3, c1.getD().get(0));
assertEquals(c1, d3.getC());
assertTrue(set.canExecute());
CommandStack stack = editingDomain.getCommandStack();
stack.execute(set);
assertEquals(d3, c0.getD().get(1));
assertEquals(c0, d3.getC());
assertNull(d1.getC());
assertEquals(d4, c1.getD().get(0));
assertTrue(stack.canUndo());
stack.undo();
assertEquals(d1, c0.getD().get(1));
assertEquals(c0, d1.getC());
assertEquals(d3, c1.getD().get(0));
assertEquals(c1, d3.getC());
assertTrue(stack.canRedo());
stack.redo();
assertEquals(d3, c0.getD().get(1));
assertEquals(c0, d3.getC());
assertNull(d1.getC());
assertEquals(d4, c1.getD().get(0));
}
@Test
public void testOneToOneSimple()
{
A a0 = refFactory.createA();
B b0 = refFactory.createB();
B b1 = refFactory.createB();
a0.setB(b0);
Command set = SetCommand.create(editingDomain, a0, refPackage.getA_B(), b1);
assertEquals(b0, a0.getB());
assertEquals(a0, b0.getA());
assertNull(b1.getA());
assertTrue(set.canExecute());
CommandStack stack = editingDomain.getCommandStack();
stack.execute(set);
assertEquals(b1, a0.getB());
assertEquals(a0, b1.getA());
assertNull(b0.getA());
assertTrue(stack.canUndo());
stack.undo();
assertEquals(b0, a0.getB());
assertEquals(a0, b0.getA());
assertNull(b1.getA());
assertTrue(stack.canRedo());
stack.redo();
assertEquals(b1, a0.getB());
assertEquals(a0, b1.getA());
assertNull(b0.getA());
}
@Test
public void testOneToOne()
{
A a0 = refFactory.createA();
A a1 = refFactory.createA();
B b0 = refFactory.createB();
B b1 = refFactory.createB();
a0.setB(b0);
a1.setB(b1);
Command set = SetCommand.create(editingDomain, a0, refPackage.getA_B(), b1);
assertEquals(b0, a0.getB());
assertEquals(a0, b0.getA());
assertEquals(b1, a1.getB());
assertEquals(a1, b1.getA());
assertTrue(set.canExecute());
CommandStack stack = editingDomain.getCommandStack();
stack.execute(set);
assertEquals(b1, a0.getB());
assertEquals(a0, b1.getA());
assertNull(a1.getB());
assertNull(b0.getA());
assertTrue(stack.canUndo());
stack.undo();
assertEquals(b0, a0.getB());
assertEquals(a0, b0.getA());
assertEquals(b1, a1.getB());
assertEquals(a1, b1.getA());
assertTrue(stack.canRedo());
stack.redo();
assertEquals(b1, a0.getB());
assertEquals(a0, b1.getA());
assertNull(a1.getB());
assertNull(b0.getA());
}
@Test
public void testManyStayEmpty()
{
B b = refFactory.createB();
Command set = SetCommand.create(editingDomain, b, refPackage.getB_D(), new BasicEList<Object>());
assertTrue(b.getD().isEmpty());
assertTrue(set.canExecute());
CommandStack stack = editingDomain.getCommandStack();
stack.execute(set);
assertTrue(b.getD().isEmpty());
assertTrue(stack.canUndo());
stack.undo();
assertTrue(b.getD().isEmpty());
assertTrue(stack.canRedo());
stack.redo();
assertTrue(b.getD().isEmpty());
}
/**
* Shows that undo on remove doesn't work properly in the many-to-many case. Should not be run as part of the suite.
*/
public void testBiDiRemove()
{
D d1 = refFactory.createD();
D d2 = refFactory.createD();
E e1 = refFactory.createE();
E e2 = refFactory.createE();
d1.getE().add(e1);
d1.getE().add(e2);
d2.getE().add(e1);
Command remove = RemoveCommand.create(editingDomain, d1, refPackage.getD_E(), e1);
assertEquals(e1, d1.getE().get(0));
assertEquals(d1, e1.getD().get(0));
assertTrue(remove.canExecute());
CommandStack stack = editingDomain.getCommandStack();
stack.execute(remove);
assertEquals(e2, d1.getE().get(0));
assertEquals(d2, e1.getD().get(0));
assertTrue(stack.canUndo());
stack.undo();
assertEquals(e1, d1.getE().get(0));
assertEquals(d1, e1.getD().get(0));
assertTrue(stack.canRedo());
stack.redo();
assertEquals(e2, d1.getE().get(0));
assertEquals(d2, e1.getD().get(0));
assertTrue(stack.canUndo());
}
}