1313import org .apache .lucene .index .LeafReaderContext ;
1414import org .apache .lucene .store .Directory ;
1515import org .apache .lucene .tests .index .RandomIndexWriter ;
16+ import org .apache .lucene .util .BytesRef ;
1617import org .elasticsearch .common .bytes .BytesReference ;
1718import org .elasticsearch .index .IndexSettings ;
1819import org .elasticsearch .index .fieldvisitor .StoredFieldLoader ;
2122import org .elasticsearch .search .lookup .SearchLookup ;
2223import org .elasticsearch .xcontent .XContentBuilder ;
2324import org .elasticsearch .xcontent .XContentType ;
24- import org .junit .Assert ;
25+ import org .hamcrest .BaseMatcher ;
26+ import org .hamcrest .Description ;
27+ import org .hamcrest .Matcher ;
2528
2629import java .io .IOException ;
30+ import java .lang .reflect .Array ;
31+ import java .util .ArrayList ;
32+ import java .util .List ;
2733import java .util .Map ;
2834import java .util .Set ;
2935
3036import static org .apache .lucene .tests .util .LuceneTestCase .newDirectory ;
3137import static org .apache .lucene .tests .util .LuceneTestCase .random ;
38+ import static org .elasticsearch .index .mapper .BlockLoaderTestRunner .PrettyEqual .prettyEqualTo ;
3239import static org .hamcrest .MatcherAssert .assertThat ;
3340import static org .hamcrest .Matchers .equalTo ;
3441
@@ -44,7 +51,7 @@ public void runTest(MapperService mapperService, Map<String, Object> document, O
4451 var documentXContent = XContentBuilder .builder (XContentType .JSON .xContent ()).map (document );
4552
4653 Object blockLoaderResult = setupAndInvokeBlockLoader (mapperService , documentXContent , blockLoaderFieldName );
47- Assert . assertEquals ( expected , blockLoaderResult );
54+ assertThat ( blockLoaderResult , prettyEqualTo ( expected ) );
4855 }
4956
5057 private Object setupAndInvokeBlockLoader (MapperService mapperService , XContentBuilder document , String fieldName ) throws IOException {
@@ -145,4 +152,86 @@ public FieldNamesFieldMapper.FieldNamesFieldType fieldNames() {
145152 }
146153 });
147154 }
155+
156+ // Copied from org.hamcrest.core.IsEqual and modified to pretty print failure when bytesref
157+ static class PrettyEqual <T > extends BaseMatcher <T > {
158+
159+ private final Object expectedValue ;
160+
161+ PrettyEqual (T equalArg ) {
162+ expectedValue = equalArg ;
163+ }
164+
165+ @ Override
166+ public boolean matches (Object actualValue ) {
167+ return areEqual (actualValue , expectedValue );
168+ }
169+
170+ @ Override
171+ public void describeTo (Description description ) {
172+ description .appendValue (attemptMakeReadable (expectedValue ));
173+ }
174+
175+ @ Override
176+ public void describeMismatch (Object item , Description description ) {
177+ super .describeMismatch (attemptMakeReadable (item ), description );
178+ }
179+
180+ private static boolean areEqual (Object actual , Object expected ) {
181+ if (actual == null ) {
182+ return expected == null ;
183+ }
184+
185+ if (expected != null && isArray (actual )) {
186+ return isArray (expected ) && areArraysEqual (actual , expected );
187+ }
188+
189+ return actual .equals (expected );
190+ }
191+
192+ private static boolean areArraysEqual (Object actualArray , Object expectedArray ) {
193+ return areArrayLengthsEqual (actualArray , expectedArray ) && areArrayElementsEqual (actualArray , expectedArray );
194+ }
195+
196+ private static boolean areArrayLengthsEqual (Object actualArray , Object expectedArray ) {
197+ return Array .getLength (actualArray ) == Array .getLength (expectedArray );
198+ }
199+
200+ private static boolean areArrayElementsEqual (Object actualArray , Object expectedArray ) {
201+ for (int i = 0 ; i < Array .getLength (actualArray ); i ++) {
202+ if (areEqual (Array .get (actualArray , i ), Array .get (expectedArray , i )) == false ) {
203+ return false ;
204+ }
205+ }
206+ return true ;
207+ }
208+
209+ private static boolean isArray (Object o ) {
210+ return o .getClass ().isArray ();
211+ }
212+
213+ // Attempt to make assertions readable:
214+ static Object attemptMakeReadable (Object expected ) {
215+ try {
216+ if (expected instanceof BytesRef bytesRef ) {
217+ expected = bytesRef .utf8ToString ();
218+ } else if (expected instanceof List <?> list && list .getFirst () instanceof BytesRef ) {
219+ List <String > expectedList = new ArrayList <>(list .size ());
220+ for (Object e : list ) {
221+ expectedList .add (((BytesRef ) e ).utf8ToString ());
222+ }
223+ expected = expectedList ;
224+ }
225+ return expected ;
226+ } catch (Exception | AssertionError e ) {
227+ // ip/geo fields can't be converted to strings:
228+ return expected ;
229+ }
230+ }
231+
232+ public static <T > Matcher <T > prettyEqualTo (T operand ) {
233+ return new PrettyEqual <>(operand );
234+ }
235+
236+ }
148237}
0 commit comments