/tests/com/google/appengine/datanucleus/query/LazyResultTest.java

http://datanucleus-appengine.googlecode.com/ · Java · 284 lines · 215 code · 39 blank · 30 comment · 0 complexity · e9510789125374e7ce92551a3a64537c MD5 · raw file

  1. /**********************************************************************
  2. Copyright (c) 2009 Google Inc.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. **********************************************************************/
  13. package com.google.appengine.datanucleus.query;
  14. import com.google.appengine.api.datastore.Entity;
  15. import com.google.appengine.datanucleus.DatastoreTestCase;
  16. import com.google.appengine.datanucleus.Utils;
  17. import com.google.appengine.datanucleus.Utils.Function;
  18. import java.util.Collections;
  19. import java.util.Iterator;
  20. import java.util.ListIterator;
  21. /**
  22. * @author Max Ross <maxr@google.com>
  23. */
  24. public class LazyResultTest extends DatastoreTestCase {
  25. public void testEquality() {
  26. LazyResult lr1 = new LazyResult<Object>(Collections.<Entity>emptyList(), null, false);
  27. LazyResult lr2 = new LazyResult<Object>(Collections.<Entity>emptyList(), null, false);
  28. assertTrue(lr1.equals(lr1));
  29. assertFalse(lr1.equals(lr2));
  30. }
  31. private static final Function<Entity, Object> NULL_FUNC = new Function<Entity, Object>() {
  32. public Object apply(Entity entity) {
  33. return entity;
  34. }
  35. };
  36. private static class CountingIterable implements Iterable<Entity> {
  37. private final Iterable<Entity> iterable;
  38. private int nextCount = 0;
  39. private CountingIterable(Iterable<Entity> iterable) {
  40. this.iterable = iterable;
  41. }
  42. public Iterator<Entity> iterator() {
  43. return new CountingIterator(iterable.iterator());
  44. }
  45. private class CountingIterator implements Iterator<Entity> {
  46. private final Iterator<Entity> iter;
  47. private CountingIterator(Iterator<Entity> iter) {
  48. this.iter = iter;
  49. }
  50. public boolean hasNext() {
  51. return iter.hasNext();
  52. }
  53. public Entity next() {
  54. nextCount++;
  55. return iter.next();
  56. }
  57. public void remove() {
  58. throw new UnsupportedOperationException();
  59. }
  60. }
  61. }
  62. public void testSize_FreshIterator() {
  63. CountingIterable iterable = new CountingIterable(Utils.<Entity>newArrayList());
  64. LazyResult lr = new LazyResult<Object>(iterable, NULL_FUNC, false);
  65. assertEquals(0, lr.size());
  66. assertEquals(0, iterable.nextCount);
  67. Entity e = null;
  68. iterable = new CountingIterable(Utils.newArrayList(e));
  69. lr = new LazyResult<Object>(iterable, NULL_FUNC, false);
  70. assertEquals(1, lr.size());
  71. assertEquals(1, iterable.nextCount);
  72. iterable = new CountingIterable(Utils.newArrayList(e, e));
  73. lr = new LazyResult<Object>(iterable, NULL_FUNC, false);
  74. assertEquals(2, lr.size());
  75. assertEquals(2, iterable.nextCount);
  76. }
  77. public void testSize_PartiallyConsumedIterator() {
  78. Entity e = null;
  79. CountingIterable iterable = new CountingIterable(Utils.newArrayList(e, e, e));
  80. LazyResult lr = new LazyResult<Object>(iterable, NULL_FUNC, false);
  81. lr.resolveNext();
  82. assertEquals(1, iterable.nextCount);
  83. assertEquals(3, lr.size());
  84. assertEquals(3, iterable.nextCount);
  85. }
  86. public void testSize_ExhaustedIterator() {
  87. Entity e = null;
  88. CountingIterable iterable = new CountingIterable(Utils.newArrayList(e, e));
  89. LazyResult lr = new LazyResult<Object>(iterable, NULL_FUNC, false);
  90. lr.resolveNext();
  91. lr.resolveNext();
  92. assertEquals(2, iterable.nextCount);
  93. assertEquals(2, lr.size());
  94. assertEquals(2, iterable.nextCount);
  95. }
  96. public void testGet_FreshIterator() {
  97. CountingIterable iterable = new CountingIterable(Utils.<Entity>newArrayList());
  98. LazyResult lr = new LazyResult<Object>(iterable, NULL_FUNC, false);
  99. try {
  100. lr.get(0);
  101. fail("expected index out of bounds exception");
  102. } catch (IndexOutOfBoundsException e) {
  103. // good
  104. }
  105. assertEquals(0, iterable.nextCount);
  106. Entity e1 = new Entity("yar");
  107. Entity e2 = new Entity("yar");
  108. iterable = new CountingIterable(Utils.newArrayList(e1, e2));
  109. lr = new LazyResult<Object>(iterable, NULL_FUNC, false);
  110. assertEquals(e1, lr.get(0));
  111. assertEquals(1, iterable.nextCount);
  112. assertEquals(e2, lr.get(1));
  113. assertEquals(2, iterable.nextCount);
  114. try {
  115. lr.get(3);
  116. fail("expected index out of bounds exception");
  117. } catch (IndexOutOfBoundsException e) {
  118. // good
  119. }
  120. assertEquals(2, iterable.nextCount);
  121. }
  122. public void testGet_PartiallyConsumedIterator() {
  123. Entity e1 = new Entity("yar");
  124. Entity e2 = new Entity("yar");
  125. CountingIterable iterable = new CountingIterable(Utils.<Entity>newArrayList(e1, e2));
  126. LazyResult lr = new LazyResult<Object>(iterable, NULL_FUNC, false);
  127. lr.resolveNext();
  128. assertEquals(1, iterable.nextCount);
  129. assertEquals(e1, lr.get(0));
  130. assertEquals(1, iterable.nextCount);
  131. assertEquals(e2, lr.get(1));
  132. assertEquals(2, iterable.nextCount);
  133. try {
  134. lr.get(3);
  135. fail("expected index out of bounds exception");
  136. } catch (IndexOutOfBoundsException e) {
  137. // good
  138. }
  139. assertEquals(2, iterable.nextCount);
  140. }
  141. public void testGet_ExhaustedIterator() {
  142. Entity e1 = new Entity("yar");
  143. Entity e2 = new Entity("yar");
  144. CountingIterable iterable = new CountingIterable(Utils.<Entity>newArrayList(e1, e2));
  145. LazyResult lr = new LazyResult<Object>(iterable, NULL_FUNC, false);
  146. lr.resolveNext();
  147. lr.resolveNext();
  148. assertEquals(2, iterable.nextCount);
  149. assertEquals(e1, lr.get(0));
  150. assertEquals(2, iterable.nextCount);
  151. assertEquals(e2, lr.get(1));
  152. assertEquals(2, iterable.nextCount);
  153. try {
  154. lr.get(3);
  155. fail("expected index out of bounds exception");
  156. } catch (IndexOutOfBoundsException e) {
  157. // good
  158. }
  159. assertEquals(2, iterable.nextCount);
  160. }
  161. // This implicitly tests the iterator() method as well since iterator() just
  162. // delegates to listIterator()
  163. public void testListIterator() {
  164. CountingIterable iterable = new CountingIterable(Utils.<Entity>newArrayList());
  165. LazyResult lr = new LazyResult<Object>(iterable, NULL_FUNC, false);
  166. assertFalse(lr.listIterator().hasNext());
  167. Entity e1 = new Entity("yar1");
  168. Entity e2 = new Entity("yar2");
  169. Entity e3 = new Entity("yar3");
  170. Entity e4 = new Entity("yar4");
  171. iterable = new CountingIterable(Utils.<Entity>newArrayList(e1, e2, e3, e4));
  172. lr = new LazyResult<Object>(iterable, NULL_FUNC, false);
  173. ListIterator listIter = lr.listIterator();
  174. assertTrue(listIter.hasNext());
  175. assertSame(e1, listIter.next());
  176. assertEquals(1, iterable.nextCount);
  177. assertSame(e1, lr.get(0));
  178. assertEquals(1, iterable.nextCount);
  179. assertEquals(e2, listIter.next());
  180. assertEquals(2, iterable.nextCount);
  181. // Calls to the iterator make more data available to get() so nextCount
  182. // does not increment.
  183. assertSame(e2, lr.get(1));
  184. assertEquals(2, iterable.nextCount);
  185. // now we work our way backwards
  186. assertEquals(2, listIter.nextIndex());
  187. assertEquals(1, listIter.previousIndex());
  188. assertTrue(listIter.hasPrevious());
  189. assertTrue(listIter.hasNext());
  190. assertSame(e2, listIter.previous());
  191. assertTrue(listIter.hasNext());
  192. assertEquals(3, iterable.nextCount);
  193. assertTrue(listIter.hasPrevious());
  194. assertEquals(1, listIter.nextIndex());
  195. assertEquals(0, listIter.previousIndex());
  196. assertSame(e1, listIter.previous());
  197. assertEquals(3, iterable.nextCount);
  198. assertFalse(listIter.hasPrevious());
  199. assertTrue(listIter.hasNext());
  200. assertEquals(-1, listIter.previousIndex());
  201. // now we go forwards again
  202. assertSame(e1, listIter.next());
  203. assertEquals(1, listIter.nextIndex());
  204. assertEquals(0, listIter.previousIndex());
  205. assertEquals(3, iterable.nextCount);
  206. assertTrue(listIter.hasPrevious());
  207. assertTrue(listIter.hasNext());
  208. assertSame(e2, listIter.next());
  209. assertEquals(2, listIter.nextIndex());
  210. assertEquals(1, listIter.previousIndex());
  211. assertEquals(3, iterable.nextCount);
  212. assertTrue(listIter.hasPrevious());
  213. assertTrue(listIter.hasNext());
  214. assertEquals(3, iterable.nextCount);
  215. assertSame(e3, listIter.next());
  216. assertEquals(3, iterable.nextCount);
  217. assertEquals(3, listIter.nextIndex());
  218. assertEquals(2, listIter.previousIndex());
  219. assertTrue(listIter.hasPrevious());
  220. assertTrue(listIter.hasNext());
  221. // the call to hasNext() results in a fetch
  222. assertEquals(4, iterable.nextCount);
  223. assertSame(e4, listIter.next());
  224. assertEquals(4, listIter.nextIndex());
  225. assertEquals(3, listIter.previousIndex());
  226. assertEquals(4, iterable.nextCount);
  227. assertTrue(listIter.hasPrevious());
  228. assertFalse(listIter.hasNext());
  229. iterable = new CountingIterable(Utils.<Entity>newArrayList(e1, e2));
  230. lr = new LazyResult<Object>(iterable, NULL_FUNC, false);
  231. listIter = lr.listIterator();
  232. assertTrue(listIter.hasNext());
  233. assertEquals(e1, listIter.next());
  234. assertEquals(1, iterable.nextCount);
  235. // Call to get makes more data available to the iterator.
  236. lr.get(1);
  237. assertEquals(2, iterable.nextCount);
  238. assertTrue(listIter.hasNext());
  239. assertSame(e2, listIter.next());
  240. assertEquals(2, iterable.nextCount);
  241. }
  242. }