From 2fd4bece16d10e8254cc13e51e63112b85533bac Mon Sep 17 00:00:00 2001 From: Riley Park Date: Wed, 12 May 2021 15:52:03 -0700 Subject: [PATCH] api: Add contains method that allows alternative methods of equality comparison fixes #363 --- .../net/kyori/adventure/text/Component.java | 37 +++++++++++++++++-- .../adventure/text/TextComponentTest.java | 12 ++++++ 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/api/src/main/java/net/kyori/adventure/text/Component.java b/api/src/main/java/net/kyori/adventure/text/Component.java index 8c85c3c895..0f74189cd1 100644 --- a/api/src/main/java/net/kyori/adventure/text/Component.java +++ b/api/src/main/java/net/kyori/adventure/text/Component.java @@ -28,7 +28,9 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; +import java.util.function.BiPredicate; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.UnaryOperator; @@ -93,6 +95,19 @@ */ @ApiStatus.NonExtendable public interface Component extends ComponentBuilderApplicable, ComponentLike, Examinable, HoverEventSource { + /** + * A predicate that checks equality of two {@code Component}s using {@link Objects#equals(Object, Object)}. + * + * @since 4.8.0 + */ + BiPredicate EQUALS = Objects::equals; + /** + * A predicate that checks equality of two {@code Component}s. + * + * @since 4.8.0 + */ + BiPredicate EQUALS_IDENTITY = (a, b) -> a == b; + /** * Gets an empty component. * @@ -1270,15 +1285,31 @@ static TranslatableComponent translatable(final @NonNull String key, final @Null /** * Checks if this component contains a component. * + *

This method uses identity comparison when checking for contains. Use {@link #contains(Component, BiPredicate)} with {@link #EQUALS} if you + * wish to use full equality comparison.

+ * * @param that the other component * @return {@code true} if this component contains the provided * component, {@code false} otherwise * @since 4.0.0 */ default boolean contains(final @NonNull Component that) { - if(this == that) return true; + return this.contains(that, EQUALS_IDENTITY); + } + + /** + * Checks if this component contains a component. + * + * @param that the other component + * @param equals the equality tester + * @return {@code true} if this component contains the provided + * component, {@code false} otherwise + * @since 4.8.0 + */ + default boolean contains(final @NonNull Component that, final @NonNull BiPredicate equals) { + if(equals.test(this, that)) return true; for(final Component child : this.children()) { - if(child.contains(that)) return true; + if(child.contains(that, equals)) return true; } final @Nullable HoverEvent hoverEvent = this.hoverEvent(); if(hoverEvent != null) { @@ -1286,7 +1317,7 @@ default boolean contains(final @NonNull Component that) { final Component hover = (Component) hoverEvent.value(); if(that == hover) return true; for(final Component child : hover.children()) { - if(child.contains(that)) return true; + if(child.contains(that, equals)) return true; } } } diff --git a/api/src/test/java/net/kyori/adventure/text/TextComponentTest.java b/api/src/test/java/net/kyori/adventure/text/TextComponentTest.java index 5abe6724d5..1421731c74 100644 --- a/api/src/test/java/net/kyori/adventure/text/TextComponentTest.java +++ b/api/src/test/java/net/kyori/adventure/text/TextComponentTest.java @@ -142,6 +142,18 @@ void testContains() { assertTrue(component.contains(child)); } + // https://github.com/KyoriPowered/adventure/issues/363 + @Test + void testContainsEquality() { + final Component c0 = Component.text("best!"); + final Component c1 = Component.text() + .append(Component.text("Nero ")) + .append(Component.text(" are the ").append(c0)) + .build(); + + assertTrue(c1.contains(Component.text("best!"), Component.EQUALS)); + } + @Test void testContent() { final TextComponent c0 = Component.text("foo");