aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--main/src/cgeo/geocaching/utils/LazyInitializedList.java8
-rw-r--r--tests/src/cgeo/geocaching/LazyInitialilzedListTest.java74
2 files changed, 82 insertions, 0 deletions
diff --git a/main/src/cgeo/geocaching/utils/LazyInitializedList.java b/main/src/cgeo/geocaching/utils/LazyInitializedList.java
index 27649e8..e607919 100644
--- a/main/src/cgeo/geocaching/utils/LazyInitializedList.java
+++ b/main/src/cgeo/geocaching/utils/LazyInitializedList.java
@@ -1,7 +1,10 @@
package cgeo.geocaching.utils;
+import org.eclipse.jdt.annotation.NonNull;
+
import java.util.AbstractList;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
@@ -9,6 +12,7 @@ public abstract class LazyInitializedList<ElementType> extends AbstractList<Elem
private volatile List<ElementType> list;
+ @NonNull
private List<ElementType> getList() {
if (list == null) {
synchronized(this) {
@@ -20,6 +24,10 @@ public abstract class LazyInitializedList<ElementType> extends AbstractList<Elem
} catch (final Exception e) {
Log.e("LazyInitializedList.getList", e);
}
+ if (list == null) {
+ Log.e("LazyInitializedList.getList: using an empty list as a fallback");
+ list = Collections.emptyList();
+ }
}
}
return list;
diff --git a/tests/src/cgeo/geocaching/LazyInitialilzedListTest.java b/tests/src/cgeo/geocaching/LazyInitialilzedListTest.java
new file mode 100644
index 0000000..bc4b6af
--- /dev/null
+++ b/tests/src/cgeo/geocaching/LazyInitialilzedListTest.java
@@ -0,0 +1,74 @@
+package cgeo.geocaching;
+
+import cgeo.geocaching.utils.LazyInitializedList;
+
+import android.test.AndroidTestCase;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class LazyInitialilzedListTest extends AndroidTestCase {
+
+ private static final int MAKE_NULL = -1;
+ private static final int MAKE_EXCEPTION = -2;
+
+ private static class MyList extends LazyInitializedList<Integer> {
+
+ private int counter;
+
+ MyList(int counter) {
+ this.counter = counter;
+ }
+
+ @Override
+ public List<Integer> call() {
+ if (counter == MAKE_NULL) {
+ return null;
+ }
+ if (counter == MAKE_EXCEPTION) {
+ throw new RuntimeException("exception in call()");
+ }
+ final List<Integer> result = new LinkedList<Integer>();
+ for (int i = 0; i < counter; i++) {
+ result.add(counter);
+ }
+ counter += 1;
+ return result;
+ }
+
+ int getCounter() {
+ return counter;
+ }
+
+ }
+
+ public static void testCallOnce() {
+ final MyList l = new MyList(0);
+ assertEquals("call() must not called prematurely", 0, l.getCounter());
+ l.size();
+ assertEquals("call() must be called when needed", 1, l.getCounter());
+ l.size();
+ assertEquals("call() must be called only once", 1, l.getCounter());
+ }
+
+ public static void testSize() {
+ final MyList l = new MyList(3);
+ assertEquals("completed size must be identical to call() result", 3, l.size());
+ }
+
+ public static void testValue() {
+ final MyList l = new MyList(1);
+ assertEquals("value must be identical to call() result", Integer.valueOf(1), l.get(0));
+ }
+
+ public static void testNull() {
+ final MyList l = new MyList(MAKE_NULL);
+ assertEquals("null returned by call() must create an empty list", 0, l.size());
+ }
+
+ public static void testException() {
+ final MyList l = new MyList(MAKE_EXCEPTION);
+ assertEquals("exception in call() must create an empty list", 0, l.size());
+ }
+
+}