/*
* Copyright 2016 Realm Inc.
*
* 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 io.realm;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import io.realm.entities.AllJavaTypes;
import io.realm.entities.CustomMethods;
import io.realm.entities.Dog;
import io.realm.entities.NullTypes;
import io.realm.rule.TestRealmConfigurationFactory;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* Test class for all methods part of the the {@link RealmCollection} interface.
* This class only tests methods that have the same behavior no matter if the collection is managed or not.
*
* Methods tested in this class:
*
* # RealmCollection
*
* - RealmQuery<E> where();
* - Number min(String fieldName);
* - Number max(String fieldName);
* - Number sum(String fieldName);
* - double average(String fieldName);
* - Date maxDate(String fieldName);
* - Date minDate(String fieldName);
* - void deleteAllFromRealm();
* - boolean isLoaded();
* - boolean load();
* - boolean isValid();
* - BaseRealm getRealm();
*
* # Collection
*
* - public boolean add(E object);
* - public boolean addAll(Collection<? extends E> collection);
* - public void deleteAll();
* + public boolean contains(Object object);
* + public boolean containsAll(Collection<?> collection);
* + public boolean equals(Object object);
* + public int hashCode();
* + public boolean isEmpty();
* - public Iterator<E> iterator();
* + public boolean remove(Object object);
* + public boolean removeAll(Collection<?> collection);
* + public boolean retainAll(Collection<?> collection);
* + public int size();
* + public Object[] toArray();
* + public <T> T[] toArray(T[] array);
**
* @see ManagedRealmCollectionTests
* @see UnManagedRealmCollectionTests
*/
@RunWith(Parameterized.class)
public class RealmCollectionTests extends CollectionTests {
private static final int TEST_SIZE = 10;
@Rule
public final TestRealmConfigurationFactory configFactory = new TestRealmConfigurationFactory();
private final CollectionClass collectionClass;
private Realm realm;
private RealmCollection<AllJavaTypes> collection;
@Parameterized.Parameters(name = "{0}")
public static List<CollectionClass> data() {
return Arrays.asList(CollectionClass.values());
}
public RealmCollectionTests(CollectionClass collectionType) {
this.collectionClass = collectionType;
}
@Before
public void setup() {
realm = Realm.getInstance(configFactory.createConfiguration());
collection = createCollection(collectionClass);
}
@After
public void tearDown() {
realm.close();
}
private RealmCollection<AllJavaTypes> createCollection(CollectionClass collectionClass) {
OrderedRealmCollection<AllJavaTypes> orderedCollection;
switch (collectionClass) {
case REALMRESULTS_SNAPSHOT_LIST_BASE:
case MANAGED_REALMLIST:
populateRealm(realm, TEST_SIZE);
orderedCollection = realm.where(AllJavaTypes.class)
.equalTo(AllJavaTypes.FIELD_LONG, 0)
.findFirst()
.getFieldList();
break;
case UNMANAGED_REALMLIST:
return populateInMemoryList(TEST_SIZE);
case REALMRESULTS_SNAPSHOT_RESULTS_BASE:
case REALMRESULTS:
populateRealm(realm, TEST_SIZE);
orderedCollection = realm.where(AllJavaTypes.class).findAll();
break;
default:
throw new AssertionError("Unsupported class: " + collectionClass);
}
if (isSnapshot(collectionClass)) {
orderedCollection = orderedCollection.createSnapshot();
}
return orderedCollection;
}
private RealmCollection<CustomMethods> createCustomMethodsCollection(Realm realm, CollectionClass collectionClass) {
OrderedRealmCollection<CustomMethods> orderedCollection;
switch (collectionClass) {
case REALMRESULTS_SNAPSHOT_LIST_BASE:
case MANAGED_REALMLIST:
realm.beginTransaction();
CustomMethods top = realm.createObject(CustomMethods.class);
top.setName("Top");
for (int i = 0; i < TEST_SIZE; i++) {
top.getMethods().add(new CustomMethods("Child" + i));
}
realm.commitTransaction();
orderedCollection = top.getMethods();
break;
case UNMANAGED_REALMLIST:
RealmList<CustomMethods> list = new RealmList<CustomMethods>();
for (int i = 0; i < TEST_SIZE; i++) {
list.add(new CustomMethods("Child" + i));
}
return list;
case REALMRESULTS_SNAPSHOT_RESULTS_BASE:
case REALMRESULTS:
realm.beginTransaction();
for (int i = 0; i < TEST_SIZE; i++) {
realm.copyToRealm(new CustomMethods("Child" + i));
}
realm.commitTransaction();
orderedCollection = realm.where(CustomMethods.class).findAll();
break;
default:
throw new AssertionError("Unsupported class: " + collectionClass);
}
if (isSnapshot(collectionClass)) {
orderedCollection = orderedCollection.createSnapshot();
}
return orderedCollection;
}
private OrderedRealmCollection<NullTypes> createEmptyCollection(Realm realm, CollectionClass collectionClass) {
OrderedRealmCollection<NullTypes> orderedCollection;
switch (collectionClass) {
case REALMRESULTS_SNAPSHOT_LIST_BASE:
case MANAGED_REALMLIST:
realm.beginTransaction();
NullTypes obj = realm.createObject(NullTypes.class, 0);
realm.commitTransaction();
orderedCollection = obj.getFieldListNull();
break;
case UNMANAGED_REALMLIST:
return new RealmList<NullTypes>();
case REALMRESULTS_SNAPSHOT_RESULTS_BASE:
case REALMRESULTS:
orderedCollection = realm.where(NullTypes.class).findAll();
break;
default:
throw new AssertionError("Unknown collection: " + collectionClass);
}
if (isSnapshot(collectionClass)) {
orderedCollection = orderedCollection.createSnapshot();
}
return orderedCollection;
}
@Test
public void contains() {
AllJavaTypes obj = collection.iterator().next();
assertTrue(collection.contains(obj));
}
@Test
public void contains_realmObjectFromOtherRealm() {
Realm realm2 = Realm.getInstance(configFactory.createConfiguration("other_realm.realm"));
populateRealm(realm2, TEST_SIZE);
AllJavaTypes otherRealmObj = realm2.where(AllJavaTypes.class).equalTo(AllJavaTypes.FIELD_LONG, 0).findFirst();
try {
assertFalse(collection.contains(otherRealmObj));
} finally {
realm2.close();
}
}
@Test
@SuppressWarnings("CollectionIncompatibleType")
public void contains_wrongType() {
//noinspection SuspiciousMethodCalls
assertFalse(collection.contains(new Dog()));
}
@Test
public void contains_null() {
assertFalse(collection.contains(null));
}
// Test that the custom equal methods is being used when testing if an object is part of the
// collection
@Test
public void contains_customEqualMethod() {
RealmCollection<CustomMethods> collection = createCustomMethodsCollection(realm, collectionClass);
// This custom equals method will only consider the field `name` when comparing objects.
// So this unmanaged version should be equal to any object with the same value, managed
// or not.
assertTrue(collection.contains(new CustomMethods("Child0")));
assertTrue(collection.contains(new CustomMethods("Child" + (TEST_SIZE - 1))));
assertFalse(collection.contains(new CustomMethods("Child" + TEST_SIZE)));
}
@Test
public void containsAll() {
Iterator<AllJavaTypes> it = collection.iterator();
List<AllJavaTypes> list = Arrays.asList(it.next(), it.next());
assertTrue(collection.containsAll(list));
}
@Test
public void containsAll_emptyInput() {
assertTrue(collection.containsAll(Collections.emptyList()));
}
@Test(expected = NullPointerException.class)
public void containsAll_nullInput() {
collection.containsAll(null);
}
@Test
public void equals() {
ArrayList<AllJavaTypes> newList = new ArrayList<AllJavaTypes>();
newList.addAll(collection);
assertTrue(collection.equals(collection));
assertTrue(collection.equals(newList));
assertFalse(collection.equals(Collections.emptyList()));
assertFalse(collection.equals(null));
}
@Test
public void hashCode_allObjects() {
ArrayList<AllJavaTypes> newList = new ArrayList<AllJavaTypes>();
newList.addAll(collection);
assertTrue(collection.hashCode() == newList.hashCode());
assertFalse(collection.hashCode() == Collections.emptyList().hashCode());
}
@Test
public void isEmpty() {
assertFalse(collection.isEmpty());
RealmCollection<NullTypes> collection = createEmptyCollection(realm, collectionClass);
assertTrue(collection.isEmpty());
}
@Test
public void size() {
assertEquals(TEST_SIZE, collection.size());
}
@Test
public void toArray() {
Object[] array = collection.toArray();
assertEquals(TEST_SIZE, array.length);
assertEquals(collection.iterator().next(), array[0]);
}
@Test
public void toArray_inputArray() {
AllJavaTypes[] array = new AllJavaTypes[collection.size()];
collection.toArray(array);
assertEquals(TEST_SIZE, array.length);
assertEquals(collection.iterator().next(), array[0]);
}
}