mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-13 11:13:43 +08:00
The PRIVATE_ITEMS list contained the bare 'test' entry, which rsync interprets as 'any directory named test at any depth' — so it caught the root-level /test/ scratch directory (intended) AND every src/test/ under each module (not intended). Pattern is already anchored to /test (root-only). This commit rsyncs the accumulated src/test/ tree forward so opensource has the unit tests that have been written / updated against existing src/main/ code since the pattern regression. Going forward each per-commit sync will carry src/test/ files along with the main change.
71 lines
3.4 KiB
Java
71 lines
3.4 KiB
Java
package vip.mate.channel;
|
|
|
|
import org.junit.jupiter.api.DisplayName;
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
|
|
/**
|
|
* Pin the adaptive-debounce thresholds in
|
|
* {@link ChannelMessageRouter#pickDebounceMs(int)}.
|
|
*
|
|
* <p>The router merges same-conversation messages within a debounce window
|
|
* before forwarding to the agent. The default {@link
|
|
* ChannelMessageRouter#DEBOUNCE_MS} (500ms) is right for normal chatting
|
|
* but too short for IM clients that silently split long pasted prompts
|
|
* across multiple frames — the second fragment can arrive 1-2 seconds
|
|
* after the first, missing the window. When merged content crosses
|
|
* {@link ChannelMessageRouter#LONG_TEXT_THRESHOLD} the merger switches to
|
|
* {@link ChannelMessageRouter#LONG_DEBOUNCE_MS} so it has time to absorb
|
|
* the rest. These tests document that boundary behavior so future tuning
|
|
* is intentional rather than incidental.
|
|
*/
|
|
class ChannelMessageRouterDebounceTest {
|
|
|
|
@Test
|
|
@DisplayName("short messages keep the 500ms default debounce")
|
|
void shortMessagesKeepDefaultDebounce() {
|
|
assertEquals(ChannelMessageRouter.DEBOUNCE_MS,
|
|
ChannelMessageRouter.pickDebounceMs(0));
|
|
assertEquals(ChannelMessageRouter.DEBOUNCE_MS,
|
|
ChannelMessageRouter.pickDebounceMs(50));
|
|
assertEquals(ChannelMessageRouter.DEBOUNCE_MS,
|
|
ChannelMessageRouter.pickDebounceMs(500));
|
|
assertEquals(ChannelMessageRouter.DEBOUNCE_MS,
|
|
ChannelMessageRouter.pickDebounceMs(ChannelMessageRouter.LONG_TEXT_THRESHOLD));
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("crossing the threshold flips to the extended 2.5s window")
|
|
void longContentTriggersLongDebounce() {
|
|
assertEquals(ChannelMessageRouter.LONG_DEBOUNCE_MS,
|
|
ChannelMessageRouter.pickDebounceMs(ChannelMessageRouter.LONG_TEXT_THRESHOLD + 1));
|
|
assertEquals(ChannelMessageRouter.LONG_DEBOUNCE_MS,
|
|
ChannelMessageRouter.pickDebounceMs(2000));
|
|
assertEquals(ChannelMessageRouter.LONG_DEBOUNCE_MS,
|
|
ChannelMessageRouter.pickDebounceMs(6000));
|
|
assertEquals(ChannelMessageRouter.LONG_DEBOUNCE_MS,
|
|
ChannelMessageRouter.pickDebounceMs(Integer.MAX_VALUE));
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("threshold + windows are sane: long > default, threshold below typical IM split")
|
|
void thresholdsAreSane() {
|
|
// The whole point — the extended window must actually be larger,
|
|
// otherwise the adaptive branch is a no-op.
|
|
assertTrue(ChannelMessageRouter.LONG_DEBOUNCE_MS > ChannelMessageRouter.DEBOUNCE_MS,
|
|
"extended debounce must exceed default");
|
|
// Threshold sits below the typical ~2000-char WeCom client split
|
|
// point; if it ever crept above 2000 the merger would never
|
|
// engage on a real paste-split.
|
|
assertTrue(ChannelMessageRouter.LONG_TEXT_THRESHOLD < 2000,
|
|
"threshold must stay under the IM client's split point");
|
|
// And well above any normally typed message — typing 1500+ chars
|
|
// in one bubble is extremely rare. Guards against accidentally
|
|
// applying the long-debounce penalty to ordinary chats.
|
|
assertTrue(ChannelMessageRouter.LONG_TEXT_THRESHOLD >= 1000,
|
|
"threshold must be high enough that typing doesn't trip it");
|
|
}
|
|
}
|