package org.fusesource.lmdbjni;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import java.io.IOException;
import java.util.LinkedList;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertTrue;

public class EntryIteratorTest {
  static {
    Setup.setLmdbLibraryPath();
  }

  @Rule
  public TemporaryFolder tmp = new TemporaryFolder();

  Env env;
  Database db;
  LinkedList<byte[]> keys;

  @Before
  public void before() throws IOException {
    String path = tmp.newFolder().getCanonicalPath();
    env = new Env(path);
    db = env.openDatabase();
    keys = new LinkedList<>();
    for (int i = 0; i < 10; i++) {
      byte[] bytes = new byte[]{(byte) i};
      keys.add(bytes);
      db.put(bytes, bytes);
    }
  }

  @After
  public void after() {
    db.close();
    env.close();
  }

  @Test
  public void testIterateForward() {
    try (Transaction tx = env.createReadTransaction(); EntryIterator it = db.iterate(tx)) {
      while (it.hasNext()) {
        Entry next = it.next();
        assertArrayEquals(keys.pollFirst(), next.getKey());
      }
      assertTrue(keys.isEmpty());
    }
  }

  @Test
  public void testIterateBackward() {
    try (Transaction tx = env.createReadTransaction(); EntryIterator it = db.iterateBackward(tx)) {
      while (it.hasNext()) {
        Entry next = it.next();
        assertArrayEquals(keys.pollLast(), next.getKey());
      }
      assertTrue(keys.isEmpty());
    }
  }

  @Test
  public void testSeekForward() {
    keys.pollFirst();
    keys.pollFirst();
    keys.pollFirst();
    keys.pollFirst();
    keys.pollFirst();
    try (Transaction tx = env.createReadTransaction(); EntryIterator it = db.seek(tx, new byte[]{5})) {
      while (it.hasNext()) {
        Entry next = it.next();
        assertArrayEquals(keys.pollFirst(), next.getKey());
      }
      assertTrue(keys.isEmpty());
    }
  }

  @Test
  public void testSeekBackward() {
    keys.pollLast();
    keys.pollLast();
    keys.pollLast();
    keys.pollLast();
    try (Transaction tx = env.createReadTransaction(); EntryIterator it = db.seekBackward(tx, new byte[]{5})) {
      while (it.hasNext()) {
        Entry next = it.next();
        assertArrayEquals(keys.pollLast(), next.getKey());
      }
      assertTrue(keys.isEmpty());
    }
  }

  @Test
  public void testIterable() {
    try (Transaction tx = env.createReadTransaction(); EntryIterator it = db.iterate(tx)) {
      for (Entry next : it.iterable()) {
        assertArrayEquals(keys.pollFirst(), next.getKey());
      }
    }
    assertTrue(keys.isEmpty());
  }
}

@@ -190,16 +190,43 @@
 eption;%0A
+import java.util.Iterator;%0A
 import j
@@ -246,16 +246,16 @@
 edList;%0A
-
 %0Aimport 
@@ -297,16 +297,60 @@
 Equals;%0A
+import static org.junit.Assert.assertFalse;%0A
 import s
@@ -1245,32 +1245,65 @@
 Key());%0A      %7D%0A
+      assertFalse(it.hasNext());%0A
       assertTrue
@@ -1597,32 +1597,65 @@
 Key());%0A      %7D%0A
+      assertFalse(it.hasNext());%0A
       assertTrue
@@ -2060,32 +2060,65 @@
 Key());%0A      %7D%0A
+      assertFalse(it.hasNext());%0A
       assertTrue
@@ -2505,32 +2505,65 @@
 Key());%0A      %7D%0A
+      assertFalse(it.hasNext());%0A
       assertTrue
@@ -2732,37 +2732,90 @@
     
-for (Entry next : it.iterable
+Iterator%3CEntry%3E iterator = it.iterable().iterator();%0A      while (iterator.hasNext
 ()) 
@@ -2852,36 +2852,47 @@
 ys.pollFirst(), 
+iterator.
 next
+()
 .getKey());%0A    
@@ -2891,24 +2891,63 @@
 ));%0A      %7D%0A
+      assertFalse(iterator.hasNext());%0A
     %7D%0A    as

Test Iterator contract for EntryIterator #52