1+ package de.srendi.advancedperipherals.test
2+
3+ import dan200.computercraft.gametest.api.*
4+ import dan200.computercraft.gametest.api.Timeouts.SECOND
5+ import dan200.computercraft.gametest.core.ClientTestEvents
6+ import net.minecraft.ChatFormatting
7+ import net.minecraft.client.Minecraft
8+ import net.minecraft.client.gui.components.toasts.SystemToast
9+ import net.minecraft.core.BlockPos
10+ import net.minecraft.gametest.framework.GameTestHelper
11+ import net.minecraft.network.chat.ClickEvent
12+ import net.minecraft.network.chat.Component
13+ import java.util.function.BiPredicate
14+
15+ @GameTestHolder
16+ class ChatBoxTest {
17+
18+ private fun getFormattedMessage (bracketColor : String , openBracket : Char , closeBracket : Char , prefix : String , message : String ): Component {
19+ return Component .literal(" $bracketColor$openBracket §r" )
20+ .append(prefix)
21+ .append(" $bracketColor$closeBracket §r " )
22+ .append(
23+ Component .literal(" Red " ).withStyle(ChatFormatting .RED )
24+ .append(Component .literal(" Bold " ).withStyle(ChatFormatting .BOLD ).withStyle(ChatFormatting .WHITE ))
25+ .append(Component .literal(" Click " ).withStyle(ChatFormatting .UNDERLINE ).withStyle(ChatFormatting .WHITE )
26+ .withStyle { it.withClickEvent(ClickEvent (ClickEvent .Action .OPEN_URL , " https://advancedperipherals.madefor.cc/" )) })
27+ .append(Component .literal(message).withStyle(ChatFormatting .ITALIC ).withStyle(ChatFormatting .AQUA ))
28+ )
29+ }
30+
31+ private fun getFormattedToast (bracketColor : ChatFormatting ? , openBracket : Char , closeBracket : Char , prefix : String , message : String ): List <Component > {
32+ val prefixComponents = if (bracketColor != null ) {
33+ listOf (
34+ Component .literal(" $openBracket " ).withStyle(bracketColor),
35+ Component .literal(prefix),
36+ Component .literal(" $closeBracket " ).withStyle(bracketColor),
37+ Component .literal(" " )
38+ )
39+ } else {
40+ listOf (
41+ Component .literal(" $openBracket$prefix$closeBracket " )
42+ )
43+ }
44+
45+ return prefixComponents + listOf (
46+ Component .literal(" Red " ).withStyle(ChatFormatting .RED ),
47+ Component .literal(" Bold " ).withStyle(ChatFormatting .WHITE ).withStyle(ChatFormatting .BOLD ),
48+ Component .literal(" Click " ).withStyle(ChatFormatting .WHITE ).withStyle(ChatFormatting .UNDERLINE )
49+ .withStyle { it.withClickEvent(ClickEvent (ClickEvent .Action .OPEN_URL , " https://advancedperipherals.madefor.cc/" )) },
50+ Component .literal(message).withStyle(ChatFormatting .AQUA ).withStyle(ChatFormatting .ITALIC )
51+ )
52+ }
53+
54+ private fun containsToast (filter : BiPredicate <Component , List <Component >>): Boolean {
55+ return ClientTestEvents .toasts.filterIsInstance<SystemToast >().any {
56+ val sink = ComponentFormattedCharSink ()
57+ it.messageLines.forEachIndexed { index, line ->
58+ line.accept(sink)
59+ if (index < it.messageLines.size - 1 ) {
60+ sink.accept(0 , sink.currentStyle!! , ' ' .code)
61+ }
62+ }
63+
64+ filter.test(it.title, sink.getComponents())
65+ }
66+ }
67+
68+ private fun assertContainsToast (title : Component , components : List <Component >) {
69+ if (! containsToast { toastTitle, toastComponents -> toastTitle == title && toastComponents == components }) {
70+ throw AssertionError (" Toast with title $title and components $components not found" )
71+ }
72+ }
73+
74+ private fun assertNotContainsToast (title : Component , components : List <Component >) {
75+ if (containsToast { toastTitle, toastComponents -> toastTitle == title && toastComponents == components }) {
76+ throw AssertionError (" Toast with title $title and components $components found" )
77+ }
78+ }
79+
80+ private fun assertNotContainsToast (filter : BiPredicate <Component , List <Component >>) {
81+ if (containsToast(filter)) {
82+ throw AssertionError (" Toast matching filter found" )
83+ }
84+ }
85+
86+ @ClientGameTest(timeoutTicks = 60 * SECOND )
87+ fun chatBox (context : GameTestHelper ) = context.sequence {
88+ thenExecute { context.positionAt(BlockPos (2 , 6 , 2 ), 90f ) }
89+ thenOnClient {
90+ Minecraft .getInstance().gui.chat.clearMessages(false )
91+ ClientTestEvents .toasts.clear()
92+ }
93+ thenComputerOk()
94+
95+ thenOnClient {
96+ // sendMessage
97+ context.assertChatContains(Component .literal(" [§r" ).append(" AP" ).append(" ]§r " ).append(" Default message" ))
98+ context.assertChatContains(Component .literal(" [§r" ).append(" GameTest" ).append(" ]§r " ).append(" Message with prefix" ))
99+ context.assertChatContains(Component .literal(" <§r" ).append(" GameTest" ).append(" >§r " ).append(" Message with brackets" ))
100+ context.assertChatContains(Component .literal(" §a<§r" ).append(" GameTest" ).append(" §a>§r " ).append(" Message with bracket color" ))
101+ context.assertChatNotContains(Component .literal(" §a<§r" ).append(" GameTest" ).append(" §a>§r " ).append(" Message with short range" ))
102+ context.assertChatNotContains { it.toString().contains(" Message with invalid brackets" ) }
103+
104+ // sendMessageToPlayer
105+ context.assertChatContains(Component .literal(" [§r" ).append(" AP" ).append(" ]§r " ).append(" Default message to player" ))
106+ context.assertChatContains(Component .literal(" [§r" ).append(" GameTest" ).append(" ]§r " ).append(" Message with prefix to player" ))
107+ context.assertChatContains(Component .literal(" <§r" ).append(" GameTest" ).append(" >§r " ).append(" Message with brackets to player" ))
108+ context.assertChatContains(Component .literal(" §a<§r" ).append(" GameTest" ).append(" §a>§r " ).append(" Message with bracket color to player" ))
109+ context.assertChatNotContains(Component .literal(" §a<§r" ).append(" GameTest" ).append(" §a>§r " ).append(" Message with short range to player" ))
110+ context.assertChatNotContains { it.toString().contains(" Message with invalid brackets to player" ) }
111+ context.assertChatNotContains(Component .literal(" [§r" ).append(" AP" ).append(" ]§r " ).append(" Default message to invalid player" ))
112+
113+ // sendFormattedMessage
114+ context.assertChatContains(getFormattedMessage(" " , ' [' , ' ]' , " AP" , " Default formatted message" ))
115+ context.assertChatContains(getFormattedMessage(" " , ' [' , ' ]' , " GameTest" , " Formatted message with prefix" ))
116+ context.assertChatContains(getFormattedMessage(" " , ' <' , ' >' , " GameTest" , " Formatted message with brackets" ))
117+ context.assertChatContains(getFormattedMessage(" §a" , ' <' , ' >' , " GameTest" , " Formatted message with bracket color" ))
118+ context.assertChatNotContains(getFormattedMessage(" §a" , ' <' , ' >' , " GameTest" , " Formatted message with short range" ))
119+ context.assertChatNotContains { it.toString().contains(" Formatted message with invalid brackets" ) }
120+
121+ // sendFormattedMessageToPlayer
122+ context.assertChatContains(getFormattedMessage(" " , ' [' , ' ]' , " AP" , " Default formatted message to player" ))
123+ context.assertChatContains(getFormattedMessage(" " , ' [' , ' ]' , " GameTest" , " Formatted message with prefix to player" ))
124+ context.assertChatContains(getFormattedMessage(" " , ' <' , ' >' , " GameTest" , " Formatted message with brackets to player" ))
125+ context.assertChatContains(getFormattedMessage(" §a" , ' <' , ' >' , " GameTest" , " Formatted message with bracket color to player" ))
126+ context.assertChatNotContains(getFormattedMessage(" §a" , ' <' , ' >' , " GameTest" , " Formatted message with short range to player" ))
127+ context.assertChatNotContains { it.toString().contains(" Formatted message with invalid brackets to player" ) }
128+ context.assertChatNotContains(getFormattedMessage(" " , ' [' , ' ]' , " AP" , " Default formatted message to invalid player" ))
129+
130+ // sendToastToPlayer
131+ val defaultToastTitle = Component .literal(" Toast Title" )
132+ assertContainsToast(defaultToastTitle, listOf (Component .literal(" [AP] Default toast to player" )))
133+ assertContainsToast(defaultToastTitle, listOf (Component .literal(" [GameTest] Toast with prefix to player" )))
134+ assertContainsToast(defaultToastTitle, listOf (Component .literal(" <GameTest> Toast with brackets to player" )))
135+ assertContainsToast(defaultToastTitle, listOf (
136+ Component .literal(" <" ).withStyle(ChatFormatting .GREEN ),
137+ Component .literal(" GameTest" ),
138+ Component .literal(" >" ).withStyle(ChatFormatting .GREEN ),
139+ Component .literal(" Toast with bracket color to player" )
140+ ))
141+ assertNotContainsToast(defaultToastTitle, listOf (
142+ Component .literal(" <" ).withStyle(ChatFormatting .GREEN ),
143+ Component .literal(" GameTest" ),
144+ Component .literal(" >" ).withStyle(ChatFormatting .GREEN ),
145+ Component .literal(" Toast with short range to player" )
146+ ))
147+ assertNotContainsToast { title, components -> title == defaultToastTitle && components.any { it.toString().contains(" Toast with invalid brackets to player" ) } }
148+ assertNotContainsToast(defaultToastTitle, listOf (Component .literal(" [AP] Default toast to invalid player" )))
149+
150+ // sendFormattedToastToPlayer
151+ val formattedToastTitle = Component .literal(" Formatted Toast Title" ).withStyle(ChatFormatting .DARK_PURPLE )
152+ assertContainsToast(formattedToastTitle, getFormattedToast(null , ' [' , ' ]' , " AP" , " Default formatted toast to player" ))
153+ assertContainsToast(formattedToastTitle, getFormattedToast(null , ' [' , ' ]' , " GameTest" , " Formatted toast with prefix to player" ))
154+ assertContainsToast(formattedToastTitle, getFormattedToast(null , ' <' , ' >' , " GameTest" , " Formatted toast with brackets to player" ))
155+ assertContainsToast(formattedToastTitle, getFormattedToast(ChatFormatting .GREEN , ' <' , ' >' , " GameTest" , " Formatted toast with bracket color to player" ))
156+ assertNotContainsToast(formattedToastTitle, getFormattedToast(ChatFormatting .GREEN , ' <' , ' >' , " GameTest" , " Formatted toast with short range to player" ))
157+ assertNotContainsToast { title, components -> title == formattedToastTitle && components.any { it.toString().contains(" Formatted toast with invalid brackets to player" ) } }
158+ assertNotContainsToast(formattedToastTitle, getFormattedToast(null , ' [' , ' ]' , " AP" , " Default formatted toast to invalid player" ))
159+ }
160+ }
161+
162+ @ClientGameTest
163+ fun chatBox_Events (context : GameTestHelper ) = context.sequence {
164+ thenIdle(20 )
165+ thenOnClient { Minecraft .getInstance().player!! .chatSigned(" This is a normal chat message" , null ) }
166+ thenIdle(20 )
167+ thenOnClient { Minecraft .getInstance().player!! .chatSigned(" \$ This is a hidden chat message" , null ) }
168+ thenIdle(20 )
169+ thenComputerOk()
170+ }
171+
172+ }
0 commit comments