package edu.northwestern.bioinformatics.studycalendar.domain.delta;

import edu.northwestern.bioinformatics.studycalendar.testing.StudyCalendarTestCase;
import edu.northwestern.bioinformatics.studycalendar.domain.PlannedCalendar;
import edu.northwestern.bioinformatics.studycalendar.domain.PlanTreeNode;
import edu.northwestern.bioinformatics.studycalendar.domain.Epoch;
import edu.northwestern.bioinformatics.studycalendar.domain.Arm;
import edu.northwestern.bioinformatics.studycalendar.domain.Period;
import edu.northwestern.bioinformatics.studycalendar.domain.PlannedEvent;

import java.util.Arrays;

/**
 * @author Rhett Sutphin
 */
public class DeltaTest extends StudyCalendarTestCase {
    public void testDeltaForPlannedCalendar() throws Exception {
        assertDeltaFor(new PlannedCalendar(), PlannedCalendarDelta.class);
    }

    public void testDeltaForEpoch() throws Exception {
        assertDeltaFor(new Epoch(), EpochDelta.class);
    }

    public void testDeltaForArm() throws Exception {
        assertDeltaFor(new Arm(), ArmDelta.class);
    }

    public void testDeltaForPeriod() throws Exception {
        assertDeltaFor(new Period(), PeriodDelta.class);
    }

    public void testDeltaForPlannedEvent() throws Exception {
        assertDeltaFor(new PlannedEvent(), PlannedEventDelta.class);
    }

    public void testAddChange() throws Exception {
        Delta<?> delta = new EpochDelta();
        assertEquals("Test setup failure", 0, delta.getChanges().size());
        delta.addChange(PropertyChange.create("nil", "null", "{}"));
        assertEquals(1, delta.getChanges().size());
    }

    public void testRemoveChangeNotifiesSiblings() throws Exception {
        Change sib0 = registerMockFor(Change.class);
        Change sib1 = registerMockFor(Change.class);
        Change sib2 = registerMockFor(Change.class);

        Delta<?> delta = new EpochDelta();
        delta.getChangesInternal().addAll(Arrays.asList(sib0, sib1, sib2));

        sib0.siblingDeleted(delta, sib1, 1, 0);
        sib2.siblingDeleted(delta, sib1, 1, 2);
        sib1.setDelta(null);

        replayMocks();
        delta.removeChange(sib1);
        verifyMocks();
    }

    public void testRemoveChangeDoesNotNotifyIfTheRemovedChangeWasNotInTheDelta() throws Exception {
        Change sib0 = registerMockFor(Change.class);
        Change sib1 = registerMockFor(Change.class);
        Change sib2 = registerMockFor(Change.class);

        Delta<?> delta = new EpochDelta();
        delta.getChangesInternal().addAll(Arrays.asList(sib0, sib2));

        replayMocks();
        delta.removeChange(sib1);
        verifyMocks();
    }

    public void testGetChangesReturnsReadOnlyList() throws Exception {
        Delta<?> delta = new EpochDelta();
        try {
            delta.getChanges().add(PropertyChange.create("aleph", "i", "I"));
            fail("Exception not thrown");
        } catch (UnsupportedOperationException e) {
            // good
        }
    }

    private static void assertDeltaFor(PlanTreeNode<?> node, Class<?> expectedClass) {
        Delta<?> actual = Delta.createDeltaFor(node);
        assertNotNull(actual);
        assertEquals("Wrong class", expectedClass, actual.getClass());
    }
}

@@ -2995,16 +2995,44 @@
 e static
+ %3CT extends PlanTreeNode%3C?%3E%3E
  void as
@@ -3044,31 +3044,17 @@
 eltaFor(
-PlanTreeNode%3C?%3E
+T
  node, C
@@ -3092,17 +3092,17 @@
   Delta%3C
-?
+T
 %3E actual

Restructure to avoid bogus IDEA parse error