Package rabbit.data.internal.xml.store

Source Code of rabbit.data.internal.xml.store.AbstractStorerTest

/*
* Copyright 2010 The Rabbit Eclipse Plug-in Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package rabbit.data.internal.xml.store;

import static rabbit.data.internal.xml.DatatypeUtil.toXmlDate;

import rabbit.data.internal.xml.DatatypeUtil;
import rabbit.data.internal.xml.IDataStore;
import rabbit.data.internal.xml.XmlPlugin;
import rabbit.data.internal.xml.convert.IConverter;
import rabbit.data.internal.xml.merge.IMerger;
import rabbit.data.internal.xml.schema.events.EventGroupType;
import rabbit.data.internal.xml.schema.events.EventListType;
import rabbit.data.store.model.DiscreteEvent;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import org.eclipse.core.runtime.IPath;
import org.joda.time.DateTime;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import javax.xml.datatype.XMLGregorianCalendar;

/**
* @see AbstractStorer
*/
public abstract class AbstractStorerTest<E extends DiscreteEvent, T, S extends EventGroupType> {

  /**
   * Location of the storage path, to be restored after the tests.
   */
  private static IPath originalStorageLocation;

  @AfterClass
  public static void afterClass() {
    XmlPlugin.getDefault().setStoragePathRoot(originalStorageLocation.toFile());
  }

  @BeforeClass
  public static void beforeClass() {
    originalStorageLocation = XmlPlugin.getDefault().getStoragePathRoot();
    XmlPlugin.getDefault().setStoragePathRoot(
        originalStorageLocation.append("Tests").toFile());
  }

  private AbstractStorer<E, T, S> storer = createStorer();

  @Before
  public void before() throws Exception {
    getDataField(storer).clear();
  }

  @Test
  public void testCommit() throws Exception {
    E event = createEvent(new DateTime());
    storer.insert(event);

    File file = getDataStore(storer).getDataFile(event.getTime().toLocalDate());
    if (file.exists() && !file.delete())
      fail("File must be deleted before test can continue");

    storer.commit();

    List<S> data = getCategories(storer, getDataStore(storer).read(file));
    assertEquals(1, data.size());
    assertEquals(toXmlDate(event.getTime()), data.get(0).getDate());

    List<T> elements = storer.getElements(data.get(0));
    assertEquals(1, elements.size());
    T element = elements.get(0);
    assertTrue(equal(getConverter(storer).convert(event), element));
  }

  @Test
  public void testCommit_emptyDataAfterward() throws Exception {
    E event = createEvent(new DateTime());
    storer.insert(event);
    assertFalse(getDataField(storer).isEmpty());
    storer.commit();
    assertTrue(getDataField(storer).isEmpty());
  }

  @Test
  public void testGetCategories() throws Exception {
    assertNotNull(getCategories(storer, new EventListType()));
  }

  @Test
  public void testGetConverter() throws Exception {
    assertNotNull(getConverter(storer));
  }

  @Test
  public void testGetDataStore() throws Exception {
    assertNotNull(getDataStore(storer));
  }

  @Test
  public void testInsert_singleElement() throws Exception {
    E event = createEvent(new DateTime());
    storer.insert(event);

    Collection<S> categories = getDataField(storer);
    assertEquals(1, categories.size());
    S category = categories.iterator().next();
    assertEquals(toXmlDate(event.getTime()), category.getDate());

    List<T> elements = storer.getElements(category);
    assertEquals(1, elements.size());
    T element = elements.iterator().next();
    assertTrue(equal(getConverter(storer).convert(event), element));
  }

  @Test
  public void testInsert_withConvertableElements() throws Exception {
    E event1 = createEvent(new DateTime());
    E event2 = createEvent(event1.getTime());
    storer.insert(event1);
    storer.insert(event2);

    Collection<S> categories = getDataField(storer);
    assertEquals(1, categories.size());
    S category = categories.iterator().next();
    assertEquals(toXmlDate(event1.getTime()), category.getDate());

    List<T> elements = storer.getElements(category);
    T t1 = getConverter(storer).convert(event1);
    T t2 = getConverter(storer).convert(event2);
    IMerger<T> merger = storer.getMerger();
    if (merger != null) { // Elements are mergeable
      assertEquals(1, elements.size());

      T element = elements.iterator().next();
      assertTrue(equal(merger.merge(t1, t2), element));

    } else { // Elements are not mergeable
      assertEquals(2, elements.size());

      Iterator<T> iterator = elements.iterator();
      // It doesn't matter what order we check, they are all equal, because
      // the two events are created equally:
      assertTrue(equal(t1, iterator.next()));
      assertTrue(equal(t2, iterator.next()));
    }
  }

