Add text queries and whole-log chat search
TextQuery holds a find bar's text and options (match case, whole word, regex) and matches plain text; HtmlText strips a log entry down to it. ChatLogStore can now search a whole log rather than only the history loaded into a chat. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package com.ts3client.chatlog;
|
||||
|
||||
import com.ts3client.text.TextQuery;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
@@ -40,4 +41,31 @@ class ChatLogStoreTest {
|
||||
assertTrue(history.get(0).contains("ericek111"));
|
||||
assertTrue(history.get(0).contains("hello"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void searchReachesPastTheLoadedHistory() throws Exception {
|
||||
ChatLogStore logs = new ChatLogStore(temp, "+Tyg2JtxE8vRNZp+JiUBnmBh0MY=");
|
||||
logs.appendMessage(ChatLogScope.CHANNEL, false, 5, "uid", "alice", "the needle is here");
|
||||
for (int i = 0; i < ChatLogStore.HISTORY_LIMIT; i++) {
|
||||
logs.appendMessage(ChatLogScope.CHANNEL, false, 5, "uid", "alice", "filler " + i);
|
||||
}
|
||||
logs.appendServerEvent("a NEEDLE of the server");
|
||||
|
||||
assertTrue(logs.channelHtmlHistory().stream().noneMatch(e -> e.contains("needle")));
|
||||
ChatLogStore.SearchResult channel = logs.search(ChatLogScope.CHANNEL, null,
|
||||
new TextQuery("needle", false, false, false), 10);
|
||||
assertEquals(1, channel.total());
|
||||
assertTrue(channel.entries().get(0).contains("the needle is here"));
|
||||
|
||||
ChatLogStore.SearchResult server = logs.search(ChatLogScope.SERVER, null,
|
||||
new TextQuery("needle", true, false, false), 10);
|
||||
assertEquals(0, server.total());
|
||||
|
||||
ChatLogStore.SearchResult capped = logs.search(ChatLogScope.CHANNEL, null,
|
||||
new TextQuery("filler", false, false, false), 10);
|
||||
assertEquals(ChatLogStore.HISTORY_LIMIT, capped.total());
|
||||
assertEquals(10, capped.entries().size());
|
||||
assertTrue(capped.truncated());
|
||||
assertTrue(capped.entries().get(9).contains("filler " + (ChatLogStore.HISTORY_LIMIT - 1)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.ts3client.text;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class TextQueryTest {
|
||||
|
||||
@Test
|
||||
void ignoresCaseUnlessAsked() {
|
||||
assertTrue(new TextQuery("hello", false, false, false).matches("Say HELLO there"));
|
||||
assertFalse(new TextQuery("hello", true, false, false).matches("Say HELLO there"));
|
||||
assertTrue(new TextQuery("čau", false, false, false).matches("ČAU"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void wholeWordsStopAtLettersAndDigitsOnly() {
|
||||
TextQuery q = new TextQuery("cat", false, true, false);
|
||||
assertTrue(q.matches("the cat sat"));
|
||||
assertTrue(q.matches("(cat)"));
|
||||
assertFalse(q.matches("concatenate"));
|
||||
assertFalse(q.matches("cat2"));
|
||||
assertTrue(new TextQuery("@all", false, true, false).matches("hey @all!"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void literalUnlessRegex() {
|
||||
assertFalse(new TextQuery("a.c", false, false, false).matches("abc"));
|
||||
assertTrue(new TextQuery("a.c", false, false, true).matches("abc"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void invalidRegexMatchesNothing() {
|
||||
TextQuery q = new TextQuery("(", false, false, true);
|
||||
assertTrue(q.isInvalid());
|
||||
assertFalse(q.matches("("));
|
||||
}
|
||||
|
||||
@Test
|
||||
void plainTextOfHtml() {
|
||||
assertEquals("<\"x\"> a & b", HtmlText.plain("<span class=\"t\"><"x"></span> a & b"));
|
||||
assertEquals("line\nnext", HtmlText.plain("line<br>next"));
|
||||
assertEquals("é", HtmlText.plain("é"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user