Added a first small set of hamcrest matchers

A first implementation of adding matchers and helper methods to elasticsearch.
The following ones are supported

assertHitCount(searchResponse, 2);

// helper methods to easily access the first hits
assertFirstHit(searchResponse, hasId("foo")):
assertSecondHit(searchResponse, hasType("foo")):
assertThirdHit(searchResponse, hasIndex("foo")):

// methods to access all other hits
assertSearchHit(searchResponse, 5, hasId("10"));
// same as above, but maybe more readable
assertSearchHit(searchResponse.getHits().getAt(5), hasIndex("foo"));

I changed GeoFilterTests to show how it works.

Furthermore I inlined assertHighlight() from HighlighterSearchTests.
The ElasticsearchAssertions class can be used now as a centralized assertion class
in order have a centralized class for every developer to look at.
This commit is contained in:
Alexander Reelsen 2013-04-30 12:40:38 +02:00
parent 345b63e2d0
commit ad92d82680
4 changed files with 200 additions and 26 deletions

View File

@ -0,0 +1,86 @@
/*
* Licensed to ElasticSearch and Shay Banon under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. ElasticSearch licenses this
* file to you 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.elasticsearch.test.hamcrest;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.SearchHit;
import org.hamcrest.Matcher;
/**
*
*/
public class ElasticsearchAssertions {
/*
* assertions
*/
public static void assertHitCount(SearchResponse searchResponse, long expectedHitCount) {
assertThat(searchResponse.getHits().totalHits(), is(expectedHitCount));
}
public static void assertFirstHit(SearchResponse searchResponse, Matcher<SearchHit> matcher) {
assertSearchHit(searchResponse, 1, matcher);
}
public static void assertSecondHit(SearchResponse searchResponse, Matcher<SearchHit> matcher) {
assertSearchHit(searchResponse, 2, matcher);
}
public static void assertThirdHit(SearchResponse searchResponse, Matcher<SearchHit> matcher) {
assertSearchHit(searchResponse, 3, matcher);
}
public static void assertSearchHit(SearchResponse searchResponse, int number, Matcher<SearchHit> matcher) {
assert number > 0;
assertThat("SearchHit number must be greater than 0", number, greaterThan(0));
assertThat(searchResponse.getHits().totalHits(), greaterThanOrEqualTo((long)number));
assertSearchHit(searchResponse.getHits().getAt(number-1), matcher);
}
public static void assertSearchHit(SearchHit searchHit, Matcher<SearchHit> matcher) {
assertThat(searchHit, matcher);
}
public static void assertHighlight(SearchResponse resp, int hit, String field, int fragment, Matcher<String> matcher) {
assertThat(resp.getShardFailures().length, equalTo(0));
assertThat(resp.getHits().hits().length, greaterThan(hit));
assertThat(resp.getHits().hits()[hit].getHighlightFields().get(field), notNullValue());
assertThat(resp.getHits().hits()[hit].getHighlightFields().get(field).fragments().length, greaterThan(fragment));
assertThat(resp.getHits().hits()[hit].highlightFields().get(field).fragments()[fragment].string(), matcher);
}
/*
* matchers
*/
public static Matcher<SearchHit> hasId(final String id) {
return new ElasticsearchMatchers.SearchHitHasIdMatcher(id);
}
public static Matcher<SearchHit> hasType(final String type) {
return new ElasticsearchMatchers.SearchHitHasTypeMatcher(type);
}
public static Matcher<SearchHit> hasIndex(final String index) {
return new ElasticsearchMatchers.SearchHitHasIndexMatcher(index);
}
}

View File

