/*
* Copyright 2013 Gordon Burgett and individual contributors
*
* 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 org.xflatdb.xflat.db;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.xflatdb.xflat.Cursor;
import org.xflatdb.xflat.KeyNotFoundException;
import org.xflatdb.xflat.convert.ConversionService;
import org.xflatdb.xflat.convert.DefaultConversionService;
import org.xflatdb.xflat.convert.converters.JDOMConverters;
import org.xflatdb.xflat.convert.converters.StringConverters;
import org.xflatdb.xflat.query.XPathQuery;
import org.xflatdb.xflat.query.XPathUpdate;
import org.hamcrest.Matchers;
import org.jdom2.Element;
import org.jdom2.xpath.XPathFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
import org.mockito.ArgumentCaptor;
import static org.mockito.Mockito.*;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.xflatdb.xflat.XFlatConstants;
import test.Bar;
import test.Foo;
/**
*
* @author gordon
*/
public class ConvertingTableTest {
public ConvertingTableTest() {
}
ConversionService conversionService;
Engine engine;
IdGenerator idGenerator;
private XPathFactory xpath;
ConvertingTable<Foo> getFooInstance(){
conversionService.addConverter(Foo.class, Element.class, new Foo.ToElementConverter());
conversionService.addConverter(Element.class, Foo.class, new Foo.FromElementConverter());
ConvertingTable<Foo> fooInstance = new ConvertingTable<>(Foo.class, "foo");
fooInstance.setConversionService(conversionService);
fooInstance.setEngineProvider(new EngineProvider() {
@Override
public Engine provideEngine() {
return engine;
}
});
fooInstance.setIdGenerator(idGenerator);
return fooInstance;
};
ConvertingTable<Bar> getBarInstance(){
conversionService.addConverter(Bar.class, Element.class, new Bar.ToElementConverter());
conversionService.addConverter(Element.class, Bar.class, new Bar.FromElementConverter());
ConvertingTable<Bar> barInstance = new ConvertingTable<>(Bar.class, "foo");
barInstance.setConversionService(conversionService);
barInstance.setEngineProvider(new EngineProvider() {
@Override
public Engine provideEngine() {
return engine;
}
});
barInstance.setIdGenerator(idGenerator);
return barInstance;
};
@Before
public void setUp() {
conversionService = new DefaultConversionService();
StringConverters.registerTo(conversionService);
JDOMConverters.registerTo(conversionService);
engine = mock(Engine.class);
idGenerator = mock(IdGenerator.class);
xpath = XPathFactory.instance();
}
@After
public void tearDown() {
}
private String getId(Element data){
return data.getAttributeValue("id", XFlatConstants.xFlatNs);
}
private void setId(Element e, String id){
e.setAttribute("id", id, XFlatConstants.xFlatNs);
}
@Test
public void testInsert_Foo_GeneratesId() throws Exception {
System.out.println("testInsert_Foo_GeneratesId");
Foo foo = new Foo();
foo.fooInt = 17;
String fooId = "testId";
when(idGenerator.generateNewId(String.class))
.thenReturn(fooId);
when(idGenerator.idToString(anyObject()))
.thenAnswer(byCallingToString());
//ACT
getFooInstance().insert(foo);
//ASSERT
ArgumentCaptor<Element> dataCaptor = ArgumentCaptor.forClass(Element.class);
verify(engine).insertRow(argThat(Matchers.equalTo(fooId)), dataCaptor.capture());
Element data = dataCaptor.getValue();
assertEquals("Should have set ID", fooId, getId(data));
assertEquals("Data should be a foo", "foo", data.getName());
assertEquals("Should have stored foo in element", "17", data.getChild("fooInt").getValue());
}//end testInsert_Foo_GeneratesId
@Test
public void testInsert_Foo_HasId_IdNotModified() throws Exception {
System.out.println("testInsert_Foo_HasId_IdNotModified");
Foo foo = new Foo();
foo.fooInt = 17;
foo.setId("fooId");
when(idGenerator.idToString(anyObject()))
.thenAnswer(byCallingToString());
//ACT
getFooInstance().insert(foo);
//ASSERT
ArgumentCaptor<Element> dataCaptor = ArgumentCaptor.forClass(Element.class);
verify(engine).insertRow(argThat(Matchers.equalTo("fooId")), dataCaptor.capture());
verify(idGenerator, never()).generateNewId(any(Class.class));
Element data = dataCaptor.getValue();
assertEquals("Should have kept ID", "fooId", getId(data));
assertEquals("Data should be a foo", "foo", data.getName());
assertEquals("Should have stored foo in element", "17", data.getChild("fooInt").getValue());
}//end testInsert_Foo_HasId_IdNotModified
@Test
public void testInsert_Bar_GeneratesId() throws Exception {
System.out.println("testInsert_Bar_GeneratesId");
Bar bar = new Bar();
bar.barString = "some data";
String barId = "testId";
when(idGenerator.generateNewId(String.class))
.thenReturn(barId);
when(idGenerator.idToString(anyObject()))
.thenAnswer(byCallingToString());
//ACT
getBarInstance().insert(bar);
//ASSERT
ArgumentCaptor<Element> dataCaptor = ArgumentCaptor.forClass(Element.class);
verify(engine).insertRow(argThat(Matchers.equalTo(barId)), dataCaptor.capture());
Element data = dataCaptor.getValue();
assertEquals("Should have set ID", barId, getId(data));
assertEquals("Data should be a bar", "bar", data.getName());
assertEquals("Should have stored bar in element", "some data", data.getChild("barString").getValue());
}//end testInsert_Bar_GeneratesId
@Test
public void testFind_Foo_IdDoesNotExist_ReturnsNull() throws Exception {
System.out.println("testFind_Foo_IdDoesNotExist_ReturnsNull");
String fooId = "test id";
when(idGenerator.idToString(anyObject()))
.thenAnswer(byCallingToString());
Foo inDb = getFooInstance().find(fooId);
assertNull("Nothing in db, should find nothing", inDb);
verify(engine).readRow(fooId);
}//end testFind_Foo_IdDoesNotExist_ReturnsNull
@Test
public void testFind_Foo_GetsElement_DeserializesAndSetsId() throws Exception {
System.out.println("testFind_Foo_GetsElement_DeserializesAndSetsId");
String fooId = "test id";
when(idGenerator.idToString(anyObject()))
.thenAnswer(byCallingToString());
when(idGenerator.stringToId(any(String.class), eq(String.class)))
.thenAnswer(byReturningFirstParam());
Element inDb = new Element("foo").setAttribute("id", fooId, Foo.FooIdNs);
setId(inDb, fooId);
inDb.addContent(new Element("fooInt").setText("32"));
when(engine.readRow(fooId))
.thenReturn(inDb);
//ACT
Foo found = getFooInstance().find(fooId);
//ASSERT
assertNotNull("Should have found some data", found);
assertEquals("Should have deserialized", 32, found.fooInt);
assertEquals("Should have set ID", fooId, found.getId());
}//end testFind_Foo_GetsElement_DeserializesAndSetsId
@Test
public void testFind_Bar_GetsElement_Deserializes() throws Exception {
System.out.println("testFind_Bar_GetsElement_Deserializes");
String barId = "test id";
when(idGenerator.idToString(anyObject()))
.thenAnswer(byCallingToString());
Element inDb = new Element("bar");
setId(inDb, barId);
inDb.addContent(new Element("barString").setText("stuff"));
when(engine.readRow(barId))
.thenReturn(inDb);
//ACT
Bar found = getBarInstance().find(barId);
//ASSERT
assertNotNull("Should get a bar", found);
assertEquals("Should deserialize correctly", "stuff", found.barString);
}//end testFind_Bar_GetsElement_Deserializes
@Test
public void testFindOne_Foo_DeserializesAndClosesCursor() throws Exception {
System.out.println("testFindOne_Foo_DeserializesAndClosesCursor");
String fooId = "test id";
when(idGenerator.idToString(anyObject()))
.thenAnswer(byCallingToString());
Element inDb = new Element("foo");
setId(inDb, fooId);
inDb.addContent(new Element("fooInt").setText("32"));
XPathQuery query = XPathQuery.eq(xpath.compile("foo/fooInt"), 32);
Cursor<Element> mockCursor = getMockCursor(inDb);
when(engine.queryTable(query))
.thenReturn(mockCursor);
//ACT
Foo found = getFooInstance().findOne(query);
//ASSERT
assertNotNull("Should have found one", found);
assertEquals("Should have deserialized", 32, found.fooInt);
verify(mockCursor).close();
}//end testFindOne_Foo_DeserializesAndClosesCursor
@Test
public void testFind_Foo_ReturnsConvertingCursor() throws Exception {
System.out.println("testFind_Foo_ReturnsConvertingCursor");
when(idGenerator.idToString(anyObject()))
.thenAnswer(byCallingToString());
when(idGenerator.stringToId(any(String.class), eq(String.class)))
.thenAnswer(byReturningFirstParam());
Element inDb1 = new Element("foo")
.setAttribute("id", "id 1", Foo.FooIdNs)
.addContent(new Element("fooInt").setText("32"));
setId(inDb1, "id 1");
Element inDb2 = new Element("foo")
.setAttribute("id", "id 2", Foo.FooIdNs)
.addContent(new Element("fooInt").setText("33"));
setId(inDb2, "id 2");
XPathQuery query = XPathQuery.gte(xpath.compile("foo/fooInt"), 32);
Cursor<Element> mockCursor = getMockCursor(inDb1, inDb2);
when(engine.queryTable(query))
.thenReturn(mockCursor);
//ACT
Cursor<Foo> fooCursor = getFooInstance().find(query);
//ASSERT
Iterator<Foo> i = fooCursor.iterator();
Foo found1 = i.next();
Foo found2 = i.next();
assertEquals("Should have gotten correct values", 32, found1.fooInt);
assertEquals("Should have gotten correct values", 33, found2.fooInt);
assertEquals("Should have gotten correct IDs", "id 1", found1.getId());
assertEquals("Should have gotten correct IDs", "id 2", found2.getId());
//verify engine cursor is closed when we close returned cursor
verify(mockCursor, never()).close();
fooCursor.close();
verify(mockCursor).close();
}//end testFind_Foo_ReturnsConvertingCursor
@Test
public void testFindAll_Foo_ConvertsAllToList() throws Exception {
System.out.println("testFindAll_Foo_ConvertsAllToList");
when(idGenerator.idToString(anyObject()))
.thenAnswer(byCallingToString());
when(idGenerator.stringToId(any(String.class), eq(String.class)))
.thenAnswer(byReturningFirstParam());
Element inDb1 = new Element("foo")
.setAttribute("id", "id 1", Foo.FooIdNs)
.addContent(new Element("fooInt").setText("32"));
setId(inDb1, "id 1");
Element inDb2 = new Element("foo")
.setAttribute("id", "id 2", Foo.FooIdNs)
.addContent(new Element("fooInt").setText("33"));
setId(inDb2, "id 2");
XPathQuery query = XPathQuery.gte(xpath.compile("foo/fooInt"), 32);
Cursor<Element> mockCursor = getMockCursor(inDb1, inDb2);
when(engine.queryTable(query))
.thenReturn(mockCursor);
//ACT
List<Foo> fooList = getFooInstance().findAll(query);
//ASSERT
Foo found1 = fooList.get(0);
Foo found2 = fooList.get(1);
assertEquals("Should have gotten correct values", 32, found1.fooInt);
assertEquals("Should have gotten correct values", 33, found2.fooInt);
assertEquals("Should have gotten correct IDs", "id 1", found1.getId());
assertEquals("Should have gotten correct IDs", "id 2", found2.getId());
}//end testFindAll_Foo_ConvertsAllToList
@Test
public void testReplace_Foo_ReplacesRowWithSameId() throws Exception {
System.out.println("testReplace_Foo_ReplacesRowWithSameId");
when(idGenerator.idToString(anyObject()))
.thenAnswer(byCallingToString());
Foo replacement = new Foo();
replacement.fooInt = 17;
replacement.setId("test id");
//act
this.getFooInstance().replace(replacement);
//assert
ArgumentCaptor<Element> captor = ArgumentCaptor.forClass(Element.class);
verify(engine).replaceRow(eq("test id"), captor.capture());
assertEquals("Should have replaced with serialized data", "17",
captor.getValue().getChild("fooInt").getText());
}//end testReplace_Foo_ReplacesRowWithSameId
@Test
public void testReplace_Foo_NoId_ThrowsKeyNotFoundException() throws Exception {
System.out.println("testReplace_Foo_NoId_ThrowsKeyNotFoundException");
when(idGenerator.idToString(anyObject()))
.thenAnswer(byCallingToString());
Foo replacement = new Foo();
replacement.fooInt = 17;
replacement.setId(null);
boolean didThrow = false;
try {
//ACT
this.getFooInstance().replace(replacement);
} catch (KeyNotFoundException expected) {
didThrow = true;
}
assertTrue("Should have thrown KeyNotFoundException", didThrow);
}//end testReplace_Foo_NoId_ThrowsKeyNotFoundException
@Test
public void testReplace_Bar_IdIsKnown_ReplacesWithCorrectId() throws Exception {
System.out.println("testReplace_Bar_IdIsKnown_ReplacesWithCorrectId");
when(idGenerator.idToString(anyObject()))
.thenAnswer(byCallingToString());
Element inDb = new Element("bar").setContent(new Element("barString").setText("test val"));
setId(inDb, "bar id 1");
when(engine.readRow("bar id 1"))
.thenReturn(inDb);
ConvertingTable<Bar> instance = getBarInstance();
Bar barInDb = instance.find("bar id 1");
barInDb.barString = "other value";
//ACT
instance.replace(barInDb);
//ASSERT
ArgumentCaptor<Element> captor = ArgumentCaptor.forClass(Element.class);
verify(engine).replaceRow(eq("bar id 1"), captor.capture());
assertEquals("Should have updated to other value", "other value",
captor.getValue().getChild("barString").getText());
}//end testReplace_Bar_IdIsKnown_ReplacesWithCorrectId
@Test
public void testReplace_Bar_NewInstance_ThrowsKeyNotFoundException() throws Exception {
System.out.println("testReplace_Bar_NewInstance_ThrowsKeyNotFoundException");
when(idGenerator.idToString(anyObject()))
.thenAnswer(byCallingToString());
Element inDb = new Element("bar").setContent(new Element("barString").setText("test val"));
setId(inDb, "bar id 1");
when(engine.readRow("bar id 1"))
.thenReturn(inDb);
ConvertingTable<Bar> instance = getBarInstance();
Bar barInDb = instance.find("bar id 1");
Bar newBar = new Bar();
newBar.barString = "test val";
//ACT
boolean didThrow = false;
try {
//ACT
instance.replace(newBar);
} catch (KeyNotFoundException expected) {
didThrow = true;
}
assertTrue("Should have thrown KeyNotFoundException", didThrow);
//ASSERT
verify(engine, never()).replaceRow(any(String.class), any(Element.class));
}//end testReplace_Bar_NewInstance_ThrowsKeyNotFoundException
@Test
public void testReplaceOne_Foo_FindsAndReplaces() throws Exception {
System.out.println("testReplaceOne_Foo_FindsAndReplaces");
when(idGenerator.stringToId(anyString(), eq(String.class)))
.thenAnswer(byReturningFirstParam());
Element existing = new Element("foo").addContent(new Element("fooInt").setText("17"));
setId(existing, "test id 1");
XPathQuery query = XPathQuery.eq(xpath.compile("foo/fooInt"), 17);
Cursor<Element> mockCursor = getMockCursor(existing);
when(engine.queryTable(query))
.thenReturn(mockCursor);
Foo newFoo = new Foo();
newFoo.fooInt = 4;
newFoo.setId("to be replaced");
//ACT
getFooInstance().replaceOne(query, newFoo);
//ASSERT
ArgumentCaptor<Element> captor = ArgumentCaptor.forClass(Element.class);
verify(engine).replaceRow(eq("test id 1"), captor.capture());
assertEquals("Should have replaced value", "4",
captor.getValue().getChild("fooInt").getText());
assertEquals("Should have set ID on object", "test id 1",
newFoo.getId());
}//end testReplaceOne_Foo_FindsAndReplaces
@Test
public void testReplaceOne_ConcurrentRemove_FindsSecond() throws Exception {
System.out.println("testReplaceOne_ConcurrentRemove_FindsSecond");
when(idGenerator.stringToId(anyString(), eq(String.class)))
.thenAnswer(byReturningFirstParam());
Element existing = new Element("foo").addContent(new Element("fooInt").setText("17"));
setId(existing, "test id 1");
Element existing2 = new Element("foo").addContent(new Element("fooInt").setText("18"));
setId(existing2, "test id 2");
XPathQuery query = XPathQuery.gte(xpath.compile("foo/fooInt"), 17);
Cursor<Element> cursor1 = getMockCursor(existing);
Cursor<Element> cursor2 = getMockCursor(existing2);
when(engine.queryTable(query))
.thenReturn(cursor1, cursor2);
doThrow(new KeyNotFoundException("test"))
.when(engine).replaceRow(eq("test id 1"), any(Element.class));
Foo newFoo = new Foo();
newFoo.fooInt = 4;
newFoo.setId("to be replaced");
//ACT
getFooInstance().replaceOne(query, newFoo);
//ASSERT
ArgumentCaptor<Element> captor = ArgumentCaptor.forClass(Element.class);
verify(engine).replaceRow(eq("test id 2"), captor.capture());
assertEquals("Should have replaced value", "4",
captor.getValue().getChild("fooInt").getText());
assertEquals("Should have set ID on object", "test id 2",
newFoo.getId());
}//end testReplaceOne_ConcurrentRemove_FindsSecond
@Test
public void testUpsert_Foo_NoId_InsertsWithNewId() throws Exception {
System.out.println("testUpsert_Foo_NoId_InsertsWithNewId");
when(idGenerator.idToString(anyObject()))
.thenAnswer(byCallingToString());
when(idGenerator.stringToId(any(String.class), eq(String.class)))
.thenAnswer(byReturningFirstParam());
String id = "test id";
when(idGenerator.generateNewId(String.class))
.thenReturn(id);
when(engine.upsertRow(eq(id), any(Element.class)))
.thenReturn(true);
Foo toUpsert = new Foo();
toUpsert.fooInt = 51;
//ACT
boolean didInsert = this.getFooInstance().upsert(toUpsert);
//ASSERT
assertTrue("Should have inserted new foo", didInsert);
ArgumentCaptor<Element> data = ArgumentCaptor.forClass(Element.class);
verify(engine).upsertRow(eq(id), data.capture());
assertEquals("Should have inserted correct data", "51",
data.getValue().getChild("fooInt").getText());
}//end testUpsert_Foo_NoId_InsertsWithNewId
@Test
public void testUpsert_Foo_HasId_UpsertsWithId() throws Exception {
System.out.println("testUpsert_Foo_HasId_UpsertsWithId");
when(idGenerator.idToString(anyObject()))
.thenAnswer(byCallingToString());
when(idGenerator.stringToId(any(String.class), eq(String.class)))
.thenAnswer(byReturningFirstParam());
String id = "test id";
Foo toUpsert = new Foo();
toUpsert.fooInt = 51;
toUpsert.setId(id);
//ACT
boolean didInsert = this.getFooInstance().upsert(toUpsert);
//ASSERT
assertFalse("Should have gotten default from upsertRow", didInsert);
ArgumentCaptor<Element> data = ArgumentCaptor.forClass(Element.class);
verify(engine).upsertRow(eq(id), data.capture());
assertEquals("Should have inserted correct data", "51",
data.getValue().getChild("fooInt").getText());
verify(idGenerator, never()).generateNewId(any(Class.class));
}//end testUpsert_Foo_HasId_UpsertsWithId
@Test
public void testUpsert_Bar_NewInstance_GeneratesNewIdAndRemembersIt() throws Exception {
System.out.println("testUpsert_Bar_NewInstance_GeneratesNewIdAndRemembersIt");
Bar toUpsert = new Bar();
toUpsert.barString = "test data";
String id = "test id";
when(idGenerator.generateNewId(String.class))
.thenReturn(id, "second invocation");
when(engine.upsertRow(eq(id), any(Element.class)))
.thenReturn(true);
//ACT
ConvertingTable<Bar> instance = this.getBarInstance();
boolean didInsert = instance.upsert(toUpsert);
//ASSERT
assertTrue("Should have inserted new bar", didInsert);
ArgumentCaptor<Element> data = ArgumentCaptor.forClass(Element.class);
verify(engine).upsertRow(eq(id), data.capture());
assertEquals("Should have inserted correct data", "test data",
data.getValue().getChild("barString").getText());
//verify we remembered the ID
instance.replace(toUpsert);
verify(engine).replaceRow(eq(id), any(Element.class));
//verify we only generated the ID once
verify(idGenerator, times(1)).generateNewId(String.class);
}//end testUpsert_Bar_NewInstance_GeneratesNewIdAndRemembersIt
@Test
public void testUpsert_Bar_RememberedInstance_Upserts() throws Exception {
System.out.println("testUpsert_Bar_RememberedInstance_Upserts");
Bar toUpsert = new Bar();
toUpsert.barString = "test data";
String id = "test id";
when(idGenerator.generateNewId(String.class))
.thenReturn(id, "second invocation");
ConvertingTable<Bar> instance = this.getBarInstance();
instance.insert(toUpsert);
toUpsert.barString = "new data";
//ACT
boolean didInsert = instance.upsert(toUpsert);
//ASSERT
assertFalse("should get default value from calling stub upsert", didInsert);
ArgumentCaptor<Element> captor = ArgumentCaptor.forClass(Element.class);
verify(engine).upsertRow(eq(id), captor.capture());
assertEquals("Should update with correct data", "new data",
captor.getValue().getChild("barString").getText());
verify(idGenerator, times(1)).generateNewId(any(Class.class));
}//end testUpsert_Bar_RememberedInstance_Upserts
@Test
public void testUpdate_Id_ConvertsId() throws Exception {
System.out.println("testUpdate_Id_ConvertsId");
String id = "test id";
Object oId = new Object();
when(idGenerator.idToString(oId))
.thenReturn(id);
XPathUpdate update = XPathUpdate.set(xpath.compile("fooInt"), 32);
when(engine.update(id, update))
.thenReturn(Boolean.TRUE);
//ACT
boolean didUpdate = this.getFooInstance().update(oId, update);
//ASSERT
assertTrue("Should have invoked update to get true result", didUpdate);
verify(engine).update(id, update);
}//end testUpdate_Id_ConvertsId
@Test
public void testUpdate_Query_Passthrough() throws Exception {
System.out.println("testUpdate_Query_Passthrough");
XPathQuery query = XPathQuery.eq(xpath.compile("fooInt"), 17);
XPathUpdate update = XPathUpdate.set(xpath.compile("fooInt"), 35);
when(engine.update(query, update))
.thenReturn(32);
//ACT
int rowsUpdated = this.getFooInstance().update(query, update);
//ASSERT
assertEquals("Should have gotten the result of our stubbed call",
32, rowsUpdated);
}//end testUpdate_Query_Passthrough
@Test
public void testDelete_Id_ConvertsId() throws Exception {
System.out.println("testDelete_Id_ConvertsId");
String id = "test id";
Object oId = new Object();
when(idGenerator.idToString(oId))
.thenReturn(id);
//ACT
this.getFooInstance().delete(oId);
//ASSERT
verify(engine).deleteRow(id);
}//end testDelete_Id_ConvertsId
@Test
public void testDeleteAll_Passthrough() throws Exception {
System.out.println("testDeleteAll_Passthrough");
XPathQuery query = XPathQuery.eq(xpath.compile("foo/fooInt"), 17);
//ACT
this.getFooInstance().deleteAll(query);
//ASSERT
verify(engine).deleteAll(query);
}//end testDeleteAll_Passthrough
private Answer<String> byCallingToString(){
return new Answer<String>(){
@Override
public String answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
return args[0].toString();
}
};
}
private Answer<Object> byReturningFirstParam(){
return new Answer<Object>(){
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
return args[0];
}
};
}
private Cursor<Element> getMockCursor(Element... elements){
return getMockCursor(Arrays.asList(elements));
}
private Cursor<Element> getMockCursor(final Iterable<Element> elements){
Cursor<Element> ret = mock(Cursor.class);
when(ret.iterator())
.thenReturn(elements.iterator());
return ret;
}
}