/*
* Copyright (c) 2016, SQL Power Group Inc.
*
* This file is part of SQL Power Library.
*
* SQL Power Library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* SQL Power Library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package ca.sqlpower.object;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nonnull;
import junit.framework.TestCase;
import ca.sqlpower.dao.PersistedSPOProperty;
import ca.sqlpower.dao.PersistedSPObject;
import ca.sqlpower.dao.SPPersister.DataType;
import ca.sqlpower.object.annotation.Accessor;
import ca.sqlpower.object.annotation.NonBound;
import ca.sqlpower.object.annotation.NonProperty;
import ca.sqlpower.object.annotation.Transient;
import com.google.common.collect.ImmutableList;
public class DifferTest extends TestCase {
public static class DiffTestClass extends AbstractSPObject {
public static final List<Class<? extends SPObject>> allowedChildTypes =
new ImmutableList.Builder<Class<? extends SPObject>>()
.add(DiffTestClass.class)
.build();
@Override
@NonProperty
public List<? extends SPObject> getChildren() {
return null;
}
@Override
public void removeDependency(@Nonnull SPObject dependency) {
}
@Override
@NonBound
public List<? extends SPObject> getDependencies() {
return null;
}
@Override
@Transient
@Accessor
public List<Class<? extends SPObject>> getAllowedChildTypes() {
return null;
}
@Override
protected boolean removeChildImpl(SPObject child) {
return false;
}
}
public static class DiffTestClass2 extends AbstractSPObject {
public static final List<Class<? extends SPObject>> allowedChildTypes =
new ImmutableList.Builder<Class<? extends SPObject>>()
.add(DiffTestClass2.class)
.add(DiffTestClass.class)
.build();
@Override
@NonProperty
public List<? extends SPObject> getChildren() {
return null;
}
@Override
public void removeDependency(@Nonnull SPObject dependency) {
}
@Override
@NonBound
public List<? extends SPObject> getDependencies() {
return null;
}
@Override
@Transient
@Accessor
public List<Class<? extends SPObject>> getAllowedChildTypes() {
return null;
}
@Override
protected boolean removeChildImpl(SPObject child) {
return false;
}
}
Differ diff;
List<PersistedSPObject> testRevisionOneObjects;
List<PersistedSPObject> testRevisionTwoObjects;
List<PersistedSPOProperty> testRevisionOneProperties;
List<PersistedSPOProperty> testRevisionTwoProperties;
List<PersistedSPObject> objectsToRemove;
List<PersistedSPObject> objectsToAdd;
List<PersistedSPOProperty> propertiesToRemove;
List<PersistedSPOProperty> propertiesToAdd;
@Override
protected void setUp() throws Exception {
super.setUp();
testRevisionOneObjects = new ArrayList<PersistedSPObject>();
testRevisionTwoObjects = new ArrayList<PersistedSPObject>();
testRevisionOneProperties = new ArrayList<PersistedSPOProperty>();
testRevisionTwoProperties = new ArrayList<PersistedSPOProperty>();
objectsToRemove = new ArrayList<PersistedSPObject>();
objectsToAdd = new ArrayList<PersistedSPObject>();
propertiesToRemove = new ArrayList<PersistedSPOProperty>();
propertiesToAdd = new ArrayList<PersistedSPOProperty>();
diff = new Differ();
testRevisionOneObjects.add(new PersistedSPObject(null, DiffTestClass.class.getName(), "1", 0));
testRevisionOneObjects.add(new PersistedSPObject("1", DiffTestClass.class.getName(), "2", 0));
testRevisionOneObjects.add(new PersistedSPObject("1", DiffTestClass.class.getName(), "3", 1));
testRevisionOneObjects.add(new PersistedSPObject("1", DiffTestClass.class.getName(), "4", 2));
testRevisionOneObjects.add(new PersistedSPObject("2", DiffTestClass.class.getName(), "5", 0));
testRevisionOneObjects.add(new PersistedSPObject("2", DiffTestClass.class.getName(), "6", 1));
testRevisionOneObjects.add(new PersistedSPObject("4", DiffTestClass.class.getName(), "7", 0));
testRevisionOneProperties.add(new PersistedSPOProperty("1", "name", DataType.STRING, "A1", "A1", false));
testRevisionOneProperties.add(new PersistedSPOProperty("2", "name", DataType.STRING, "B1", "B1", false));
testRevisionOneProperties.add(new PersistedSPOProperty("3", "name", DataType.STRING, "B2", "B2", false));
testRevisionOneProperties.add(new PersistedSPOProperty("4", "name", DataType.STRING, "B3", "B3", false));
testRevisionOneProperties.add(new PersistedSPOProperty("5", "name", DataType.STRING, "C1", "C1", false));
testRevisionOneProperties.add(new PersistedSPOProperty("6", "name", DataType.STRING, "C2", "C2", false));
testRevisionOneProperties.add(new PersistedSPOProperty("7", "name", DataType.STRING, "D1", "D1", false));
testRevisionOneProperties.add(new PersistedSPOProperty("2", "value", DataType.INTEGER, 1, 1, false));
testRevisionOneProperties.add(new PersistedSPOProperty("7", "value", DataType.DOUBLE, 1.1, 1.1, false));
testRevisionTwoObjects.add(new PersistedSPObject(null, DiffTestClass.class.getName(), "1", 0));
testRevisionTwoObjects.add(new PersistedSPObject("1", DiffTestClass.class.getName(), "2", 0));
testRevisionTwoObjects.add(new PersistedSPObject("1", DiffTestClass.class.getName(), "3", 1));
testRevisionTwoObjects.add(new PersistedSPObject("1", DiffTestClass.class.getName(), "4", 2));
testRevisionTwoObjects.add(new PersistedSPObject("2", DiffTestClass.class.getName(), "5", 0));
testRevisionTwoObjects.add(new PersistedSPObject("2", DiffTestClass.class.getName(), "6", 1));
testRevisionTwoObjects.add(new PersistedSPObject("4", DiffTestClass.class.getName(), "7", 0));
testRevisionTwoProperties.add(new PersistedSPOProperty("1", "name", DataType.STRING, "A1", "A1", false));
testRevisionTwoProperties.add(new PersistedSPOProperty("2", "name", DataType.STRING, "B1", "B1", false));
testRevisionTwoProperties.add(new PersistedSPOProperty("3", "name", DataType.STRING, "B2", "B2", false));
testRevisionTwoProperties.add(new PersistedSPOProperty("4", "name", DataType.STRING, "B3", "B3", false));
testRevisionTwoProperties.add(new PersistedSPOProperty("5", "name", DataType.STRING, "C1", "C1", false));
testRevisionTwoProperties.add(new PersistedSPOProperty("6", "name", DataType.STRING, "C2", "C2", false));
testRevisionTwoProperties.add(new PersistedSPOProperty("7", "name", DataType.STRING, "D1", "D1", false));
testRevisionTwoProperties.add(new PersistedSPOProperty("2", "value", DataType.INTEGER, 1, 1, false));
testRevisionTwoProperties.add(new PersistedSPOProperty("7", "value", DataType.DOUBLE, 1.1, 1.1, false));
}
public void testIdenticalRevisions() {
diff.calcDiff(testRevisionOneObjects, testRevisionTwoObjects, testRevisionOneProperties, testRevisionTwoProperties);
assertEquals(diff.getPersistedSPOsToAdd().size(), 0);
assertEquals(diff.getPersistedSPOsToRemove().size(), 0);
assertEquals(diff.getPropertyDiffPersists().size(), 0);
}
public void testObjectAdditions() {
objectsToAdd.add(new PersistedSPObject("1", DiffTestClass.class.getName(), "8", 3));
objectsToAdd.add(new PersistedSPObject("2", DiffTestClass.class.getName(), "9", 2));
objectsToAdd.add(new PersistedSPObject("8", DiffTestClass.class.getName(), "10", 0));
testRevisionTwoObjects.addAll(objectsToAdd);
diff.calcDiff(testRevisionOneObjects, testRevisionTwoObjects, testRevisionOneProperties, testRevisionTwoProperties);
assertEquals(3, diff.getPersistedSPOsToAdd().size());
assertEquals(diff.getPersistedSPOsToRemove().size(), 0);
assertEquals(diff.getPropertyDiffPersists().size(), 0);
// Sort and compare the lists of object additions.
Collections.sort(diff.getPersistedSPOsToAdd());
Collections.sort(objectsToAdd);
assertEquals(diff.getPersistedSPOsToAdd(), objectsToAdd);
}
public void testObjectRemovals() {
objectsToRemove.add(new PersistedSPObject("1", DiffTestClass.class.getName(), "8", 3));
objectsToRemove.add(new PersistedSPObject("2", DiffTestClass.class.getName(), "9", 2));
PersistedSPObject child = new PersistedSPObject("8", DiffTestClass.class.getName(), "10", 0);
objectsToRemove.add(child);
testRevisionOneObjects.addAll(objectsToRemove);
objectsToRemove.remove(child); // this should not be persisted
diff.calcDiff(testRevisionOneObjects, testRevisionTwoObjects, testRevisionOneProperties, testRevisionTwoProperties);
assertEquals(diff.getPersistedSPOsToAdd().size(), 0);
assertEquals(diff.getPersistedSPOsToRemove().size(), 2);
assertEquals(diff.getPropertyDiffPersists().size(), 0);
Collections.sort(diff.getPersistedSPOsToRemove());
Collections.sort(objectsToRemove);
assertEquals(diff.getPersistedSPOsToRemove(), objectsToRemove);
}
public void testObjectAdditionsAndRemovals() {
objectsToRemove.add(new PersistedSPObject("1", DiffTestClass.class.getName(), "8", 3));
objectsToRemove.add(new PersistedSPObject("2", DiffTestClass.class.getName(), "9", 2));
PersistedSPObject child = new PersistedSPObject("8", DiffTestClass.class.getName(), "10", 0);
objectsToRemove.add(child);
testRevisionOneObjects.addAll(objectsToRemove);
objectsToRemove.remove(child);
objectsToAdd.add(new PersistedSPObject("1", DiffTestClass.class.getName(), "11", 3));
objectsToAdd.add(new PersistedSPObject("2", DiffTestClass.class.getName(), "12", 2));
objectsToAdd.add(new PersistedSPObject("4", DiffTestClass.class.getName(), "13", 1));
objectsToAdd.add(new PersistedSPObject("7", DiffTestClass.class.getName(), "14", 0));
testRevisionTwoObjects.addAll(objectsToAdd);
diff.calcDiff(testRevisionOneObjects, testRevisionTwoObjects, testRevisionOneProperties, testRevisionTwoProperties);
assertEquals(diff.getPersistedSPOsToAdd().size(), 4);
assertEquals(diff.getPersistedSPOsToRemove().size(), 2);
assertEquals(diff.getPropertyDiffPersists().size(), 0);
Collections.sort(diff.getPersistedSPOsToRemove());
Collections.sort(diff.getPersistedSPOsToAdd());
Collections.sort(objectsToRemove);
Collections.sort(objectsToAdd);
assertEquals(diff.getPersistedSPOsToRemove(), objectsToRemove);
assertEquals(diff.getPersistedSPOsToAdd(), objectsToAdd);
}
public void testAddedProperties() {
propertiesToAdd.add(new PersistedSPOProperty("3", "value", DataType.INTEGER, null, 2, true));
propertiesToAdd.add(new PersistedSPOProperty("4", "value", DataType.DOUBLE, null, 2.1, true));
testRevisionTwoProperties.addAll(propertiesToAdd);
diff.calcDiff(testRevisionOneObjects, testRevisionTwoObjects, testRevisionOneProperties, testRevisionTwoProperties);
assertEquals(diff.getPersistedSPOsToAdd().size(), 0);
assertEquals(diff.getPersistedSPOsToRemove().size(), 0);
assertEquals(diff.getPropertyDiffPersists().size(), 2);
Collections.sort(diff.getPropertyDiffPersists());
Collections.sort(propertiesToAdd);
assertEquals(diff.getPropertyDiffPersists(), propertiesToAdd);
}
public void testNulledProperties() {
testRevisionTwoProperties.remove(testRevisionTwoProperties.size() - 1);
testRevisionTwoProperties.remove(testRevisionTwoProperties.size() - 1);
diff.calcDiff(testRevisionOneObjects, testRevisionTwoObjects, testRevisionOneProperties, testRevisionTwoProperties);
assertEquals(diff.getPersistedSPOsToAdd().size(), 0);
assertEquals(diff.getPersistedSPOsToRemove().size(), 0);
assertEquals(diff.getPropertyDiffPersists().size(), 2);
Collections.sort(diff.getPropertyDiffPersists());
assertNull(diff.getPropertyDiffPersists().get(0).getNewValue());
assertEquals(diff.getPropertyDiffPersists().get(0).getUUID(), "2");
assertNull(diff.getPropertyDiffPersists().get(1).getNewValue());
assertEquals(diff.getPropertyDiffPersists().get(1).getUUID(), "7");
}
public void testChangedPropeties() {
testRevisionTwoProperties.remove(testRevisionTwoProperties.size() - 1);
testRevisionTwoProperties.remove(testRevisionTwoProperties.size() - 1);
testRevisionTwoProperties.remove(testRevisionTwoProperties.size() - 1);
propertiesToAdd.add(new PersistedSPOProperty("7", "name", DataType.STRING, "D1", "D1*", true));
propertiesToAdd.add(new PersistedSPOProperty("2", "value", DataType.INTEGER, 1, 2, true));
propertiesToAdd.add(new PersistedSPOProperty("7", "value", DataType.DOUBLE, 1.1, 2.1, true));
testRevisionTwoProperties.addAll(propertiesToAdd);
diff.calcDiff(testRevisionOneObjects, testRevisionTwoObjects, testRevisionOneProperties, testRevisionTwoProperties);
assertEquals(diff.getPersistedSPOsToAdd().size(), 0);
assertEquals(diff.getPersistedSPOsToRemove().size(), 0);
assertEquals(diff.getPropertyDiffPersists().size(), 3);
Collections.sort(diff.getPropertyDiffPersists());
Collections.sort(propertiesToAdd);
assertEquals(diff.getPropertyDiffPersists(), propertiesToAdd);
}
public void testPropertyAdditionsRemovalsAndChanges() {
objectsToRemove.add(new PersistedSPObject("1", DiffTestClass.class.getName(), "8", 3));
testRevisionOneObjects.addAll(objectsToRemove);
// Will be removed because of object's removal. However, there will be no property persist call.
propertiesToRemove.add(new PersistedSPOProperty("8", "name", DataType.STRING, null, "E1", true));
testRevisionOneProperties.addAll(propertiesToRemove);
objectsToAdd.add(new PersistedSPObject("4", DiffTestClass.class.getName(), "9", 1));
testRevisionTwoObjects.addAll(objectsToAdd);
propertiesToAdd.add(new PersistedSPOProperty("7", "name", DataType.STRING, "D1", "D1*", true));
propertiesToAdd.add(new PersistedSPOProperty("2", "value", DataType.INTEGER, 1, 2, true));
propertiesToAdd.add(new PersistedSPOProperty("7", "value", DataType.DOUBLE, 1.1, 2.1, true));
propertiesToAdd.add(new PersistedSPOProperty("9", "name", DataType.STRING, null, "F1", true));
testRevisionTwoProperties.addAll(propertiesToAdd);
diff.calcDiff(testRevisionOneObjects, testRevisionTwoObjects, testRevisionOneProperties, testRevisionTwoProperties);
assertEquals(diff.getPersistedSPOsToAdd().size(), 1);
assertEquals(diff.getPersistedSPOsToRemove().size(), 1);
assertEquals(diff.getPropertyDiffPersists().size(), 4);
assertEquals(diff.getPersistedSPOsToAdd(), objectsToAdd);
assertEquals(diff.getPersistedSPOsToRemove(), objectsToRemove);
Collections.sort(diff.getPropertyDiffPersists());
Collections.sort(propertiesToAdd);
assertEquals(diff.getPropertyDiffPersists(), propertiesToAdd);
}
// public void testMockPersisting() {
//
// objectsToRemove.add(new PersistedSPObject("1", DiffTestClass.class.getName(), "8", 3));
// testRevisionOneObjects.addAll(objectsToRemove);
//
// // Will be removed because of object's removal. However, there will be no property persist call.
// propertiesToRemove.add(new PersistedSPOProperty("8", "name", DataType.STRING, null, "E1", true));
// testRevisionOneProperties.addAll(propertiesToRemove);
//
// objectsToAdd.add(new PersistedSPObject("4", DiffTestClass.class.getName(), "9", 1));
// objectsToAdd.add(new PersistedSPObject("9", DiffTestClass.class.getName(), "10",0));
// testRevisionTwoObjects.addAll(objectsToAdd);
//
// testRevisionTwoProperties.remove(testRevisionTwoProperties.size() - 1);
// testRevisionTwoProperties.remove(testRevisionTwoProperties.size() - 1);
// testRevisionTwoProperties.remove(testRevisionTwoProperties.size() - 1);
//
// propertiesToAdd.add(new PersistedSPOProperty("7", "name", DataType.STRING, "D1", "D1*", true));
// propertiesToAdd.add(new PersistedSPOProperty("2", "value", DataType.INTEGER, 1, 2, true));
// propertiesToAdd.add(new PersistedSPOProperty("7", "value", DataType.DOUBLE, 1.1, 2.1, true));
// propertiesToAdd.add(new PersistedSPOProperty("9", "name", DataType.STRING, null, "F1", true));
// testRevisionTwoProperties.addAll(propertiesToAdd);
//
//
// MockJCRPersister mockJCR = new MockJCRPersister();
// mockJCR.addRevision(testRevisionOneObjects, testRevisionOneProperties);
// mockJCR.addRevision(testRevisionTwoObjects, testRevisionTwoProperties);
//
// try {
// diff.calcDiff(mockJCR, SPCredentials.createSystemInstance(), "test-id", 0, 1);
// } catch (SPPersistenceException e) {
// throw new RuntimeException(e);
// }
//
// assertEquals(diff.getPersistedSPOsToAdd().size(), 2);
// assertEquals(diff.getPersistedSPOsToRemove().size(), 1);
// assertEquals(diff.getPropertyDiffPersists().size(), 4);
//
// assertEquals(diff.getPersistedSPOsToRemove(), objectsToRemove);
//
// Collections.sort(diff.getPersistedSPOsToAdd());
// Collections.sort(objectsToAdd);
// assertEquals(diff.getPersistedSPOsToAdd(), objectsToAdd);
//
// Collections.sort(diff.getPropertyDiffPersists());
// Collections.sort(propertiesToAdd);
// assertEquals(diff.getPropertyDiffPersists(), propertiesToAdd);
//
// // Give the mock JCR the older revision again, so that the differ can modify it.
//
// mockJCR.addRevision(testRevisionOneObjects, testRevisionOneProperties); // revision 2
//
// // revision 3
// try {
// diff.persistTo(mockJCR, false);
// } catch (SPPersistenceException e) {
// throw new RuntimeException(e);
// }
//
// // Test that the revision has the right amount of objects and properties.
//
// Collections.sort(mockJCR.getObjectsFromRevision(3));
// Collections.sort(mockJCR.getPropertiesFromRevision(3));
// Collections.sort(testRevisionTwoObjects);
// Collections.sort(testRevisionTwoProperties);
// assertEquals(mockJCR.getObjectsFromRevision(3), testRevisionTwoObjects);
// assertEquals(mockJCR.getPropertiesFromRevision(3), testRevisionTwoProperties);
//
// }
@Override
protected void tearDown() throws Exception {
super.tearDown();
}
/**
* Regression test. Previously moving an object and adding a child
* to the moved object in the same transaction would add the object
* in twice in the end.
*/
public void testMoveObjectWithNewChild() throws Exception {
List<PersistedSPObject> oldList = new ArrayList<PersistedSPObject>();
oldList.add(new PersistedSPObject(null, DiffTestClass.class.getName(), "1", 0));
oldList.add(new PersistedSPObject("1", DiffTestClass.class.getName(), "2", 0));
oldList.add(new PersistedSPObject("1", DiffTestClass.class.getName(), "3", 1));
List<PersistedSPObject> newList = new ArrayList<PersistedSPObject>();
newList.add(new PersistedSPObject(null, DiffTestClass.class.getName(), "1", 0));
newList.add(new PersistedSPObject("1", DiffTestClass.class.getName(), "3", 0));
newList.add(new PersistedSPObject("1", DiffTestClass.class.getName(), "2", 1));
newList.add(new PersistedSPObject("2", DiffTestClass.class.getName(), "4", 0));
diff.calcDiff(oldList, newList,
new ArrayList<PersistedSPOProperty>(), new ArrayList<PersistedSPOProperty>());
int childCount = 0;
for (PersistedSPObject spo : diff.getPersistedSPOsToAdd()) {
if (spo.getUUID().equals("4")) {
childCount++;
}
}
//previously was coming out as 2
assertEquals(1, childCount);
}
/**
* If we add an object to the start of an existing list of objects we should
* just get the one addition. We shouldn't get the removal of a whole bunch
* of other objects
*/
public void testInsertWithoutRemovals() throws Exception {
List<PersistedSPObject> oldList = new ArrayList<PersistedSPObject>();
oldList.add(new PersistedSPObject(null, DiffTestClass.class.getName(), "1", 0));
oldList.add(new PersistedSPObject("1", DiffTestClass.class.getName(), "2", 0));
oldList.add(new PersistedSPObject("1", DiffTestClass.class.getName(), "3", 1));
List<PersistedSPObject> newList = new ArrayList<PersistedSPObject>();
newList.add(new PersistedSPObject(null, DiffTestClass.class.getName(), "1", 0));
newList.add(new PersistedSPObject("1", DiffTestClass.class.getName(), "4", 0));
newList.add(new PersistedSPObject("1", DiffTestClass.class.getName(), "2", 1));
newList.add(new PersistedSPObject("1", DiffTestClass.class.getName(), "3", 2));
diff.calcDiff(oldList, newList,
new ArrayList<PersistedSPOProperty>(), new ArrayList<PersistedSPOProperty>());
assertEquals(0, diff.getPersistedSPOsToRemove().size());
assertEquals(1, diff.getPersistedSPOsToAdd().size());
}
public void testChildrenOfDifferentTypes() throws Exception {
List<PersistedSPObject> oldList = new ArrayList<PersistedSPObject>();
oldList.add(new PersistedSPObject(null, DiffTestClass2.class.getName(), "1", 0));
oldList.add(new PersistedSPObject("1", DiffTestClass2.class.getName(), "2", 0));
oldList.add(new PersistedSPObject("1", DiffTestClass.class.getName(), "3", 0));
List<PersistedSPObject> newList = new ArrayList<PersistedSPObject>();
newList.add(new PersistedSPObject(null, DiffTestClass2.class.getName(), "1", 0));
newList.add(new PersistedSPObject("1", DiffTestClass2.class.getName(), "4", 0));
newList.add(new PersistedSPObject("1", DiffTestClass2.class.getName(), "2", 1));
newList.add(new PersistedSPObject("1", DiffTestClass.class.getName(), "3", 0));
diff.calcDiff(oldList, newList,
new ArrayList<PersistedSPOProperty>(), new ArrayList<PersistedSPOProperty>());
assertEquals(0, diff.getPersistedSPOsToRemove().size());
assertEquals(1, diff.getPersistedSPOsToAdd().size());
}
public void testMoveWithParentClass() throws Exception {
Differ diff = new Differ(DiffTestClass.class.getName());
List<PersistedSPObject> oldList = new ArrayList<PersistedSPObject>();
oldList.add(new PersistedSPObject("0", DiffTestClass.class.getName(), "1", 0));
oldList.add(new PersistedSPObject("0", DiffTestClass.class.getName(), "2", 1));
oldList.add(new PersistedSPObject("0", DiffTestClass.class.getName(), "3", 2));
List<PersistedSPObject> newList = new ArrayList<PersistedSPObject>();
newList.add(new PersistedSPObject("0", DiffTestClass.class.getName(), "1", 0));
newList.add(new PersistedSPObject("0", DiffTestClass.class.getName(), "4", 1));
newList.add(new PersistedSPObject("0", DiffTestClass.class.getName(), "2", 2));
newList.add(new PersistedSPObject("0", DiffTestClass.class.getName(), "3", 3));
diff.calcDiff(oldList, newList,
new ArrayList<PersistedSPOProperty>(), new ArrayList<PersistedSPOProperty>());
assertEquals(0, diff.getPersistedSPOsToRemove().size());
assertEquals(1, diff.getPersistedSPOsToAdd().size());
}
}