@ -0,0 +1,96 @@
/*
* Licensed to ElasticSearch and Shay Banon under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. ElasticSearch licenses this
* file to you 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.elasticsearch.test.hamcrest;
import org.elasticsearch.search.SearchHit;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
public class ElasticsearchMatchers {
public static class SearchHitHasIdMatcher extends TypeSafeMatcher<SearchHit> {
private String id;
public SearchHitHasIdMatcher(String id) {
this.id = id;
}
@Override
protected boolean matchesSafely(SearchHit searchHit) {
return searchHit.getId().equals(id);
}
@Override
public void describeMismatchSafely(final SearchHit searchHit, final Description mismatchDescription) {
mismatchDescription.appendText(" was ").appendValue(searchHit.getId());
}
@Override
public void describeTo(final Description description) {
description.appendText("searchHit id should be ").appendValue(id);
}
}
public static class SearchHitHasTypeMatcher extends TypeSafeMatcher<SearchHit> {
private String type;
public SearchHitHasTypeMatcher(String type) {
this.type = type;
}
@Override
public boolean matchesSafely(final SearchHit searchHit) {
return searchHit.getType().equals(type);
}
@Override
public void describeMismatchSafely(final SearchHit searchHit, final Description mismatchDescription) {
mismatchDescription.appendText(" was ").appendValue(searchHit.getType());
}
@Override
public void describeTo(final Description description) {
description.appendText("searchHit type should be ").appendValue(type);
}
}
public static class SearchHitHasIndexMatcher extends TypeSafeMatcher<SearchHit> {
private String index;
public SearchHitHasIndexMatcher(String index) {
this.index = index;
}
@Override
public boolean matchesSafely(final SearchHit searchHit) {
return searchHit.getIndex().equals(index);
}
@Override
public void describeMismatchSafely(final SearchHit searchHit, final Description mismatchDescription) {
mismatchDescription.appendText(" was ").appendValue(searchHit.getIndex());
}
@Override
public void describeTo(final Description description) {
description.appendText("searchHit index should be ").appendValue(index);
}
}
}

View File

@ -25,6 +25,7 @@ import static org.elasticsearch.index.query.FilterBuilders.geoDistanceFilter;
import static org.elasticsearch.index.query.QueryBuilders.fieldQuery;
import static org.elasticsearch.index.query.QueryBuilders.filteredQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.equalTo;
@ -281,15 +282,15 @@ public class GeoFilterTests extends AbstractNodesTests {
.setQuery(matchAllQuery())
.setFilter(FilterBuilders.geoIntersectionFilter("area", ShapeBuilder.newPoint(3, 3)))
.execute().actionGet();
assertThat(result.getHits().getTotalHits(), equalTo(1L));
assertThat(result.getHits().getAt(0).getId(), equalTo("1"));
assertHitCount(result, 1);
assertFirstHit(result, hasId("1"));
// Point in polygon hole
result = client.prepareSearch()
.setQuery(matchAllQuery())
.setFilter(FilterBuilders.geoIntersectionFilter("area", ShapeBuilder.newPoint(4.5, 4.5)))
.execute().actionGet();
assertThat(result.getHits().getTotalHits(), equalTo(0L));
assertHitCount(result, 0);
// by definition the border of a polygon belongs to the inner
// so the border of a polygons hole also belongs to the inner
@ -300,16 +301,16 @@ public class GeoFilterTests extends AbstractNodesTests {
.setQuery(matchAllQuery())
.setFilter(FilterBuilders.geoIntersectionFilter("area", ShapeBuilder.newPoint(10.0, 5.0)))
.execute().actionGet();
assertThat(result.getHits().getTotalHits(), equalTo(1L));
assertThat(result.getHits().getAt(0).getId(), equalTo("1"));
assertHitCount(result, 1);
assertFirstHit(result, hasId("1"));
// Point on hole border
result = client.prepareSearch()
.setQuery(matchAllQuery())
.setFilter(FilterBuilders.geoIntersectionFilter("area", ShapeBuilder.newPoint(5.0, 2.0)))
.execute().actionGet();
assertThat(result.getHits().getTotalHits(), equalTo(1L));
assertThat(result.getHits().getAt(0).getId(), equalTo("1"));
assertHitCount(result, 1);
assertFirstHit(result, hasId("1"));
if(disjointSupport) {
// Point not in polygon
@ -317,15 +318,15 @@ public class GeoFilterTests extends AbstractNodesTests {
.setQuery(matchAllQuery())
.setFilter(FilterBuilders.geoDisjointFilter("area", ShapeBuilder.newPoint(3, 3)))
.execute().actionGet();
assertThat(result.getHits().getTotalHits(), equalTo(0L));
assertHitCount(result, 0);
// Point in polygon hole
result = client.prepareSearch()
.setQuery(matchAllQuery())
.setFilter(FilterBuilders.geoDisjointFilter("area", ShapeBuilder.newPoint(4.5, 4.5)))
.execute().actionGet();
assertThat(result.getHits().getTotalHits(), equalTo(1L));
assertThat(result.getHits().getAt(0).getId(), equalTo("1"));
assertHitCount(result, 1);
assertFirstHit(result, hasId("1"));
}
// Create a polygon that fills the empty area of the polygon defined above
@ -345,8 +346,8 @@ public class GeoFilterTests extends AbstractNodesTests {
.setQuery(matchAllQuery())
.setFilter(FilterBuilders.geoIntersectionFilter("area", ShapeBuilder.newPoint(4.5, 4.5)))
.execute().actionGet();
assertThat(result.getHits().getTotalHits(), equalTo(1L));
assertThat(result.getHits().getAt(0).getId(), equalTo("2"));
assertHitCount(result, 1);
assertFirstHit(result, hasId("2"));
// Create Polygon with hole and common edge
PolygonBuilder builder = ShapeBuilder.newPolygon()
@ -365,7 +366,7 @@ public class GeoFilterTests extends AbstractNodesTests {
.setQuery(matchAllQuery())
.setFilter(FilterBuilders.geoWithinFilter("area", builder.build()))
.execute().actionGet();
assertThat(result.getHits().getTotalHits(), equalTo(2L));
assertHitCount(result, 2);
}
/* TODO: fix Polygon builder! It is not possible to cross the lats -180 and 180.
@ -424,7 +425,7 @@ public class GeoFilterTests extends AbstractNodesTests {
.setQuery(fieldQuery("_id", key))
.execute().actionGet();
assertThat(searchResponse.getHits().getTotalHits(), equalTo(1L));
assertHitCount(searchResponse, 1);
for (SearchHit hit : searchResponse.getHits()) {
assertThat(hit.getId(), equalTo(key));
@ -438,7 +439,7 @@ public class GeoFilterTests extends AbstractNodesTests {
.bottomRight(-90, 179.99999))
).execute().actionGet();
assertThat(world.getHits().totalHits(), equalTo(246L));
assertHitCount(world, 246);
SearchResponse distance = client.prepareSearch().addField("pin").setQuery(
filteredQuery(
@ -446,7 +447,7 @@ public class GeoFilterTests extends AbstractNodesTests {
geoDistanceFilter("pin").distance("425km").point(51.11, 9.851)
)).execute().actionGet();
assertThat(distance.getHits().totalHits(), equalTo(5L));
assertHitCount(distance, 5);
GeoPoint point = new GeoPoint();
for (SearchHit hit : distance.getHits()) {
String name = hit.getId();

View File

@ -60,6 +60,7 @@ import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.QueryBuilders.*;
import static org.elasticsearch.search.builder.SearchSourceBuilder.highlight;
import static org.elasticsearch.search.builder.SearchSourceBuilder.searchSource;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThan;
@ -167,16 +168,6 @@ public class HighlighterSearchTests extends AbstractNodesTests {
}
public void assertHighlight(SearchResponse resp, int hit, String field, int fragment, Matcher<String> matcher) {
assertThat(resp.getShardFailures().length, equalTo(0));
assertThat(resp.getHits().hits().length, greaterThan(hit));
assertThat(resp.getHits().hits()[hit].getHighlightFields().get(field), notNullValue());
assertThat(resp.getHits().hits()[hit].getHighlightFields().get(field).fragments().length, greaterThan(fragment));
assertThat(resp.getHits().hits()[hit].highlightFields().get(field).fragments()[fragment].string(),
matcher);
}
@Test
public void testEnsureNoNegativeOffsets() throws Exception {
try {