package de.invesdwin.util.bean;
import java.beans.PropertyChangeEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.annotation.concurrent.NotThreadSafe;
import org.junit.Test;
import de.invesdwin.util.assertions.Assertions;
@NotThreadSafe
public class DirtyTrackerTest {
@Test
public void testIsTrackingChangesDirectlyCascade() {
final OuterVo outer = newOuterVo();
//first on directly
outer.dirtyTracker().startTrackingChangesDirectly();
Assertions.assertThat(outer.dirtyTracker().isTrackingChanges()).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isTrackingChanges()).isTrue();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isTrackingChanges()).isTrue();
Assertions.assertThat(outer.dirtyTracker().isTrackingChangesDirectly()).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isTrackingChangesDirectly()).isFalse();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isTrackingChangesDirectly()).isFalse();
Assertions.assertThat(outer.getPropertyChangeListeners()).hasSize(1);
Assertions.assertThat(outer.getInner().getPropertyChangeListeners()).hasSize(1);
Assertions.assertThat(outer.getInner().getInner().getPropertyChangeListeners()).hasSize(1);
//second on directly
outer.getInner().dirtyTracker().startTrackingChangesDirectly();
Assertions.assertThat(outer.dirtyTracker().isTrackingChanges()).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isTrackingChanges()).isTrue();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isTrackingChanges()).isTrue();
Assertions.assertThat(outer.dirtyTracker().isTrackingChangesDirectly()).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isTrackingChangesDirectly()).isTrue();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isTrackingChangesDirectly()).isFalse();
Assertions.assertThat(outer.getPropertyChangeListeners()).hasSize(1);
Assertions.assertThat(outer.getInner().getPropertyChangeListeners()).hasSize(2);
Assertions.assertThat(outer.getInner().getInner().getPropertyChangeListeners()).hasSize(2);
//third on directly
outer.getInner().getInner().dirtyTracker().startTrackingChangesDirectly();
Assertions.assertThat(outer.dirtyTracker().isTrackingChanges()).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isTrackingChanges()).isTrue();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isTrackingChanges()).isTrue();
Assertions.assertThat(outer.dirtyTracker().isTrackingChangesDirectly()).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isTrackingChangesDirectly()).isTrue();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isTrackingChangesDirectly()).isTrue();
Assertions.assertThat(outer.getPropertyChangeListeners()).hasSize(1);
Assertions.assertThat(outer.getInner().getPropertyChangeListeners()).hasSize(2);
Assertions.assertThat(outer.getInner().getInner().getPropertyChangeListeners()).hasSize(3);
//first off directly
outer.dirtyTracker().stopTrackingChangesDirectly();
Assertions.assertThat(outer.dirtyTracker().isTrackingChanges()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isTrackingChanges()).isTrue();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isTrackingChanges()).isTrue();
Assertions.assertThat(outer.dirtyTracker().isTrackingChangesDirectly()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isTrackingChangesDirectly()).isTrue();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isTrackingChangesDirectly()).isTrue();
Assertions.assertThat(outer.getPropertyChangeListeners()).hasSize(0);
Assertions.assertThat(outer.getInner().getPropertyChangeListeners()).hasSize(1);
Assertions.assertThat(outer.getInner().getInner().getPropertyChangeListeners()).hasSize(2);
//second off directly
outer.getInner().dirtyTracker().stopTrackingChangesDirectly();
Assertions.assertThat(outer.dirtyTracker().isTrackingChanges()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isTrackingChanges()).isFalse();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isTrackingChanges()).isTrue();
Assertions.assertThat(outer.dirtyTracker().isTrackingChangesDirectly()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isTrackingChangesDirectly()).isFalse();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isTrackingChangesDirectly()).isTrue();
Assertions.assertThat(outer.getPropertyChangeListeners()).hasSize(0);
Assertions.assertThat(outer.getInner().getPropertyChangeListeners()).hasSize(0);
Assertions.assertThat(outer.getInner().getInner().getPropertyChangeListeners()).hasSize(1);
//third off directly
outer.getInner().getInner().dirtyTracker().stopTrackingChangesDirectly();
Assertions.assertThat(outer.dirtyTracker().isTrackingChanges()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isTrackingChanges()).isFalse();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isTrackingChanges()).isFalse();
Assertions.assertThat(outer.dirtyTracker().isTrackingChangesDirectly()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isTrackingChangesDirectly()).isFalse();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isTrackingChangesDirectly()).isFalse();
Assertions.assertThat(outer.getPropertyChangeListeners()).hasSize(0);
Assertions.assertThat(outer.getInner().getPropertyChangeListeners()).hasSize(0);
Assertions.assertThat(outer.getInner().getInner().getPropertyChangeListeners()).hasSize(0);
}
@Test
public void testFirstStaysOffIfSecondIsTracking() {
final OuterVo outer = newOuterVo();
//second on directly
outer.getInner().dirtyTracker().startTrackingChangesDirectly();
Assertions.assertThat(outer.dirtyTracker().isTrackingChanges()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isTrackingChanges()).isTrue();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isTrackingChanges()).isTrue();
Assertions.assertThat(outer.dirtyTracker().isTrackingChangesDirectly()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isTrackingChangesDirectly()).isTrue();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isTrackingChangesDirectly()).isFalse();
//second off directly
outer.getInner().dirtyTracker().stopTrackingChangesDirectly();
Assertions.assertThat(outer.dirtyTracker().isTrackingChanges()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isTrackingChanges()).isFalse();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isTrackingChanges()).isFalse();
Assertions.assertThat(outer.dirtyTracker().isTrackingChangesDirectly()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isTrackingChangesDirectly()).isFalse();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isTrackingChangesDirectly()).isFalse();
}
@Test
public void testManualMarkingWithoutTracking() {
final OuterVo outer = newOuterVo();
//add listener
final List<String> expectedDirtyEventsOnSecondLevel = new ArrayList<String>();
final List<String> expectedCleanEventsOnSecondLevel = new ArrayList<String>();
final List<String> expectedPropertyChangeEventsOnSecondLevel = new ArrayList<String>();
addListenerWithAssertions(outer, expectedDirtyEventsOnSecondLevel, expectedCleanEventsOnSecondLevel,
expectedPropertyChangeEventsOnSecondLevel);
//all clean
Assertions.assertThat(outer.dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner")).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner.value")).isFalse();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(expectedDirtyEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedCleanEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedPropertyChangeEventsOnSecondLevel).isEmpty();
//second dirty
expectedDirtyEventsOnSecondLevel.add("inner");
expectedDirtyEventsOnSecondLevel.add("value");
expectedDirtyEventsOnSecondLevel.add("inner.value");
Assertions.assertThat(outer.getInner().dirtyTracker().markDirty()).isTrue();
Assertions.assertThat(outer.dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty()).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner")).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner.value")).isTrue();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isDirty()).isTrue();
Assertions.assertThat(expectedDirtyEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedCleanEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedPropertyChangeEventsOnSecondLevel).isEmpty();
//third clean
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().markClean()).isTrue();
Assertions.assertThat(outer.dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty()).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner")).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner.value")).isTrue();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(expectedDirtyEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedCleanEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedPropertyChangeEventsOnSecondLevel).isEmpty();
//second clean
expectedCleanEventsOnSecondLevel.add("inner");
expectedCleanEventsOnSecondLevel.add("value");
expectedCleanEventsOnSecondLevel.add("inner.value");
Assertions.assertThat(outer.getInner().dirtyTracker().markClean()).isTrue();
Assertions.assertThat(outer.dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner")).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner.value")).isFalse();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(expectedDirtyEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedCleanEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedPropertyChangeEventsOnSecondLevel).isEmpty();
}
private void addListenerWithAssertions(final OuterVo outer, final List<String> expectedDirtyEventsOnSecondLevel,
final List<String> expectedCleanEventsOnSecondLevel,
final List<String> expectedPropertyChangeEventsOnSecondLevel) {
outer.getInner().dirtyTracker().getListeners().add(new IDirtyTrackerListener() {
private int countPropertyChangeEvents = 0;
private int countOnDirtyEvents = 0;
private int countOnCleanEvents = 0;
@Override
public void propertyChange(final PropertyChangeEvent evt) {
countPropertyChangeEvents++;
try {
Assertions.assertThat(expectedPropertyChangeEventsOnSecondLevel.remove(evt.getPropertyName()))
.isTrue();
} catch (final Throwable t) {
throw new RuntimeException(countPropertyChangeEvents + ". propertyChange: " + evt.getPropertyName(),
t);
}
}
@Override
public void onDirty(final String beanPath) {
countOnDirtyEvents++;
try {
Assertions.assertThat(expectedDirtyEventsOnSecondLevel.remove(beanPath)).isTrue();
} catch (final Throwable t) {
throw new RuntimeException(countOnDirtyEvents + ". onDirty: " + beanPath, t);
}
}
@Override
public void onClean(final String beanPath) {
countOnCleanEvents++;
try {
Assertions.assertThat(expectedCleanEventsOnSecondLevel.remove(beanPath)).isTrue();
} catch (final Throwable t) {
throw new RuntimeException(countOnCleanEvents + ". onClean: " + beanPath, t);
}
}
});
}
@Test
public void testManualMarkingWithTracking() {
final OuterVo outer = newOuterVo();
//add listener
final List<String> expectedDirtyEventsOnSecondLevel = new ArrayList<String>();
final List<String> expectedCleanEventsOnSecondLevel = new ArrayList<String>();
final List<String> expectedPropertyChangeEventsOnSecondLevel = new ArrayList<String>();
addListenerWithAssertions(outer, expectedDirtyEventsOnSecondLevel, expectedCleanEventsOnSecondLevel,
expectedPropertyChangeEventsOnSecondLevel);
//first on directly
outer.dirtyTracker().startTrackingChangesDirectly();
Assertions.assertThat(outer.dirtyTracker().isTrackingChanges()).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isTrackingChanges()).isTrue();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isTrackingChanges()).isTrue();
Assertions.assertThat(outer.dirtyTracker().isTrackingChangesDirectly()).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isTrackingChangesDirectly()).isFalse();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isTrackingChangesDirectly()).isFalse();
Assertions.assertThat(expectedDirtyEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedCleanEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedPropertyChangeEventsOnSecondLevel).isEmpty();
//all clean
Assertions.assertThat(outer.dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner")).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner.value")).isFalse();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(expectedDirtyEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedCleanEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedPropertyChangeEventsOnSecondLevel).isEmpty();
//second dirty
expectedDirtyEventsOnSecondLevel.add("inner");
expectedDirtyEventsOnSecondLevel.add("value");
expectedDirtyEventsOnSecondLevel.add("inner.value");
Assertions.assertThat(outer.getInner().dirtyTracker().markDirty()).isTrue();
Assertions.assertThat(outer.dirtyTracker().isDirty()).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty()).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner")).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner.value")).isTrue();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isDirty()).isTrue();
Assertions.assertThat(expectedDirtyEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedCleanEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedPropertyChangeEventsOnSecondLevel).isEmpty();
//third clean
expectedCleanEventsOnSecondLevel.add("inner.value");
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().markClean()).isTrue();
Assertions.assertThat(outer.dirtyTracker().isDirty()).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty()).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner")).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner.value")).isFalse();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(expectedDirtyEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedCleanEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedPropertyChangeEventsOnSecondLevel).isEmpty();
//second clean
expectedCleanEventsOnSecondLevel.add("inner");
expectedCleanEventsOnSecondLevel.add("value");
Assertions.assertThat(outer.getInner().dirtyTracker().markClean()).isTrue();
Assertions.assertThat(outer.dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner")).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner.value")).isFalse();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(expectedDirtyEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedCleanEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedPropertyChangeEventsOnSecondLevel).isEmpty();
}
@Test
public void testAutomaticMarkingWithoutTracking() {
final OuterVo outer = newOuterVo();
//add listener
final List<String> expectedDirtyEventsOnSecondLevel = new ArrayList<String>();
final List<String> expectedCleanEventsOnSecondLevel = new ArrayList<String>();
final List<String> expectedPropertyChangeEventsOnSecondLevel = new ArrayList<String>();
addListenerWithAssertions(outer, expectedDirtyEventsOnSecondLevel, expectedCleanEventsOnSecondLevel,
expectedPropertyChangeEventsOnSecondLevel);
//all clean
Assertions.assertThat(outer.dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner")).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner.value")).isFalse();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(expectedDirtyEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedCleanEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedPropertyChangeEventsOnSecondLevel).isEmpty();
//second dirty
outer.getInner().setValue(Integer.MAX_VALUE);
Assertions.assertThat(outer.dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner")).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner.value")).isFalse();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(expectedDirtyEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedCleanEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedPropertyChangeEventsOnSecondLevel).isEmpty();
//third dirty
outer.getInner().getInner().setValue(String.valueOf(Integer.MAX_VALUE));
Assertions.assertThat(outer.dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner")).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner.value")).isFalse();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(expectedDirtyEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedCleanEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedPropertyChangeEventsOnSecondLevel).isEmpty();
}
@Test
public void testAutomaticMarkingWithTracking() {
final OuterVo outer = newOuterVo();
//add listener
final List<String> expectedDirtyEventsOnSecondLevel = new ArrayList<String>();
final List<String> expectedCleanEventsOnSecondLevel = new ArrayList<String>();
final List<String> expectedPropertyChangeEventsOnSecondLevel = new ArrayList<String>();
addListenerWithAssertions(outer, expectedDirtyEventsOnSecondLevel, expectedCleanEventsOnSecondLevel,
expectedPropertyChangeEventsOnSecondLevel);
//first on directly
outer.dirtyTracker().startTrackingChangesDirectly();
Assertions.assertThat(outer.dirtyTracker().isTrackingChanges()).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isTrackingChanges()).isTrue();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isTrackingChanges()).isTrue();
Assertions.assertThat(outer.dirtyTracker().isTrackingChangesDirectly()).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isTrackingChangesDirectly()).isFalse();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isTrackingChangesDirectly()).isFalse();
Assertions.assertThat(expectedDirtyEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedCleanEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedPropertyChangeEventsOnSecondLevel).isEmpty();
//all clean
Assertions.assertThat(outer.dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner")).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner.value")).isFalse();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(expectedDirtyEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedCleanEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedPropertyChangeEventsOnSecondLevel).isEmpty();
//second dirty
expectedDirtyEventsOnSecondLevel.add("value");
expectedPropertyChangeEventsOnSecondLevel.add("value");
outer.getInner().setValue(Integer.MAX_VALUE);
Assertions.assertThat(outer.dirtyTracker().isDirty()).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty()).isTrue();
Assertions.assertThat(outer.dirtyTracker().isDirty("inner")).isTrue();
Assertions.assertThat(outer.dirtyTracker().isDirty("inner.value")).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner")).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner.value")).isFalse();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(expectedDirtyEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedCleanEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedPropertyChangeEventsOnSecondLevel).isEmpty();
//third dirty
expectedDirtyEventsOnSecondLevel.add("inner.value");
expectedPropertyChangeEventsOnSecondLevel.add("inner.value");
outer.getInner().getInner().setValue(String.valueOf(Integer.MAX_VALUE));
Assertions.assertThat(outer.dirtyTracker().isDirty()).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty()).isTrue();
Assertions.assertThat(outer.dirtyTracker().isDirty("inner")).isTrue();
Assertions.assertThat(outer.dirtyTracker().isDirty("inner.value")).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner")).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner.value")).isTrue();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isDirty()).isTrue();
Assertions.assertThat(expectedDirtyEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedCleanEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedPropertyChangeEventsOnSecondLevel).isEmpty();
}
@Test
public void testAutomaticMarkingWithTrackingAndChangingValueObjects() {
final OuterVo outer = newOuterVo();
//add listener
final List<String> expectedDirtyEventsOnSecondLevel = new ArrayList<String>();
final List<String> expectedCleanEventsOnSecondLevel = new ArrayList<String>();
final List<String> expectedPropertyChangeEventsOnSecondLevel = new ArrayList<String>();
addListenerWithAssertions(outer, expectedDirtyEventsOnSecondLevel, expectedCleanEventsOnSecondLevel,
expectedPropertyChangeEventsOnSecondLevel);
//first on directly
outer.dirtyTracker().startTrackingChangesDirectly();
Assertions.assertThat(outer.dirtyTracker().isTrackingChanges()).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isTrackingChanges()).isTrue();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isTrackingChanges()).isTrue();
Assertions.assertThat(outer.dirtyTracker().isTrackingChangesDirectly()).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isTrackingChangesDirectly()).isFalse();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isTrackingChangesDirectly()).isFalse();
Assertions.assertThat(expectedDirtyEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedCleanEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedPropertyChangeEventsOnSecondLevel).isEmpty();
//all clean
Assertions.assertThat(outer.dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner")).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner.value")).isFalse();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(expectedDirtyEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedCleanEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedPropertyChangeEventsOnSecondLevel).isEmpty();
//second dirty
expectedDirtyEventsOnSecondLevel.add("value");
expectedPropertyChangeEventsOnSecondLevel.add("value");
outer.getInner().setValue(Integer.MAX_VALUE);
Assertions.assertThat(outer.dirtyTracker().isDirty()).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty()).isTrue();
Assertions.assertThat(outer.dirtyTracker().isDirty("inner")).isTrue();
Assertions.assertThat(outer.dirtyTracker().isDirty("inner.value")).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner")).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner.value")).isFalse();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(expectedDirtyEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedCleanEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedPropertyChangeEventsOnSecondLevel).isEmpty();
//third new value object
expectedDirtyEventsOnSecondLevel.add("inner");
expectedDirtyEventsOnSecondLevel.add("inner.value");
expectedPropertyChangeEventsOnSecondLevel.add("inner");
outer.getInner().setInner(new InnerInnerVO());
Assertions.assertThat(outer.dirtyTracker().isDirty()).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty()).isTrue();
Assertions.assertThat(outer.dirtyTracker().isDirty("inner")).isTrue();
Assertions.assertThat(outer.dirtyTracker().isDirty("inner.value")).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner")).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner.value")).isTrue();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(expectedDirtyEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedCleanEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedPropertyChangeEventsOnSecondLevel).isEmpty();
//third dirty
expectedPropertyChangeEventsOnSecondLevel.add("inner.value");
outer.getInner().getInner().setValue(String.valueOf(Integer.MAX_VALUE));
Assertions.assertThat(outer.dirtyTracker().isDirty()).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty()).isTrue();
Assertions.assertThat(outer.dirtyTracker().isDirty("inner")).isTrue();
Assertions.assertThat(outer.dirtyTracker().isDirty("inner.value")).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner")).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner.value")).isTrue();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isDirty()).isTrue();
Assertions.assertThat(expectedDirtyEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedCleanEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedPropertyChangeEventsOnSecondLevel).isEmpty();
//third clean
expectedCleanEventsOnSecondLevel.add("inner.value");
outer.getInner().getInner().dirtyTracker().markClean();
Assertions.assertThat(outer.dirtyTracker().isDirty()).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty()).isTrue();
Assertions.assertThat(outer.dirtyTracker().isDirty("inner")).isTrue();
Assertions.assertThat(outer.dirtyTracker().isDirty("inner.value")).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner")).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner.value")).isFalse();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(expectedDirtyEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedCleanEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedPropertyChangeEventsOnSecondLevel).isEmpty();
//third same value set thus unchanged
outer.getInner().getInner().setValue(String.valueOf(Integer.MAX_VALUE));
Assertions.assertThat(outer.dirtyTracker().isDirty()).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty()).isTrue();
Assertions.assertThat(outer.dirtyTracker().isDirty("inner")).isTrue();
Assertions.assertThat(outer.dirtyTracker().isDirty("inner.value")).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner")).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner.value")).isFalse();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isDirty()).isFalse();
Assertions.assertThat(expectedDirtyEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedCleanEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedPropertyChangeEventsOnSecondLevel).isEmpty();
//third dirty
expectedPropertyChangeEventsOnSecondLevel.add("inner.value");
expectedDirtyEventsOnSecondLevel.add("inner.value");
outer.getInner().getInner().setValue(null);
Assertions.assertThat(outer.dirtyTracker().isDirty()).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty()).isTrue();
Assertions.assertThat(outer.dirtyTracker().isDirty("inner")).isTrue();
Assertions.assertThat(outer.dirtyTracker().isDirty("inner.value")).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner")).isTrue();
Assertions.assertThat(outer.getInner().dirtyTracker().isDirty("inner.value")).isTrue();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isDirty()).isTrue();
Assertions.assertThat(expectedDirtyEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedCleanEventsOnSecondLevel).isEmpty();
Assertions.assertThat(expectedPropertyChangeEventsOnSecondLevel).isEmpty();
}
@Test
public void testIterableEmptyEqualsNull() {
final ListVo listVo = new ListVo();
listVo.setList(null);
listVo.dirtyTracker().startTrackingChangesDirectly();
Assertions.assertThat(listVo.dirtyTracker().isDirty()).isFalse();
listVo.setList(new ArrayList<OuterVo>());
Assertions.assertThat(listVo.dirtyTracker().isDirty()).isFalse();
listVo.setList(new ArrayList<OuterVo>());
Assertions.assertThat(listVo.dirtyTracker().isDirty()).isFalse();
listVo.setList(Arrays.asList(newOuterVo()));
Assertions.assertThat(listVo.dirtyTracker().isDirty()).isTrue();
listVo.dirtyTracker().markClean();
Assertions.assertThat(listVo.dirtyTracker().isDirty()).isFalse();
listVo.setList(null);
Assertions.assertThat(listVo.dirtyTracker().isDirty()).isTrue();
}
@Test
public void testIterableChildrenGetTracked() {
final ListVo listVo = new ListVo();
listVo.dirtyTracker().startTrackingChangesDirectly();
Assertions.assertThat(listVo.dirtyTracker().isDirty()).isFalse();
listVo.getList().get(0).setOtherValue(1298129);
Assertions.assertThat(listVo.dirtyTracker().isDirty()).isTrue();
}
public static class ListVo extends AValueObject {
private List<OuterVo> list = new ArrayList<OuterVo>();
public ListVo() {
list.add(newOuterVo());
list.add(newOuterVo());
list.add(newOuterVo());
}
public List<OuterVo> getList() {
return list;
}
public void setList(final List<OuterVo> list) {
final List<OuterVo> oldValue = this.list;
this.list = list;
firePropertyChange("list", oldValue, list);
}
}
private static OuterVo newOuterVo() {
final OuterVo outer = new OuterVo();
Assertions.assertThat(outer.dirtyTracker().isTrackingChanges()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isTrackingChanges()).isFalse();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isTrackingChanges()).isFalse();
Assertions.assertThat(outer.dirtyTracker().isTrackingChangesDirectly()).isFalse();
Assertions.assertThat(outer.getInner().dirtyTracker().isTrackingChangesDirectly()).isFalse();
Assertions.assertThat(outer.getInner().getInner().dirtyTracker().isTrackingChangesDirectly()).isFalse();
return outer;
}
//TOOD: maybe also test some of the healing mechanisms and those healing mechanisms that are not working
public static class OuterVo extends AValueObject {
private static final long serialVersionUID = 1L;
private InnerVO inner = new InnerVO();
private Integer otherValue;
public InnerVO getInner() {
return inner;
}
public void setInner(final InnerVO inner) {
final InnerVO oldValue = this.inner;
this.inner = inner;
firePropertyChange("inner", oldValue, inner);
}
public Integer getOtherValue() {
return otherValue;
}
public void setOtherValue(final Integer otherValue) {
final Integer oldValue = this.otherValue;
this.otherValue = otherValue;
firePropertyChange("otherValue", oldValue, otherValue);
}
}
public static class InnerVO extends AValueObject {
private static final long serialVersionUID = 1L;
private Integer value;
private InnerInnerVO inner = new InnerInnerVO();
public Integer getValue() {
return value;
}
public void setValue(final Integer value) {
final Integer oldValue = this.value;
this.value = value;
firePropertyChange("value", oldValue, value);
}
public InnerInnerVO getInner() {
return inner;
}
public void setInner(final InnerInnerVO inner) {
final InnerInnerVO oldValue = this.inner;
this.inner = inner;
firePropertyChange("inner", oldValue, inner);
}
}
public static class InnerInnerVO extends AValueObject {
private static final long serialVersionUID = 1L;
private String value;
public String getValue() {
return value;
}
public void setValue(final String value) {
final String oldValue = this.value;
this.value = value;
firePropertyChange("value", oldValue, value);
}
}
}