VIVO-873 Improve unit tests of DocumentModifier classes

Add copy constructors, equals(), and hashCode() to BaseSearchInputDocument and BaseSearchInputField
This commit is contained in:
Jim Blake 2014-10-17 10:52:11 -04:00
parent 3ccb10dc83
commit 7a12354430
5 changed files with 170 additions and 11 deletions

View file

@ -6,7 +6,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputDocument;
/**
* This interface represents an object that can add to a SearchInputDocument.
* An object that can add to a SearchInputDocument.
*/
public interface DocumentModifier {
/**
@ -20,7 +20,9 @@ public interface DocumentModifier {
*/
public void modifyDocument(Individual individual, SearchInputDocument doc);
// called to inform the DocumentModifier that the system is shutting down
/**
* Called to inform the DocumentModifier that the system is shutting down.
*/
public void shutdown();
}

View file

@ -18,7 +18,7 @@ import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory;
import edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames;
/**
* Adds all labels to name fields, not just the one returned by Indivdiual.getName().
* Adds all labels to name fields, not just the one returned by Individual.getName().
*/
public class NameFields implements DocumentModifier {
RDFServiceFactory rsf;

View file

@ -14,8 +14,28 @@ import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputField;
* A foundation class for implementing SearchInputDocument.
*/
public class BaseSearchInputDocument implements SearchInputDocument {
private final Map<String, SearchInputField> fieldMap = new HashMap<>();
private float documentBoost = 1.0F;
private final Map<String, SearchInputField> fieldMap;
private float documentBoost;
/**
* Default constructor.
*/
public BaseSearchInputDocument() {
this.fieldMap = new HashMap<>();
this.documentBoost = 1.0F;
}
/**
* Create a deep copy, down to the value objects.
*/
public BaseSearchInputDocument(BaseSearchInputDocument doc) {
this.documentBoost = doc.documentBoost;
this.fieldMap = new HashMap<>();
for (String fieldName : doc.getFieldMap().keySet()) {
this.fieldMap.put(fieldName,
new BaseSearchInputField(doc.getField(fieldName)));
}
}
@Override
public void addField(SearchInputField field) {
@ -77,6 +97,29 @@ public class BaseSearchInputDocument implements SearchInputDocument {
return new BaseSearchInputField(name);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + Float.floatToIntBits(documentBoost);
result = prime * result + fieldMap.hashCode();
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
BaseSearchInputDocument other = (BaseSearchInputDocument) obj;
return (Float.floatToIntBits(documentBoost) == Float
.floatToIntBits(other.documentBoost))
&& fieldMap.equals(other.fieldMap);
}
@Override
public String toString() {
return "BaseSearchInputDocument[fieldMap=" + fieldMap

View file

@ -14,12 +14,22 @@ import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputField;
*/
public class BaseSearchInputField implements SearchInputField {
private final String name;
private final List<Object> valueList = new ArrayList<>();
private float boost = 1.0F;
private final List<Object> valueList;
private float boost;
public BaseSearchInputField(String name) {
this.name = name;
this.valueList = new ArrayList<>();
this.boost = 1.0F;
}
/**
* Create a copy of the field.
*/
public BaseSearchInputField(SearchInputField field) {
this.name = field.getName();
this.valueList = new ArrayList<>(field.getValues());
this.boost = field.getBoost();
}
@Override
@ -61,10 +71,58 @@ public class BaseSearchInputField implements SearchInputField {
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + Float.floatToIntBits(boost);
result = prime * result + name.hashCode();
result = prime * result + valueList.hashCode();
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
BaseSearchInputField other = (BaseSearchInputField) obj;
return (Float.floatToIntBits(boost) == Float
.floatToIntBits(other.boost))
&& name.equals(other.name)
&& equalsIgnoreOrder(valueList, other.valueList);
}
/**
* Can't just compare the value lists, because they are considered to be
* equivalent even if the order is differemt.
*
* Can't just convert them to Sets, because either list may contain the same
* object multiple times.
*
* Remove the members of list1 from list2, one at a time. If any member is
* not found, the lists are not equivalent.
*/
private boolean equalsIgnoreOrder(List<Object> list1, List<Object> list2) {
if (list1.size() != list2.size()) {
return false;
}
List<Object> remaining = new ArrayList<>(list2);
for (Object value : list1) {
if (!remaining.remove(value)) {
return false;
}
}
return true;
}
@Override
public String toString() {
return "BaseSearchInputField[name=" + name + ", valueList="
+ valueList + ", boost=" + boost + "]";
return "BaseSearchInputField[name=" + name + ", valueList=" + valueList
+ ", boost=" + boost + "]";
}
}

View file

@ -0,0 +1,56 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.searchengine.base;
import static org.junit.Assert.*;
import java.util.Collection;
import java.util.Map;
import org.junit.Test;
import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchInputField;
/**
* TODO
*/
public class BaseSearchInputDocumentTest {
/**
* The copy constructor should make a deep copy, down to (but not including)
* the field values. The component parts should be equal, but not the same.
*/
@Test
public void copyConstructor() {
BaseSearchInputDocument doc = new BaseSearchInputDocument();
doc.setDocumentBoost(42.6F);
SearchInputField field1 = new BaseSearchInputField("testField");
field1.addValues("value1", "value2");
field1.setBoost(1.1F);
doc.addField(field1);
SearchInputField field2 = new BaseSearchInputField("anotherField");
field2.setBoost(-16F);
doc.addField(field2);
BaseSearchInputDocument other = new BaseSearchInputDocument(doc);
assertEquals(doc, other);
assertEquals(doc.getDocumentBoost(), other.getDocumentBoost(), 0.01F);
Map<String, SearchInputField> docMap = doc.getFieldMap();
Map<String, SearchInputField> otherMap = other.getFieldMap();
assertEquals(docMap, otherMap);
assertNotSame(docMap, otherMap);
for (String fieldName : docMap.keySet()) {
SearchInputField docField = doc.getField(fieldName);
SearchInputField otherField = other.getField(fieldName);
assertEquals(docField, otherField);
assertNotSame(docField, otherField);
Collection<Object> docFieldValues = docField.getValues();
Collection<Object> otherFieldValues = otherField.getValues();
assertEquals(docFieldValues, otherFieldValues);
}
}
}