From 94367eb84d89ef5c6263e43130cd1690ecb75d4e Mon Sep 17 00:00:00 2001 From: zml Date: Mon, 13 Mar 2023 22:23:29 -0700 Subject: [PATCH] feat(minimessage): use virtual components to preserve rainbow/gradient tags --- .../minimessage/MiniMessageSerializer.java | 12 +- .../internal/serializer/Emitable.java | 14 + .../standard/AbstractColorChangingTag.java | 92 ++- .../minimessage/tag/standard/GradientTag.java | 42 +- .../minimessage/tag/standard/RainbowTag.java | 21 +- .../text/minimessage/AbstractTest.java | 6 + .../tag/standard/GradientTagTest.java | 731 +++++++++--------- .../tag/standard/RainbowTagTest.java | 439 ++++++----- .../tag/standard/ResetTagTest.java | 17 +- 9 files changed, 798 insertions(+), 576 deletions(-) diff --git a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/MiniMessageSerializer.java b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/MiniMessageSerializer.java index 0d082fbdd..d30032616 100644 --- a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/MiniMessageSerializer.java +++ b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/MiniMessageSerializer.java @@ -68,10 +68,13 @@ private MiniMessageSerializer() { private static void visit(final @NotNull Component component, final Collector emitter, final SerializableResolver resolver, final boolean lastChild) { // visit self resolver.handle(component, emitter); - emitter.flushClaims(component); + Component childSource = emitter.flushClaims(component); + if (childSource == null) { + childSource = component; + } // then children - for (final Iterator it = component.children().iterator(); it.hasNext();) { + for (final Iterator it = childSource.children().iterator(); it.hasNext();) { emitter.mark(); visit(it.next(), emitter, resolver, lastChild && !it.hasNext()); } @@ -336,9 +339,11 @@ public boolean styleClaimed(final @NotNull String claimId) { return this.claimedStyleElements.contains(claimId); } - void flushClaims(final Component component) { + @Nullable Component flushClaims(final Component component) { // return: a substitute to provide children + Component ret = null; if (this.componentClaim != null) { this.componentClaim.emit(this); + ret = this.componentClaim.substitute(); this.componentClaim = null; } else if (component instanceof TextComponent) { this.text(((TextComponent) component).content()); @@ -347,6 +352,7 @@ void flushClaims(final Component component) { throw new IllegalStateException("Unclaimed component " + component); } this.claimedStyleElements.clear(); + return ret; } } diff --git a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/internal/serializer/Emitable.java b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/internal/serializer/Emitable.java index 0f5fc52fd..8d5a02f3d 100644 --- a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/internal/serializer/Emitable.java +++ b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/internal/serializer/Emitable.java @@ -23,7 +23,9 @@ */ package net.kyori.adventure.text.minimessage.internal.serializer; +import net.kyori.adventure.text.Component; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * Something that holds data representable as MiniMessage tags. @@ -39,4 +41,16 @@ public interface Emitable { * @since 4.10.0 */ void emit(final @NotNull TokenEmitter emitter); + + /** + * Provide a substitute for this component's actual children. + * + *

This allows modifying tags to output original data while still transforming the created components.

+ * + * @return a potential substitute + * @since 4.13.0 + */ + default @Nullable Component substitute() { // TODO: maybe make this be only for component claims? + return null; + } } diff --git a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/standard/AbstractColorChangingTag.java b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/standard/AbstractColorChangingTag.java index 4ca786794..ffc6ff155 100644 --- a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/standard/AbstractColorChangingTag.java +++ b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/standard/AbstractColorChangingTag.java @@ -25,14 +25,19 @@ import java.util.Collections; import java.util.PrimitiveIterator; +import java.util.function.Consumer; import java.util.stream.Stream; import net.kyori.adventure.internal.Internals; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextComponent; +import net.kyori.adventure.text.VirtualComponent; +import net.kyori.adventure.text.VirtualComponentHolder; import net.kyori.adventure.text.flattener.ComponentFlattener; import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.minimessage.internal.parser.node.TagNode; import net.kyori.adventure.text.minimessage.internal.parser.node.ValueNode; +import net.kyori.adventure.text.minimessage.internal.serializer.Emitable; +import net.kyori.adventure.text.minimessage.internal.serializer.TokenEmitter; import net.kyori.adventure.text.minimessage.tag.Inserting; import net.kyori.adventure.text.minimessage.tag.Modifying; import net.kyori.adventure.text.minimessage.tree.Node; @@ -95,6 +100,11 @@ public final void postVisit() { @Override public final Component apply(final @NotNull Component current, final int depth) { + if (depth == 0) { + // capture state into a virtual component, no other logic is needed in normal MM handling + return Component.virtual(new TagInfoHolder(new ComponentData(this.preserveData(), current))); + } + if ((this.disableApplyingColorDepth != -1 && depth > this.disableApplyingColorDepth) || current.style().color() != null) { if (this.disableApplyingColorDepth == -1 || depth < this.disableApplyingColorDepth) { this.disableApplyingColorDepth = depth; @@ -102,18 +112,19 @@ public final Component apply(final @NotNull Component current, final int depth) // This component has its own color applied, which overrides ours // We still want to keep track of where we are though if this is text if (current instanceof TextComponent) { - final String content = ((TextComponent) current).content(); - final int len = content.codePointCount(0, content.length()); - for (int i = 0; i < len; i++) { - // increment our color index - this.advanceColor(); - } + this.skipColorForLengthOf(((TextComponent) current).content()); } return current.children(Collections.emptyList()); } this.disableApplyingColorDepth = -1; - if (current instanceof TextComponent && ((TextComponent) current).content().length() > 0) { + if (current instanceof VirtualComponent) { + // this component has its own information, so we can't rainbowify direct content -- we can process children tho + // basically treat as if it's a non-text component + this.skipColorForLengthOf(((VirtualComponent) current).content()); + + return current.children(Collections.emptyList()); + } else if (current instanceof TextComponent && ((TextComponent) current).content().length() > 0) { final TextComponent textComponent = (TextComponent) current; final String content = textComponent.content(); @@ -138,6 +149,14 @@ public final Component apply(final @NotNull Component current, final int depth) return Component.empty().mergeStyle(current); } + private void skipColorForLengthOf(final String content) { + final int len = content.codePointCount(0, content.length()); + for (int i = 0; i < len; i++) { + // increment our color index + this.advanceColor(); + } + } + // The lifecycle protected abstract void init(); @@ -155,6 +174,14 @@ public final Component apply(final @NotNull Component current, final int depth) */ protected abstract TextColor color(); + /** + * Return an emitable that will accurately reserialize the provided input data. + * + * @return the emitable for this tag + * @since 4.13.0 + */ + protected abstract @NotNull Consumer preserveData(); + // misc @Override @@ -170,4 +197,55 @@ public final Component apply(final @NotNull Component current, final int depth) @Override public abstract int hashCode(); + + static final class ComponentData implements Emitable { + final Consumer output; + final Component originalComp; + + ComponentData(final Consumer output, final Component originalComp) { + this.output = output; + this.originalComp = originalComp; + } + + @Override + public void emit(final @NotNull TokenEmitter emitter) { + this.output.accept(emitter); + } + + @Override + public Component substitute() { + return this.originalComp; + } + } + + static final class TagInfoHolder implements VirtualComponentHolder { + private final ComponentData data; + + TagInfoHolder(final ComponentData data) { + this.data = data; + } + + @Override + public @NotNull ComponentData unbox() { + return this.data; + } + + @Override + public @NotNull String fallbackString() { + return ""; // only holds data for reserialization, not for display + } + } + + static @Nullable Emitable claimComponent(final Component comp) { + if (!(comp instanceof VirtualComponent)) { + return null; + } + + final VirtualComponentHolder holder = ((VirtualComponent) comp).holder(); + if (!(holder instanceof TagInfoHolder)) { + return null; + } + + return ((TagInfoHolder) holder).unbox(); + } } diff --git a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/standard/GradientTag.java b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/standard/GradientTag.java index 04ab305b9..044461179 100644 --- a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/standard/GradientTag.java +++ b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/standard/GradientTag.java @@ -29,9 +29,13 @@ import java.util.List; import java.util.Objects; import java.util.OptionalDouble; +import java.util.function.Consumer; import java.util.stream.Stream; +import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.minimessage.Context; +import net.kyori.adventure.text.minimessage.internal.serializer.SerializableResolver; +import net.kyori.adventure.text.minimessage.internal.serializer.TokenEmitter; import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.resolver.ArgumentQueue; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; @@ -47,8 +51,10 @@ */ final class GradientTag extends AbstractColorChangingTag { private static final String GRADIENT = "gradient"; + private static final TextColor DEFAULT_WHITE = TextColor.color(0xffffff); + private static final TextColor DEFAULT_BLACK = TextColor.color(0x000000); - static final TagResolver RESOLVER = TagResolver.resolver(GRADIENT, GradientTag::create); + static final TagResolver RESOLVER = SerializableResolver.claimingComponent(GRADIENT, GradientTag::create, AbstractColorChangingTag::claimComponent); private int index = 0; private int colorIndex = 0; @@ -102,7 +108,7 @@ private GradientTag(final float phase, final List colors) { } if (colors.isEmpty()) { - this.colors = new TextColor[]{TextColor.color(0xffffff), TextColor.color(0x000000)}; + this.colors = new TextColor[]{DEFAULT_WHITE, DEFAULT_BLACK}; } else { this.colors = colors.toArray(new TextColor[0]); } @@ -145,6 +151,38 @@ protected TextColor color() { } } + @Override + protected @NotNull Consumer preserveData() { + final TextColor[] colors; + final float phase; + + if (this.negativePhase) { + colors = Arrays.copyOf(this.colors, this.colors.length); + Collections.reverse(Arrays.asList(colors)); + phase = this.phase - 1; + } else { + colors = this.colors; + phase = this.phase; + } + + return emit -> { + emit.tag(GRADIENT); + if (colors.length != 2 || !colors[0].equals(DEFAULT_WHITE) || !colors[1].equals(DEFAULT_BLACK)) { // non-default params + for (final TextColor color : colors) { + if (color instanceof NamedTextColor) { + emit.argument(NamedTextColor.NAMES.keyOrThrow((NamedTextColor) color)); + } else { + emit.argument(color.asHexString()); + } + } + } + + if (phase != 0) { + emit.argument(Float.toString(phase)); + } + }; + } + @Override public @NotNull Stream examinableProperties() { return Stream.of( diff --git a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/standard/RainbowTag.java b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/standard/RainbowTag.java index 6abd32ff9..4a3c32070 100644 --- a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/standard/RainbowTag.java +++ b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/standard/RainbowTag.java @@ -24,9 +24,12 @@ package net.kyori.adventure.text.minimessage.tag.standard; import java.util.Objects; +import java.util.function.Consumer; import java.util.stream.Stream; import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.minimessage.Context; +import net.kyori.adventure.text.minimessage.internal.serializer.SerializableResolver; +import net.kyori.adventure.text.minimessage.internal.serializer.TokenEmitter; import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.resolver.ArgumentQueue; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; @@ -44,7 +47,7 @@ final class RainbowTag extends AbstractColorChangingTag { private static final String REVERSE = "!"; private static final String RAINBOW = "rainbow"; - static final TagResolver RESOLVER = TagResolver.resolver(RAINBOW, RainbowTag::create); + static final TagResolver RESOLVER = SerializableResolver.claimingComponent(RAINBOW, RainbowTag::create, AbstractColorChangingTag::claimComponent); private final boolean reversed; private final int phase; @@ -105,6 +108,22 @@ protected TextColor color() { return TextColor.color(HSVLike.hsvLike(hue, 1f, 1f)); } + @Override + protected @NotNull Consumer preserveData() { + final boolean reversed = this.reversed; + final int phase = this.phase; + return emit -> { + emit.tag(RAINBOW); + if (reversed && phase != 0) { + emit.argument(REVERSE + phase); + } else if (reversed) { + emit.argument(REVERSE); + } else if (phase != 0) { + emit.argument(Integer.toString(phase)); + } + }; + } + @Override public @NotNull Stream examinableProperties() { return Stream.of(ExaminableProperty.of("phase", this.phase)); diff --git a/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/AbstractTest.java b/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/AbstractTest.java index 9709d165c..c4a03271f 100644 --- a/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/AbstractTest.java +++ b/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/AbstractTest.java @@ -23,6 +23,7 @@ */ package net.kyori.adventure.text.minimessage; +import java.util.Arrays; import java.util.Collections; import java.util.function.UnaryOperator; import java.util.stream.Collectors; @@ -75,4 +76,9 @@ public static Context dummyContext(final String originalMessage) { public static ArgumentQueue emptyArgumentQueue(final Context context) { return new ArgumentQueueImpl<>(context, Collections.emptyList()); } + + public static Component virtualOfChildren(final ComponentLike... children) { + return Component.virtual(() -> "") // not part of equality... should it be? + .children(Arrays.asList(children)); + } } diff --git a/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/standard/GradientTagTest.java b/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/standard/GradientTagTest.java index cd2601d41..464416bf0 100644 --- a/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/standard/GradientTagTest.java +++ b/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/standard/GradientTagTest.java @@ -32,6 +32,7 @@ import static net.kyori.adventure.text.Component.empty; import static net.kyori.adventure.text.Component.text; +import static net.kyori.adventure.text.Component.textOfChildren; import static net.kyori.adventure.text.Component.translatable; import static net.kyori.adventure.text.event.HoverEvent.showText; import static net.kyori.adventure.text.format.NamedTextColor.BLACK; @@ -54,32 +55,32 @@ void testGradient() { final String input = "Woo: ||||||||||||||||||||||||!"; final Component expected = empty().color(YELLOW) .append(text("Woo: ")) - .append(empty() - .append(text("|", WHITE)) - .append(text("|", color(0xf4f4f4))) - .append(text("|", color(0xeaeaea))) - .append(text("|", color(0xdfdfdf))) - .append(text("|", color(0xd5d5d5))) - .append(text("|", color(0xcacaca))) - .append(text("|", color(0xbfbfbf))) - .append(text("|", color(0xb5b5b5))) - .append(text("|", GRAY)) - .append(text("|", color(0x9f9f9f))) - .append(text("|", color(0x959595))) - .append(text("|", color(0x8a8a8a))) - .append(text("|", color(0x808080))) - .append(text("|", color(0x757575))) - .append(text("|", color(0x6a6a6a))) - .append(text("|", color(0x606060))) - .append(text("|", DARK_GRAY)) - .append(text("|", color(0x4a4a4a))) - .append(text("|", color(0x404040))) - .append(text("|", color(0x353535))) - .append(text("|", color(0x2a2a2a))) - .append(text("|", color(0x202020))) - .append(text("|", color(0x151515))) - .append(text("|", color(0x0b0b0b))) - ).append(text("!")); + .append(virtualOfChildren(textOfChildren( + text("|", WHITE), + text("|", color(0xf4f4f4)), + text("|", color(0xeaeaea)), + text("|", color(0xdfdfdf)), + text("|", color(0xd5d5d5)), + text("|", color(0xcacaca)), + text("|", color(0xbfbfbf)), + text("|", color(0xb5b5b5)), + text("|", GRAY), + text("|", color(0x9f9f9f)), + text("|", color(0x959595)), + text("|", color(0x8a8a8a)), + text("|", color(0x808080)), + text("|", color(0x757575)), + text("|", color(0x6a6a6a)), + text("|", color(0x606060)), + text("|", DARK_GRAY), + text("|", color(0x4a4a4a)), + text("|", color(0x404040)), + text("|", color(0x353535)), + text("|", color(0x2a2a2a)), + text("|", color(0x202020)), + text("|", color(0x151515)), + text("|", color(0x0b0b0b)) + ))).append(text("!")); this.assertParsedEquals(expected, input); } @@ -90,32 +91,32 @@ void testGradientWithHover() { final Component expected = empty().color(YELLOW) .append(text("Woo: ")) .append(empty().hoverEvent(showText(text("This is a test"))) - .append(empty() - .append(text("|", style(WHITE))) - .append(text("|", style(color(0xf4f4f4)))) - .append(text("|", style(color(0xeaeaea)))) - .append(text("|", style(color(0xdfdfdf)))) - .append(text("|", style(color(0xd5d5d5)))) - .append(text("|", style(color(0xcacaca)))) - .append(text("|", style(color(0xbfbfbf)))) - .append(text("|", style(color(0xb5b5b5)))) - .append(text("|", style(GRAY))) - .append(text("|", style(color(0x9f9f9f)))) - .append(text("|", style(color(0x959595)))) - .append(text("|", style(color(0x8a8a8a)))) - .append(text("|", style(color(0x808080)))) - .append(text("|", style(color(0x757575)))) - .append(text("|", style(color(0x6a6a6a)))) - .append(text("|", style(color(0x606060)))) - .append(text("|", style(DARK_GRAY))) - .append(text("|", style(color(0x4a4a4a)))) - .append(text("|", style(color(0x404040)))) - .append(text("|", style(color(0x353535)))) - .append(text("|", style(color(0x2a2a2a)))) - .append(text("|", style(color(0x202020)))) - .append(text("|", style(color(0x151515)))) - .append(text("|", style(color(0x0b0b0b)))) - ).append(text("!"))); + .append(virtualOfChildren(textOfChildren( + text("|", style(WHITE)), + text("|", style(color(0xf4f4f4))), + text("|", style(color(0xeaeaea))), + text("|", style(color(0xdfdfdf))), + text("|", style(color(0xd5d5d5))), + text("|", style(color(0xcacaca))), + text("|", style(color(0xbfbfbf))), + text("|", style(color(0xb5b5b5))), + text("|", style(GRAY)), + text("|", style(color(0x9f9f9f))), + text("|", style(color(0x959595))), + text("|", style(color(0x8a8a8a))), + text("|", style(color(0x808080))), + text("|", style(color(0x757575))), + text("|", style(color(0x6a6a6a))), + text("|", style(color(0x606060))), + text("|", style(DARK_GRAY)), + text("|", style(color(0x4a4a4a))), + text("|", style(color(0x404040))), + text("|", style(color(0x353535))), + text("|", style(color(0x2a2a2a))), + text("|", style(color(0x202020))), + text("|", style(color(0x151515))), + text("|", style(color(0x0b0b0b))) + ))).append(text("!"))); this.assertParsedEquals(expected, input); } @@ -125,32 +126,32 @@ void testGradient2() { final String input = "Woo: ||||||||||||||||||||||||!"; final Component expected = empty().color(YELLOW) .append(text("Woo: ")) - .append(empty() - .append(text("|", color(0x5e4fa2))) - .append(text("|", color(0x64529f))) - .append(text("|", color(0x6b559c))) - .append(text("|", color(0x715899))) - .append(text("|", color(0x785b96))) - .append(text("|", color(0x7e5d93))) - .append(text("|", color(0x846090))) - .append(text("|", color(0x8b638d))) - .append(text("|", color(0x91668a))) - .append(text("|", color(0x976987))) - .append(text("|", color(0x9e6c84))) - .append(text("|", color(0xa46f81))) - .append(text("|", color(0xab727e))) - .append(text("|", color(0xb1747a))) - .append(text("|", color(0xb77777))) - .append(text("|", color(0xbe7a74))) - .append(text("|", color(0xc47d71))) - .append(text("|", color(0xca806e))) - .append(text("|", color(0xd1836b))) - .append(text("|", color(0xd78668))) - .append(text("|", color(0xde8965))) - .append(text("|", color(0xe48b62))) - .append(text("|", color(0xea8e5f))) - .append(text("|", color(0xf1915c))) - ) + .append(virtualOfChildren(textOfChildren( + text("|", color(0x5e4fa2)), + text("|", color(0x64529f)), + text("|", color(0x6b559c)), + text("|", color(0x715899)), + text("|", color(0x785b96)), + text("|", color(0x7e5d93)), + text("|", color(0x846090)), + text("|", color(0x8b638d)), + text("|", color(0x91668a)), + text("|", color(0x976987)), + text("|", color(0x9e6c84)), + text("|", color(0xa46f81)), + text("|", color(0xab727e)), + text("|", color(0xb1747a)), + text("|", color(0xb77777)), + text("|", color(0xbe7a74)), + text("|", color(0xc47d71)), + text("|", color(0xca806e)), + text("|", color(0xd1836b)), + text("|", color(0xd78668)), + text("|", color(0xde8965)), + text("|", color(0xe48b62)), + text("|", color(0xea8e5f)), + text("|", color(0xf1915c)) + ))) .append(text("!")); this.assertParsedEquals(expected, input); @@ -161,32 +162,32 @@ void testGradient3() { final String input = "Woo: ||||||||||||||||||||||||!"; final Component expected = empty().color(YELLOW) .append(text("Woo: ")) - .append(empty() - .append(text("|", GREEN)) - .append(text("|", color(0x55f85c))) - .append(text("|", color(0x55f163))) - .append(text("|", color(0x55ea6a))) - .append(text("|", color(0x55e371))) - .append(text("|", color(0x55dc78))) - .append(text("|", color(0x55d580))) - .append(text("|", color(0x55cd87))) - .append(text("|", color(0x55c68e))) - .append(text("|", color(0x55bf95))) - .append(text("|", color(0x55b89c))) - .append(text("|", color(0x55b1a3))) - .append(text("|", color(0x55aaaa))) - .append(text("|", color(0x55a3b1))) - .append(text("|", color(0x559cb8))) - .append(text("|", color(0x5595bf))) - .append(text("|", color(0x558ec6))) - .append(text("|", color(0x5587cd))) - .append(text("|", color(0x5580d5))) - .append(text("|", color(0x5578dc))) - .append(text("|", color(0x5571e3))) - .append(text("|", color(0x556aea))) - .append(text("|", color(0x5563f1))) - .append(text("|", color(0x555cf8))) - ).append(text("!")); + .append(virtualOfChildren(textOfChildren( + text("|", GREEN), + text("|", color(0x55f85c)), + text("|", color(0x55f163)), + text("|", color(0x55ea6a)), + text("|", color(0x55e371)), + text("|", color(0x55dc78)), + text("|", color(0x55d580)), + text("|", color(0x55cd87)), + text("|", color(0x55c68e)), + text("|", color(0x55bf95)), + text("|", color(0x55b89c)), + text("|", color(0x55b1a3)), + text("|", color(0x55aaaa)), + text("|", color(0x55a3b1)), + text("|", color(0x559cb8)), + text("|", color(0x5595bf)), + text("|", color(0x558ec6)), + text("|", color(0x5587cd)), + text("|", color(0x5580d5)), + text("|", color(0x5578dc)), + text("|", color(0x5571e3)), + text("|", color(0x556aea)), + text("|", color(0x5563f1)), + text("|", color(0x555cf8)) + ))).append(text("!")); this.assertParsedEquals(expected, input); } @@ -196,62 +197,62 @@ void testGradientMultiColor() { final String input = "Woo: ||||||||||||||||||||||||||||||||||||||||||||||||||||||!"; final Component expected = empty().color(YELLOW) .append(text("Woo: ")) - .append(empty() - .append(text("|", RED)) - .append(text("|", color(0xf25562))) - .append(text("|", color(0xe5556f))) - .append(text("|", color(0xd8557c))) - .append(text("|", color(0xcb5589))) - .append(text("|", color(0xbe5596))) - .append(text("|", color(0xb155a3))) - .append(text("|", color(0xa355b1))) - .append(text("|", color(0x9655be))) - .append(text("|", color(0x8955cb))) - .append(text("|", color(0x7c55d8))) - .append(text("|", color(0x6f55e5))) - .append(text("|", color(0x6255f2))) - .append(text("|", BLUE)) - .append(text("|", BLUE)) - .append(text("|", color(0x5562f2))) - .append(text("|", color(0x556fe5))) - .append(text("|", color(0x557cd8))) - .append(text("|", color(0x5589cb))) - .append(text("|", color(0x5596be))) - .append(text("|", color(0x55a3b1))) - .append(text("|", color(0x55b1a3))) - .append(text("|", color(0x55be96))) - .append(text("|", color(0x55cb89))) - .append(text("|", color(0x55d87c))) - .append(text("|", color(0x55e56f))) - .append(text("|", color(0x55f262))) - .append(text("|", GREEN)) - .append(text("|", GREEN)) - .append(text("|", color(0x62ff55))) - .append(text("|", color(0x6fff55))) - .append(text("|", color(0x7cff55))) - .append(text("|", color(0x89ff55))) - .append(text("|", color(0x96ff55))) - .append(text("|", color(0xa3ff55))) - .append(text("|", color(0xb1ff55))) - .append(text("|", color(0xbeff55))) - .append(text("|", color(0xcbff55))) - .append(text("|", color(0xd8ff55))) - .append(text("|", color(0xe5ff55))) - .append(text("|", color(0xf2ff55))) - .append(text("|", YELLOW)) - .append(text("|", YELLOW)) - .append(text("|", color(0xfff255))) - .append(text("|", color(0xffe555))) - .append(text("|", color(0xffd855))) - .append(text("|", color(0xffcb55))) - .append(text("|", color(0xffbe55))) - .append(text("|", color(0xffb155))) - .append(text("|", color(0xffa355))) - .append(text("|", color(0xff9655))) - .append(text("|", color(0xff8955))) - .append(text("|", color(0xff7c55))) - .append(text("|", color(0xff6f55))) - ).append(text("!")); + .append(virtualOfChildren(textOfChildren( + text("|", RED), + text("|", color(0xf25562)), + text("|", color(0xe5556f)), + text("|", color(0xd8557c)), + text("|", color(0xcb5589)), + text("|", color(0xbe5596)), + text("|", color(0xb155a3)), + text("|", color(0xa355b1)), + text("|", color(0x9655be)), + text("|", color(0x8955cb)), + text("|", color(0x7c55d8)), + text("|", color(0x6f55e5)), + text("|", color(0x6255f2)), + text("|", BLUE), + text("|", BLUE), + text("|", color(0x5562f2)), + text("|", color(0x556fe5)), + text("|", color(0x557cd8)), + text("|", color(0x5589cb)), + text("|", color(0x5596be)), + text("|", color(0x55a3b1)), + text("|", color(0x55b1a3)), + text("|", color(0x55be96)), + text("|", color(0x55cb89)), + text("|", color(0x55d87c)), + text("|", color(0x55e56f)), + text("|", color(0x55f262)), + text("|", GREEN), + text("|", GREEN), + text("|", color(0x62ff55)), + text("|", color(0x6fff55)), + text("|", color(0x7cff55)), + text("|", color(0x89ff55)), + text("|", color(0x96ff55)), + text("|", color(0xa3ff55)), + text("|", color(0xb1ff55)), + text("|", color(0xbeff55)), + text("|", color(0xcbff55)), + text("|", color(0xd8ff55)), + text("|", color(0xe5ff55)), + text("|", color(0xf2ff55)), + text("|", YELLOW), + text("|", YELLOW), + text("|", color(0xfff255)), + text("|", color(0xffe555)), + text("|", color(0xffd855)), + text("|", color(0xffcb55)), + text("|", color(0xffbe55)), + text("|", color(0xffb155)), + text("|", color(0xffa355)), + text("|", color(0xff9655)), + text("|", color(0xff8955)), + text("|", color(0xff7c55)), + text("|", color(0xff6f55)) + ))).append(text("!")); this.assertParsedEquals(expected, input); } @@ -261,62 +262,62 @@ void testGradientMultiColor2() { final String input = "Woo: ||||||||||||||||||||||||||||||||||||||||||||||||||||||!"; final Component expected = empty().color(YELLOW) .append(text("Woo: ")) - .append(empty() - .append(text("|", BLACK)) - .append(text("|", color(0x90909))) - .append(text("|", color(0x131313))) - .append(text("|", color(0x1c1c1c))) - .append(text("|", color(0x262626))) - .append(text("|", color(0x2f2f2f))) - .append(text("|", color(0x393939))) - .append(text("|", color(0x424242))) - .append(text("|", color(0x4c4c4c))) - .append(text("|", DARK_GRAY)) - .append(text("|", color(0x5e5e5e))) - .append(text("|", color(0x686868))) - .append(text("|", color(0x717171))) - .append(text("|", color(0x7b7b7b))) - .append(text("|", color(0x848484))) - .append(text("|", color(0x8e8e8e))) - .append(text("|", color(0x979797))) - .append(text("|", color(0xa1a1a1))) - .append(text("|", GRAY)) - .append(text("|", color(0xb3b3b3))) - .append(text("|", color(0xbdbdbd))) - .append(text("|", color(0xc6c6c6))) - .append(text("|", color(0xd0d0d0))) - .append(text("|", color(0xd9d9d9))) - .append(text("|", color(0xe3e3e3))) - .append(text("|", color(0xececec))) - .append(text("|", color(0xf6f6f6))) - .append(text("|", WHITE)) - .append(text("|", WHITE)) - .append(text("|", color(0xf6f6f6))) - .append(text("|", color(0xececec))) - .append(text("|", color(0xe3e3e3))) - .append(text("|", color(0xd9d9d9))) - .append(text("|", color(0xd0d0d0))) - .append(text("|", color(0xc6c6c6))) - .append(text("|", color(0xbdbdbd))) - .append(text("|", color(0xb3b3b3))) - .append(text("|", GRAY)) - .append(text("|", color(0xa1a1a1))) - .append(text("|", color(0x979797))) - .append(text("|", color(0x8e8e8e))) - .append(text("|", color(0x848484))) - .append(text("|", color(0x7b7b7b))) - .append(text("|", color(0x717171))) - .append(text("|", color(0x686868))) - .append(text("|", color(0x5e5e5e))) - .append(text("|", DARK_GRAY)) - .append(text("|", color(0x4c4c4c))) - .append(text("|", color(0x424242))) - .append(text("|", color(0x393939))) - .append(text("|", color(0x2f2f2f))) - .append(text("|", color(0x262626))) - .append(text("|", color(0x1c1c1c))) - .append(text("|", color(0x131313))) - ).append(text("!")); + .append(virtualOfChildren(textOfChildren( + text("|", BLACK), + text("|", color(0x90909)), + text("|", color(0x131313)), + text("|", color(0x1c1c1c)), + text("|", color(0x262626)), + text("|", color(0x2f2f2f)), + text("|", color(0x393939)), + text("|", color(0x424242)), + text("|", color(0x4c4c4c)), + text("|", DARK_GRAY), + text("|", color(0x5e5e5e)), + text("|", color(0x686868)), + text("|", color(0x717171)), + text("|", color(0x7b7b7b)), + text("|", color(0x848484)), + text("|", color(0x8e8e8e)), + text("|", color(0x979797)), + text("|", color(0xa1a1a1)), + text("|", GRAY), + text("|", color(0xb3b3b3)), + text("|", color(0xbdbdbd)), + text("|", color(0xc6c6c6)), + text("|", color(0xd0d0d0)), + text("|", color(0xd9d9d9)), + text("|", color(0xe3e3e3)), + text("|", color(0xececec)), + text("|", color(0xf6f6f6)), + text("|", WHITE), + text("|", WHITE), + text("|", color(0xf6f6f6)), + text("|", color(0xececec)), + text("|", color(0xe3e3e3)), + text("|", color(0xd9d9d9)), + text("|", color(0xd0d0d0)), + text("|", color(0xc6c6c6)), + text("|", color(0xbdbdbd)), + text("|", color(0xb3b3b3)), + text("|", GRAY), + text("|", color(0xa1a1a1)), + text("|", color(0x979797)), + text("|", color(0x8e8e8e)), + text("|", color(0x848484)), + text("|", color(0x7b7b7b)), + text("|", color(0x717171)), + text("|", color(0x686868)), + text("|", color(0x5e5e5e)), + text("|", DARK_GRAY), + text("|", color(0x4c4c4c)), + text("|", color(0x424242)), + text("|", color(0x393939)), + text("|", color(0x2f2f2f)), + text("|", color(0x262626)), + text("|", color(0x1c1c1c)), + text("|", color(0x131313)) + ))).append(text("!")); this.assertParsedEquals(expected, input); } @@ -326,62 +327,62 @@ void testGradientMultiColor2Phase() { final String input = "Woo: ||||||||||||||||||||||||||||||||||||||||||||||||||||||!"; final Component expected = empty().color(YELLOW) .append(text("Woo: ")) - .append(empty() - .append(text("|", color(0xa6a6a6))) - .append(text("|", color(0x9c9c9c))) - .append(text("|", color(0x939393))) - .append(text("|", color(0x898989))) - .append(text("|", color(0x808080))) - .append(text("|", color(0x777777))) - .append(text("|", color(0x6d6d6d))) - .append(text("|", color(0x646464))) - .append(text("|", color(0x5a5a5a))) - .append(text("|", color(0x515151))) - .append(text("|", color(0x474747))) - .append(text("|", color(0x3e3e3e))) - .append(text("|", color(0x343434))) - .append(text("|", color(0x2b2b2b))) - .append(text("|", color(0x222222))) - .append(text("|", color(0x181818))) - .append(text("|", color(0xf0f0f))) - .append(text("|", color(0x50505))) - .append(text("|", color(0x40404))) - .append(text("|", color(0xe0e0e))) - .append(text("|", color(0x171717))) - .append(text("|", color(0x212121))) - .append(text("|", color(0x2a2a2a))) - .append(text("|", color(0x333333))) - .append(text("|", color(0x3d3d3d))) - .append(text("|", color(0x464646))) - .append(text("|", color(0x505050))) - .append(text("|", color(0x595959))) - .append(text("|", color(0x595959))) - .append(text("|", color(0x636363))) - .append(text("|", color(0x6c6c6c))) - .append(text("|", color(0x767676))) - .append(text("|", color(0x7f7f7f))) - .append(text("|", color(0x888888))) - .append(text("|", color(0x929292))) - .append(text("|", color(0x9b9b9b))) - .append(text("|", color(0xa5a5a5))) - .append(text("|", color(0xaeaeae))) - .append(text("|", color(0xb8b8b8))) - .append(text("|", color(0xc1c1c1))) - .append(text("|", color(0xcbcbcb))) - .append(text("|", color(0xd4d4d4))) - .append(text("|", color(0xdddddd))) - .append(text("|", color(0xe7e7e7))) - .append(text("|", color(0xf0f0f0))) - .append(text("|", color(0xfafafa))) - .append(text("|", color(0xfbfbfb))) - .append(text("|", color(0xf1f1f1))) - .append(text("|", color(0xe8e8e8))) - .append(text("|", color(0xdedede))) - .append(text("|", color(0xd5d5d5))) - .append(text("|", color(0xcccccc))) - .append(text("|", color(0xc2c2c2))) - .append(text("|", color(0xb9b9b9))) - ).append(text("!")); + .append(virtualOfChildren(textOfChildren( + text("|", color(0xa6a6a6)), + text("|", color(0x9c9c9c)), + text("|", color(0x939393)), + text("|", color(0x898989)), + text("|", color(0x808080)), + text("|", color(0x777777)), + text("|", color(0x6d6d6d)), + text("|", color(0x646464)), + text("|", color(0x5a5a5a)), + text("|", color(0x515151)), + text("|", color(0x474747)), + text("|", color(0x3e3e3e)), + text("|", color(0x343434)), + text("|", color(0x2b2b2b)), + text("|", color(0x222222)), + text("|", color(0x181818)), + text("|", color(0xf0f0f)), + text("|", color(0x50505)), + text("|", color(0x40404)), + text("|", color(0xe0e0e)), + text("|", color(0x171717)), + text("|", color(0x212121)), + text("|", color(0x2a2a2a)), + text("|", color(0x333333)), + text("|", color(0x3d3d3d)), + text("|", color(0x464646)), + text("|", color(0x505050)), + text("|", color(0x595959)), + text("|", color(0x595959)), + text("|", color(0x636363)), + text("|", color(0x6c6c6c)), + text("|", color(0x767676)), + text("|", color(0x7f7f7f)), + text("|", color(0x888888)), + text("|", color(0x929292)), + text("|", color(0x9b9b9b)), + text("|", color(0xa5a5a5)), + text("|", color(0xaeaeae)), + text("|", color(0xb8b8b8)), + text("|", color(0xc1c1c1)), + text("|", color(0xcbcbcb)), + text("|", color(0xd4d4d4)), + text("|", color(0xdddddd)), + text("|", color(0xe7e7e7)), + text("|", color(0xf0f0f0)), + text("|", color(0xfafafa)), + text("|", color(0xfbfbfb)), + text("|", color(0xf1f1f1)), + text("|", color(0xe8e8e8)), + text("|", color(0xdedede)), + text("|", color(0xd5d5d5)), + text("|", color(0xcccccc)), + text("|", color(0xc2c2c2)), + text("|", color(0xb9b9b9)) + ))).append(text("!")); this.assertParsedEquals(expected, input); } @@ -391,32 +392,32 @@ void testGradientPhase() { final String input = "Woo: ||||||||||||||||||||||||!"; final Component expected = empty().color(YELLOW) .append(text("Woo: ")) - .append(empty() - .append(text("|", color(0x5588cc))) - .append(text("|", color(0x5581d3))) - .append(text("|", color(0x557ada))) - .append(text("|", color(0x5573e1))) - .append(text("|", color(0x556ce8))) - .append(text("|", color(0x5565ef))) - .append(text("|", color(0x555ef7))) - .append(text("|", color(0x5556fe))) - .append(text("|", color(0x555bf9))) - .append(text("|", color(0x5562f2))) - .append(text("|", color(0x5569eb))) - .append(text("|", color(0x5570e4))) - .append(text("|", color(0x5577dd))) - .append(text("|", color(0x557ed6))) - .append(text("|", color(0x5585cf))) - .append(text("|", color(0x558cc8))) - .append(text("|", color(0x5593c1))) - .append(text("|", color(0x559aba))) - .append(text("|", color(0x55a2b3))) - .append(text("|", color(0x55a9ab))) - .append(text("|", color(0x55b0a4))) - .append(text("|", color(0x55b79d))) - .append(text("|", color(0x55be96))) - .append(text("|", color(0x55c58f))) - ).append(text("!")); + .append(virtualOfChildren(textOfChildren( + text("|", color(0x5588cc)), + text("|", color(0x5581d3)), + text("|", color(0x557ada)), + text("|", color(0x5573e1)), + text("|", color(0x556ce8)), + text("|", color(0x5565ef)), + text("|", color(0x555ef7)), + text("|", color(0x5556fe)), + text("|", color(0x555bf9)), + text("|", color(0x5562f2)), + text("|", color(0x5569eb)), + text("|", color(0x5570e4)), + text("|", color(0x5577dd)), + text("|", color(0x557ed6)), + text("|", color(0x5585cf)), + text("|", color(0x558cc8)), + text("|", color(0x5593c1)), + text("|", color(0x559aba)), + text("|", color(0x55a2b3)), + text("|", color(0x55a9ab)), + text("|", color(0x55b0a4)), + text("|", color(0x55b79d)), + text("|", color(0x55be96)), + text("|", color(0x55c58f)) + ))).append(text("!")); this.assertParsedEquals(expected, input); } @@ -425,16 +426,20 @@ void testGradientPhase() { @Test void testGradientWithInnerTokens() { final String input = "123456!"; - final Component expected = empty() - .append(text("1", GREEN)) - .append(text("2", color(0x55e371))) - .append(text("3", color(0x55c68e))) - .append(empty().decorate(BOLD) - .append(text("4", color(0x55aaaa))) - .append(text("5", color(0x558ec6))) - .append(text("6", color(0x5571e3))) - ) - .append(text("!")); + final Component expected = textOfChildren( + virtualOfChildren( + textOfChildren( + text("1", GREEN), + text("2", color(0x55e371)), + text("3", color(0x55c68e)) + ), + empty().decorate(BOLD) + .append(text("4", color(0x55aaaa))) + .append(text("5", color(0x558ec6))) + .append(text("6", color(0x5571e3))) + ), + text("!") + ); this.assertParsedEquals(expected, input); } @@ -442,26 +447,30 @@ void testGradientWithInnerTokens() { @Test void testGradientWithInnerGradientWithInnerToken() { final String input = "123456789abc!"; - final Component expected = empty() - .append(text("1", GREEN)) - .append(text("2", color(0x55f163))) - .append(text("3", color(0x55e371))) - .append(empty() - .append(text("4", RED)) - .append(text("5", color(0xff7155))) - .append(text("6", color(0xff8e55))) - .append(empty().decorate(BOLD) - .append(text("7", color(0xffaa55))) - .append(text("8", color(0xffc655))) - .append(text("9", color(0xffe355))) - ) - ) - .append(empty() - .append(text("a", color(0x5580d5))) - .append(text("b", color(0x5571e3))) - .append(text("c", color(0x5563f1))) - ) - .append(text("!")); + final Component expected = textOfChildren( + virtualOfChildren( + textOfChildren( + text("1", GREEN), + text("2", color(0x55f163)), + text("3", color(0x55e371)) + ), + virtualOfChildren( + empty() + .append(text("4", RED)) + .append(text("5", color(0xff7155))) + .append(text("6", color(0xff8e55))), + empty().decorate(BOLD) + .append(text("7", color(0xffaa55))) + .append(text("8", color(0xffc655))) + .append(text("9", color(0xffe355))) + ), + empty() + .append(text("a", color(0x5580d5))) + .append(text("b", color(0x5571e3))) + .append(text("c", color(0x5563f1))) + ), + text("!") + ); this.assertParsedEquals(expected, input); } @@ -472,11 +481,11 @@ void testNonBmpCharactersInGradient() { final String input = "Something 𐌰𐌱𐌲"; final Component expected = text("Something ") - .append(empty() - .append(text("𐌰", BLUE)) - .append(text("𐌱", color(0x558ec6))) - .append(text("𐌲", color(0x55c68e))) - ); + .append(virtualOfChildren(textOfChildren( + text("𐌰", BLUE), + text("𐌱", color(0x558ec6)), + text("𐌲", color(0x55c68e)) + ))); this.assertParsedEquals(expected, input); } @@ -486,8 +495,8 @@ void testSingleCharGradient() { final String input1 = "A"; final String input2 = "AB"; - final Component expected1 = text("A", RED); - final Component expected2 = text().append(text("A", RED), text("B", BLUE)).build(); + final Component expected1 = virtualOfChildren(text("A", RED)); + final Component expected2 = virtualOfChildren(textOfChildren(text("A", RED), text("B", BLUE))); this.assertParsedEquals(expected1, input1); this.assertParsedEquals(expected2, input2); @@ -498,14 +507,12 @@ void testSingleCharGradient() { void testNestedGradientsDontOverrideColors() { final String input = "ab gray"; - final Component expected = Component.text() - .append( + final Component expected = virtualOfChildren( text("a", color(0x1985ff)), - text("b", color(0x00fffb)), + virtualOfChildren(text("b", color(0x00fffb))), text(" ", color(0x1e98ff)), text("gray", NamedTextColor.GRAY) - ) - .build(); + ); this.assertParsedEquals(expected, input); } @@ -515,15 +522,19 @@ void testNestedGradientsDontOverrideColors() { void testNestedGradientsReallyDontOverrideColors() { final String input = "A B C"; - final Component expected = Component.textOfChildren( + final Component expected = virtualOfChildren( + textOfChildren( text("A", NamedTextColor.WHITE), - text(" ", color(0xddddff)), - Component.textOfChildren( + text(" ", color(0xddddff)) + ), + virtualOfChildren( + textOfChildren( text("B", NamedTextColor.YELLOW), - text(" ", color(0xaaaa39)), - text("C", NamedTextColor.WHITE) - ) - ); + text(" ", color(0xaaaa39)) + ), + text("C", NamedTextColor.WHITE) + ) + ); this.assertParsedEquals(expected, input); } @@ -533,7 +544,7 @@ void testNestedGradientsReallyDontOverrideColors() { void testDecorationsPreserved() { final Component placeholder = Component.text("b", style(TextDecoration.ITALIC.withState(true))); final String input = "acd!"; - final Component expected = Component.textOfChildren( + final Component expected = virtualOfChildren( text("a", WHITE), text("b", color(0xcccccc), TextDecoration.ITALIC), text("c", color(0x999999)), @@ -548,13 +559,31 @@ void testDecorationsPreserved() { @Test void testLangTagInGradient() { final String input = "ab!"; - final Component expected = Component.textOfChildren( - text("a", RED), - text("b", color(0xd55580)), + final Component expected = virtualOfChildren( + textOfChildren( + text("a", RED), + text("b", color(0xd55580)) + ), translatable("block.minecraft.diamond_block", color(0xaa55aa)) .append(text("!", color(0x8055d5))) ); this.assertParsedEquals(expected, input); } + + @Test + void testRoundTripGradient() { + final String input = "hello world!"; + final Component parsed = PARSER.deserialize(input); + + this.assertSerializedEquals(input, parsed); + } + + @Test + void testRoundTripNestedGradient() { + final String input = "A B C"; + final Component parsed = PARSER.deserialize(input); + + this.assertSerializedEquals(input, parsed); + } } diff --git a/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/standard/RainbowTagTest.java b/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/standard/RainbowTagTest.java index fce94c976..5ddfb4370 100644 --- a/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/standard/RainbowTagTest.java +++ b/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/standard/RainbowTagTest.java @@ -31,6 +31,7 @@ import static net.kyori.adventure.text.Component.empty; import static net.kyori.adventure.text.Component.text; +import static net.kyori.adventure.text.Component.textOfChildren; import static net.kyori.adventure.text.event.ClickEvent.openUrl; import static net.kyori.adventure.text.format.NamedTextColor.GOLD; import static net.kyori.adventure.text.format.NamedTextColor.GREEN; @@ -58,32 +59,32 @@ void testRainbow() { final String input = "Woo: ||||||||||||||||||||||||!"; final Component expected = empty().color(YELLOW) .append(text("Woo: ")) - .append(empty() - .append(text("|", color(0xff0000))) - .append(text("|", color(0xff3f00))) - .append(text("|", color(0xff7f00))) - .append(text("|", color(0xffbf00))) - .append(text("|", color(0xffff00))) - .append(text("|", color(0xbfff00))) - .append(text("|", color(0x7fff00))) - .append(text("|", color(0x3fff00))) - .append(text("|", color(0x00ff00))) - .append(text("|", color(0x00ff3f))) - .append(text("|", color(0x00ff7f))) - .append(text("|", color(0x00ffbf))) - .append(text("|", color(0x00ffff))) - .append(text("|", color(0x00bfff))) - .append(text("|", color(0x007fff))) - .append(text("|", color(0x003fff))) - .append(text("|", color(0x0000ff))) - .append(text("|", color(0x3f00ff))) - .append(text("|", color(0x7f00ff))) - .append(text("|", color(0xbf00ff))) - .append(text("|", color(0xff00ff))) - .append(text("|", color(0xff00bf))) - .append(text("|", color(0xff007f))) - .append(text("|", color(0xff003f))) - ) + .append(virtualOfChildren(textOfChildren( + text("|", color(0xf3801f)), + text("|", color(0xe1a00d)), + text("|", color(0xc9bf03)), + text("|", color(0xacd901)), + text("|", color(0x8bed08)), + text("|", color(0x6afa16)), + text("|", color(0x4bff2c)), + text("|", color(0x2ffa48)), + text("|", color(0x18ed68)), + text("|", color(0x08d989)), + text("|", color(0x01bfa9)), + text("|", color(0x02a0c7)), + text("|", color(0x0c80e0)), + text("|", color(0x1e5ff2)), + text("|", color(0x3640fc)), + text("|", color(0x5326fe)), + text("|", color(0x7412f7)), + text("|", color(0x9505e9)), + text("|", color(0xb401d3)), + text("|", color(0xd005b7)), + text("|", color(0xe71297)), + text("|", color(0xf72676)), + text("|", color(0xfe4056)), + text("|", color(0xfd5f38)) + ))) .append(text("!")); this.assertParsedEquals(expected, input); @@ -94,32 +95,32 @@ void testRainbowBackwards() { final String input = "Woo: ||||||||||||||||||||||||!"; final Component expected = empty().color(YELLOW) .append(text("Woo: ")) - .append(empty() - .append(text("|", color(0xff003f))) - .append(text("|", color(0xff007f))) - .append(text("|", color(0xff00bf))) - .append(text("|", color(0xff00ff))) - .append(text("|", color(0xbf00ff))) - .append(text("|", color(0x7f00ff))) - .append(text("|", color(0x3f00ff))) - .append(text("|", color(0x0000ff))) - .append(text("|", color(0x003fff))) - .append(text("|", color(0x007fff))) - .append(text("|", color(0x00bfff))) - .append(text("|", color(0x00ffff))) - .append(text("|", color(0x00ffbf))) - .append(text("|", color(0x00ff7f))) - .append(text("|", color(0x00ff3f))) - .append(text("|", color(0x00ff00))) - .append(text("|", color(0x3fff00))) - .append(text("|", color(0x7fff00))) - .append(text("|", color(0xbfff00))) - .append(text("|", color(0xffff00))) - .append(text("|", color(0xffbf00))) - .append(text("|", color(0xff7f00))) - .append(text("|", color(0xff3f00))) - .append(text("|", color(0xff0000))) - ) + .append(virtualOfChildren(textOfChildren( + text("|", color(0xfd5f38)), + text("|", color(0xfe4056)), + text("|", color(0xf72676)), + text("|", color(0xe71297)), + text("|", color(0xd005b7)), + text("|", color(0xb401d3)), + text("|", color(0x9505e9)), + text("|", color(0x7412f7)), + text("|", color(0x5326fe)), + text("|", color(0x3640fc)), + text("|", color(0x1e5ff2)), + text("|", color(0x0c80e0)), + text("|", color(0x02a0c7)), + text("|", color(0x01bfa9)), + text("|", color(0x08d989)), + text("|", color(0x18ed68)), + text("|", color(0x2ffa48)), + text("|", color(0x4bff2c)), + text("|", color(0x6afa16)), + text("|", color(0x8bed08)), + text("|", color(0xacd901)), + text("|", color(0xc9bf03)), + text("|", color(0xe1a00d)), + text("|", color(0xf3801f)) + ))) .append(text("!")); this.assertParsedEquals(expected, input); @@ -130,32 +131,32 @@ void testRainbowPhase() { final String input = "Woo: ||||||||||||||||||||||||!"; final Component expected = empty().color(YELLOW) .append(text("Woo: ")) - .append(empty() - .append(text("|", color(0xcbff00))) - .append(text("|", color(0x8cff00))) - .append(text("|", color(0x4cff00))) - .append(text("|", color(0x0cff00))) - .append(text("|", color(0x00ff33))) - .append(text("|", color(0x00ff72))) - .append(text("|", color(0x00ffb2))) - .append(text("|", color(0x00fff2))) - .append(text("|", color(0x00cbff))) - .append(text("|", color(0x008cff))) - .append(text("|", color(0x004cff))) - .append(text("|", color(0x000cff))) - .append(text("|", color(0x3200ff))) - .append(text("|", color(0x7200ff))) - .append(text("|", color(0xb200ff))) - .append(text("|", color(0xf200ff))) - .append(text("|", color(0xff00cc))) - .append(text("|", color(0xff008c))) - .append(text("|", color(0xff004c))) - .append(text("|", color(0xff000c))) - .append(text("|", color(0xff3200))) - .append(text("|", color(0xff7200))) - .append(text("|", color(0xffb200))) - .append(text("|", color(0xfff200))) - ) + .append(virtualOfChildren(textOfChildren( + text("|", color(0x1ff35c)), + text("|", color(0x0de17d)), + text("|", color(0x03c99e)), + text("|", color(0x01acbd)), + text("|", color(0x088bd7)), + text("|", color(0x166aec)), + text("|", color(0x2c4bf9)), + text("|", color(0x482ffe)), + text("|", color(0x6818fb)), + text("|", color(0x8908ef)), + text("|", color(0xa901db)), + text("|", color(0xc702c1)), + text("|", color(0xe00ca3)), + text("|", color(0xf21e82)), + text("|", color(0xfc3661)), + text("|", color(0xfe5342)), + text("|", color(0xf77428)), + text("|", color(0xe99513)), + text("|", color(0xd3b406)), + text("|", color(0xb7d001)), + text("|", color(0x97e704)), + text("|", color(0x76f710)), + text("|", color(0x56fe24)), + text("|", color(0x38fd3e)) + ))) .append(text("!")); this.assertParsedEquals(expected, input); @@ -166,32 +167,32 @@ void testRainbowPhaseBackwards() { final String input = "Woo: ||||||||||||||||||||||||!"; final Component expected = empty().color(YELLOW) .append(text("Woo: ")) - .append(empty() - .append(text("|", color(0xfff200))) - .append(text("|", color(0xffb200))) - .append(text("|", color(0xff7200))) - .append(text("|", color(0xff3200))) - .append(text("|", color(0xff000c))) - .append(text("|", color(0xff004c))) - .append(text("|", color(0xff008c))) - .append(text("|", color(0xff00cc))) - .append(text("|", color(0xf200ff))) - .append(text("|", color(0xb200ff))) - .append(text("|", color(0x7200ff))) - .append(text("|", color(0x3200ff))) - .append(text("|", color(0x000cff))) - .append(text("|", color(0x004cff))) - .append(text("|", color(0x008cff))) - .append(text("|", color(0x00cbff))) - .append(text("|", color(0x00fff2))) - .append(text("|", color(0x00ffb2))) - .append(text("|", color(0x00ff72))) - .append(text("|", color(0x00ff33))) - .append(text("|", color(0x0cff00))) - .append(text("|", color(0x4cff00))) - .append(text("|", color(0x8cff00))) - .append(text("|", color(0xcbff00))) - ) + .append(virtualOfChildren(textOfChildren( + text("|", color(0x38fd3e)), + text("|", color(0x56fe24)), + text("|", color(0x76f710)), + text("|", color(0x97e704)), + text("|", color(0xb7d001)), + text("|", color(0xd3b406)), + text("|", color(0xe99513)), + text("|", color(0xf77428)), + text("|", color(0xfe5342)), + text("|", color(0xfc3661)), + text("|", color(0xf21e82)), + text("|", color(0xe00ca3)), + text("|", color(0xc702c1)), + text("|", color(0xa901db)), + text("|", color(0x8908ef)), + text("|", color(0x6818fb)), + text("|", color(0x482ffe)), + text("|", color(0x2c4bf9)), + text("|", color(0x166aec)), + text("|", color(0x088bd7)), + text("|", color(0x01acbd)), + text("|", color(0x03c99e)), + text("|", color(0x0de17d)), + text("|", color(0x1ff35c)) + ))) .append(text("!")); this.assertParsedEquals(expected, input); @@ -203,32 +204,33 @@ void testRainbowWithInsertion() { final Component expected = empty().color(YELLOW) .append(text("Woo: ")) .append(empty().insertion("test") - .append(empty() - .append(text("|", color(0xff0000))) - .append(text("|", color(0xff3f00))) - .append(text("|", color(0xff7f00))) - .append(text("|", color(0xffbf00))) - .append(text("|", color(0xffff00))) - .append(text("|", color(0xbfff00))) - .append(text("|", color(0x7fff00))) - .append(text("|", color(0x3fff00))) - .append(text("|", color(0x00ff00))) - .append(text("|", color(0x00ff3f))) - .append(text("|", color(0x00ff7f))) - .append(text("|", color(0x00ffbf))) - .append(text("|", color(0x00ffff))) - .append(text("|", color(0x00bfff))) - .append(text("|", color(0x007fff))) - .append(text("|", color(0x003fff))) - .append(text("|", color(0x0000ff))) - .append(text("|", color(0x3f00ff))) - .append(text("|", color(0x7f00ff))) - .append(text("|", color(0xbf00ff))) - .append(text("|", color(0xff00ff))) - .append(text("|", color(0xff00bf))) - .append(text("|", color(0xff007f))) - .append(text("|", color(0xff003f))) - ).append(text("!")) + .append(virtualOfChildren(textOfChildren( + text("|", color(0xf3801f)), + text("|", color(0xe1a00d)), + text("|", color(0xc9bf03)), + text("|", color(0xacd901)), + text("|", color(0x8bed08)), + text("|", color(0x6afa16)), + text("|", color(0x4bff2c)), + text("|", color(0x2ffa48)), + text("|", color(0x18ed68)), + text("|", color(0x08d989)), + text("|", color(0x01bfa9)), + text("|", color(0x02a0c7)), + text("|", color(0x0c80e0)), + text("|", color(0x1e5ff2)), + text("|", color(0x3640fc)), + text("|", color(0x5326fe)), + text("|", color(0x7412f7)), + text("|", color(0x9505e9)), + text("|", color(0xb401d3)), + text("|", color(0xd005b7)), + text("|", color(0xe71297)), + text("|", color(0xf72676)), + text("|", color(0xfe4056)), + text("|", color(0xfd5f38)) + ))) + .append(text("!")) ); this.assertParsedEquals(expected, input); @@ -240,32 +242,33 @@ void testRainbowBackwardsWithInsertion() { final Component expected = empty().color(YELLOW) .append(text("Woo: ")) .append(empty().insertion("test") - .append(empty() - .append(text("|", color(0xff003f))) - .append(text("|", color(0xff007f))) - .append(text("|", color(0xff00bf))) - .append(text("|", color(0xff00ff))) - .append(text("|", color(0xbf00ff))) - .append(text("|", color(0x7f00ff))) - .append(text("|", color(0x3f00ff))) - .append(text("|", color(0x0000ff))) - .append(text("|", color(0x003fff))) - .append(text("|", color(0x007fff))) - .append(text("|", color(0x00bfff))) - .append(text("|", color(0x00ffff))) - .append(text("|", color(0x00ffbf))) - .append(text("|", color(0x00ff7f))) - .append(text("|", color(0x00ff3f))) - .append(text("|", color(0x00ff00))) - .append(text("|", color(0x3fff00))) - .append(text("|", color(0x7fff00))) - .append(text("|", color(0xbfff00))) - .append(text("|", color(0xffff00))) - .append(text("|", color(0xffbf00))) - .append(text("|", color(0xff7f00))) - .append(text("|", color(0xff3f00))) - .append(text("|", color(0xff0000))) - ).append(text("!")) + .append(virtualOfChildren(textOfChildren( + text("|", color(0xfd5f38)), + text("|", color(0xfe4056)), + text("|", color(0xf72676)), + text("|", color(0xe71297)), + text("|", color(0xd005b7)), + text("|", color(0xb401d3)), + text("|", color(0x9505e9)), + text("|", color(0x7412f7)), + text("|", color(0x5326fe)), + text("|", color(0x3640fc)), + text("|", color(0x1e5ff2)), + text("|", color(0x0c80e0)), + text("|", color(0x02a0c7)), + text("|", color(0x01bfa9)), + text("|", color(0x08d989)), + text("|", color(0x18ed68)), + text("|", color(0x2ffa48)), + text("|", color(0x4bff2c)), + text("|", color(0x6afa16)), + text("|", color(0x8bed08)), + text("|", color(0xacd901)), + text("|", color(0xc9bf03)), + text("|", color(0xe1a00d)), + text("|", color(0xf3801f)) + ))) + .append(text("!")) ); this.assertParsedEquals(expected, input); @@ -275,10 +278,12 @@ void testRainbowBackwardsWithInsertion() { void testRainbowWithInnerClick() { final String input = "Rainbow: GH"; final Component expected = text("Rainbow: ") - .append(empty().clickEvent(openUrl("https://github.com")) - .append(text("G").color(color(0xff0000))) - .append(text("H").color(color(0x00ffff))) - ); + .append(virtualOfChildren( + empty() + .clickEvent(openUrl("https://github.com")) + .append(text("G").color(color(0xf3801f))) + .append(text("H").color(color(0x0c80e0))) + )); this.assertParsedEquals(expected, input); } @@ -287,10 +292,12 @@ void testRainbowWithInnerClick() { void testRainbowBackwardsWithInnerClick() { final String input = "Rainbow: GH"; final Component expected = text("Rainbow: ") - .append(empty().clickEvent(openUrl("https://github.com")) - .append(text("G").color(color(0x00ffff))) - .append(text("H").color(color(0xff0000))) - ); + .append(virtualOfChildren( + empty() + .clickEvent(openUrl("https://github.com")) + .append(text("G").color(color(0x0c80e0))) + .append(text("H").color(color(0xf3801f))) + )); this.assertParsedEquals(expected, input); } @@ -298,16 +305,17 @@ void testRainbowBackwardsWithInnerClick() { // GH-125 @Test void testNoRepeatedTextAfterUnclosedRainbow() { - final Component expected = text() - .append(text('r', color(0xff0000))) - .append(text('a', color(0xff7500))) - .append(text('i', color(0xffeb00))) - .append(text('n', color(0x9cff00))) - .append(text('b', color(0x27ff00))) - .append(text('o', color(0x00ff4e))) - .append(text('w', color(0x00ffc4))) - .append(text("yellow", YELLOW)) - .build(); + final Component expected = virtualOfChildren( + text() + .append(text('r', color(0xf3801f))) + .append(text('a', color(0xcdbb04))) + .append(text('i', color(0x96e805))) + .append(text('n', color(0x59fe22))) + .append(text('b', color(0x25f654))) + .append(text('o', color(0x06d490))) + .append(text('w', color(0x039ec9))), + text("yellow", YELLOW) + ); final String input = "rainbowyellow"; this.assertParsedEquals(expected, input); @@ -315,33 +323,38 @@ void testNoRepeatedTextAfterUnclosedRainbow() { @Test void testRainbowOrGradientContinuesAfterColoredInner() { - final Component expectedRainbow = text() - .append(text('r', color(0xff0000))) - .append(text('a', color(0xff7f00))) - .append(text('i', color(0xffff00))) - .append(text('n', color(0x7fff00))) - .append(text("white", WHITE)) - .append(text() - .append(text('b', color(0x7f00ff))) - .append(text('o', color(0xff00ff))) - .append(text('w', color(0xff007f)))) - .build(); + final Component expectedRainbow = virtualOfChildren( + text() + .append(text('r', color(0xf3801f))) + .append(text('a', color(0xc9bf03))) + .append(text('i', color(0x8bed08))) + .append(text('n', color(0x4bff2c))), + text("white", WHITE), + text() + .append(text('b', color(0xb401d3))) + .append(text('o', color(0xe71297))) + .append(text('w', color(0xfe4056))) + ); final String rainbowInput = "rainwhitebow"; this.assertParsedEquals(expectedRainbow, rainbowInput); - final Component expectedGradient = text() - .append(text('g', WHITE)) - .append(text('r', color(0xebebeb))) - .append(text('a', color(0xd8d8d8))) - .append(text('d', color(0xc4c4c4))) - .append(text("green", GREEN)) - .append(text() - .append(text('i', color(0x4e4e4e))) - .append(text('e', color(0x3b3b3b))) - .append(text('n', color(0x272727))) - .append(text('t', color(0x141414)))) - .build(); + final Component expectedGradient = virtualOfChildren( + textOfChildren( + text('g', WHITE), + text('r', color(0xebebeb)), + text('a', color(0xd8d8d8)), + text('d', color(0xc4c4c4)) + ), + text("green", GREEN), + textOfChildren( + text('i', color(0x4e4e4e)), + text('e', color(0x3b3b3b)), + text('n', color(0x272727)), + text('t', color(0x141414)) + ) + ); + final String gradientInput = "gradgreenient"; this.assertParsedEquals(expectedGradient, gradientInput); @@ -351,22 +364,42 @@ void testRainbowOrGradientContinuesAfterColoredInner() { void gh137() { final String input = ""; final String input2 = "a"; - final Component expected1 = text("a", GOLD); - final Component expected2 = text().append(text("a", GOLD), text("a", YELLOW)).build(); - final Component expected3 = text().append(text("a", GOLD), text("a", YELLOW), text("a", YELLOW)).build(); - final Component expected4 = text().append(text("a", GOLD), text("a", TextColor.color(0xffd52b)), text("a", YELLOW), text("a", YELLOW)).build(); + final Component expected1 = virtualOfChildren(text("a", GOLD)); + final Component expected2 = virtualOfChildren(textOfChildren( + text("a", GOLD), + text("a", YELLOW) + )); + final Component expected3 = virtualOfChildren(textOfChildren( + text("a", GOLD), + text("a", YELLOW), + text("a", YELLOW) + )); + final Component expected4 = virtualOfChildren(textOfChildren( + text("a", GOLD), + text("a", TextColor.color(0xffd52b)), + text("a", YELLOW), + text("a", YELLOW) + )); + final Component expected5 = virtualOfChildren( + textOfChildren( + text("a", GOLD), + text("a", TextColor.color(0xffd52b)), + text("a", YELLOW) + ), + text("a", YELLOW) + ); this.assertParsedEquals(expected1, input, component("dum", text("a"))); this.assertParsedEquals(expected2, input, component("dum", text("aa"))); this.assertParsedEquals(expected3, input, component("dum", text("aaa"))); this.assertParsedEquals(expected4, input, component("dum", text("aaaa"))); - this.assertParsedEquals(expected4, input2, component("dum", text("aaa"))); + this.assertParsedEquals(expected5, input2, component("dum", text("aaa"))); } @Test void gh147() { final String input = ""; - final Component expected1 = text().append(text("y", color(0xff0000)), text("o", color(0x00ffff))).build(); + final Component expected1 = virtualOfChildren(text().append(text("y", color(0xf3801f)), text("o", color(0x0c80e0))).build()); this.assertParsedEquals(expected1, input, component("msg", text("yo"))); } } diff --git a/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/standard/ResetTagTest.java b/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/standard/ResetTagTest.java index ed92e8f59..e95f198fd 100644 --- a/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/standard/ResetTagTest.java +++ b/text-minimessage/src/test/java/net/kyori/adventure/text/minimessage/tag/standard/ResetTagTest.java @@ -29,25 +29,24 @@ import static net.kyori.adventure.text.Component.empty; import static net.kyori.adventure.text.Component.text; +import static net.kyori.adventure.text.Component.textOfChildren; import static net.kyori.adventure.text.format.NamedTextColor.YELLOW; import static net.kyori.adventure.text.format.TextColor.color; class ResetTagTest extends AbstractTest { - @Test void testReset() { final String input = "Click this wooo to insert!"; final Component expected = text("Click ") .append(empty().color(YELLOW).insertion("test") .append(text("this")) - .append(empty() - .append(text(" ", color(0xff0000))) - .append(text("w", color(0xcbff00))) - .append(text("o", color(0x00ff66))) - .append(text("o", color(0x0065ff))) - .append(text("o", color(0xcc00ff))) - ) - ).append(text(" to insert!")); + .append(virtualOfChildren(textOfChildren( + text(" ", color(0xf3801f)), + text("w", color(0x71f813)), + text("o", color(0x03ca9c)), + text("o", color(0x4135fe)), + text("o", color(0xd507b1)) + )))).append(text(" to insert!")); this.assertParsedEquals(expected, input); }