  @Test
  public void testInsert_withElementsInDifferentDates() throws Exception {
    E event1 = createEvent(new DateTime().withDayOfYear(1));
    E event2 = createEventDiff(event1.getTime().plusDays(1));
    storer.insert(event1);
    storer.insert(event2);

    Collection<S> categories = getDataField(storer);
    assertEquals(2, categories.size());

    Iterator<S> iterator = categories.iterator();
    S category1 = iterator.next();
    S category2 = iterator.next();

    // Swap the categories if neccessary so that category1 contains event1 etc.
    if (category1.getDate().equals(toXmlDate(event2.getTime()))) {
      S tmp = category1;
      category1 = category2;
      category2 = tmp;
    }
    assertEquals(toXmlDate(event1.getTime()), category1.getDate());
    assertEquals(toXmlDate(event2.getTime()), category2.getDate());

    List<T> elements = storer.getElements(category1);
    assertEquals(1, elements.size());
    assertTrue(equal(getConverter(storer).convert(event1), elements.get(0)));

    elements = storer.getElements(category2);
    assertEquals(1, elements.size());
    assertTrue(equal(getConverter(storer).convert(event2), elements.get(0)));
  }

  @Test
  public void testInsert_withElementsInDifferentMonths() throws Exception {
    E event1 = createEvent(new DateTime());
    E event2 = createEvent(event1.getTime().plusMonths(1));
    storer.insert(event1);
    storer.insert(event2);

    // Now data about event1 should be commit, so only data about event2 is in
    // memory.

    Collection<S> categories = getDataField(storer);
    assertEquals(1, categories.size());
    S category = categories.iterator().next();
    assertEquals(toXmlDate(event2.getTime()), category.getDate());

    List<T> elements = storer.getElements(category);
    assertEquals(1, elements.size());
    T element = elements.iterator().next();
    assertTrue(equal(getConverter(storer).convert(event2), element));
  }

  @Test
  public void testInsert_withNonConvertableElements() throws Exception {
    E event1 = createEvent(new DateTime());
    E event2 = createEventDiff(event1.getTime());
    storer.insert(event1);
    storer.insert(event2);

    Collection<S> categories = getDataField(storer);
    assertEquals(1, categories.size());
    S category = categories.iterator().next();
    assertEquals(toXmlDate(event1.getTime()), category.getDate());

    List<T> elements = storer.getElements(category);
    assertEquals(2, elements.size());

    T t1 = getConverter(storer).convert(event1);
    T t2 = getConverter(storer).convert(event2);
    assertTrue(equal(t1, elements.get(0)));
    assertTrue(equal(t2, elements.get(1)));
  }

  @Test
  public void testNewCateogry() throws Exception {
    XMLGregorianCalendar date = newCalendar();
    S category = storer.newCategory(date);
    assertNotNull(category);
    assertEquals(date, category.getDate());
  }

  /**
   * Creates an event for testing. Subsequence calls to this method should
   * return equal objects.
   */
  protected abstract E createEvent(DateTime dateTime) throws Exception;

  /**
   * Creates an event for testing. The return event must be different to
   * {@link #createEvent(DateTime)} (Non mergeable). Subsequence calls to this
   * method should return equal objects.
   */
  protected abstract E createEventDiff(DateTime dateTime) throws Exception;

  /**
   * Creates a storer for testing.
   */
  protected abstract AbstractStorer<E, T, S> createStorer();

  /**
   * Checks whether the two objects have the exact same properties.
   */
  protected abstract boolean equal(T t1, T t2);

  /**
   * Calls the protected method
   * {@code AbstractStorer.getXmlTypeCategories(EventListType)}.
   */
  @SuppressWarnings("unchecked")
  protected List<S> getCategories(AbstractStorer<E, T, S> storer,
      EventListType events) throws Exception {

    Method method = AbstractStorer.class.getDeclaredMethod("getCategories",
        EventListType.class);
    method.setAccessible(true);
    return (List<S>) method.invoke(storer, events);
  }

  /**
   * Calls the protected method AbstractStorer.getConverter()
   */
  @SuppressWarnings("unchecked")
  protected IConverter<E, T> getConverter(AbstractStorer<E, T, S> storer)
      throws Exception {
    Method method = AbstractStorer.class.getDeclaredMethod("getConverter");
    method.setAccessible(true);
    return (IConverter<E, T>) method.invoke(storer);
  }

  @SuppressWarnings("unchecked")
  protected Collection<S> getDataField(AbstractStorer<E, T, S> s)
      throws Exception {
    Field f = AbstractStorer.class.getDeclaredField("data");
    f.setAccessible(true);
    return (Collection<S>) f.get(s);
  }

  /**
   * Calls the protected method {@code AbstractStorer.getDataStore()}.
   */
  protected IDataStore getDataStore(AbstractStorer<E, T, S> storer)
      throws Exception {
    Method method = AbstractStorer.class.getDeclaredMethod("getDataStore");
    method.setAccessible(true);
    return (IDataStore) method.invoke(storer);
  }

  private XMLGregorianCalendar newCalendar() {
    return DatatypeUtil.toXmlDate(new DateTime());
  }
}
TOP

Related Classes of rabbit.data.internal.xml.store.AbstractStorerTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.