mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-13 19:23:42 +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.
95 lines
3.0 KiB
Java
95 lines
3.0 KiB
Java
package vip.mate.wiki.service;
|
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
import org.junit.jupiter.api.BeforeEach;
|
|
import org.junit.jupiter.api.DisplayName;
|
|
import org.junit.jupiter.api.Test;
|
|
import vip.mate.wiki.WikiProperties;
|
|
import vip.mate.wiki.dto.EnrichmentBatchPlan;
|
|
import vip.mate.wiki.job.WikiModelRoutingService;
|
|
|
|
import static org.junit.jupiter.api.Assertions.*;
|
|
import static org.mockito.Mockito.mock;
|
|
|
|
/**
|
|
* RFC-051 follow-up: pin parseBatchPlan's tolerance for the shapes weak
|
|
* models actually emit.
|
|
*/
|
|
class WikiEnrichmentBatchParseTest {
|
|
|
|
private WikiLinkEnrichmentService svc;
|
|
|
|
@BeforeEach
|
|
void setUp() {
|
|
svc = new WikiLinkEnrichmentService(
|
|
mock(WikiPageService.class),
|
|
mock(WikiModelRoutingService.class),
|
|
new WikiProperties(),
|
|
new ObjectMapper());
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("happy path: parses well-formed multi-page plan")
|
|
void parsesGoodBatch() {
|
|
String json = """
|
|
{
|
|
"plans": {
|
|
"spring-ai": {
|
|
"replacements": [
|
|
{"original": "Spring AI", "replacement": "[[spring-ai|Spring AI]]", "occurrence": 1}
|
|
]
|
|
},
|
|
"linux": {
|
|
"replacements": []
|
|
}
|
|
}
|
|
}
|
|
""";
|
|
EnrichmentBatchPlan p = svc.parseBatchPlan(json);
|
|
assertNotNull(p);
|
|
assertEquals(2, p.plans().size());
|
|
assertEquals(1, p.plans().get("spring-ai").replacements().size());
|
|
assertTrue(p.plans().get("linux").replacements().isEmpty());
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("tolerates fenced code block wrapper that some models love")
|
|
void parsesCodeFenced() {
|
|
String json = """
|
|
```json
|
|
{
|
|
"plans": {
|
|
"x": {"replacements": [{"original": "X", "replacement": "[[x|X]]", "occurrence": 1}]}
|
|
}
|
|
}
|
|
```""";
|
|
EnrichmentBatchPlan p = svc.parseBatchPlan(json);
|
|
assertNotNull(p);
|
|
assertEquals(1, p.plans().size());
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("tolerates stray prose around the JSON object")
|
|
void parsesWithSurroundingProse() {
|
|
String json = "Sure! Here's the plan:\n{\"plans\":{\"x\":{\"replacements\":[]}}}\nLet me know if you need adjustments.";
|
|
EnrichmentBatchPlan p = svc.parseBatchPlan(json);
|
|
assertNotNull(p);
|
|
assertEquals(1, p.plans().size());
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("returns empty (not null) when plans field is missing")
|
|
void missingPlansFieldYieldsEmpty() {
|
|
EnrichmentBatchPlan p = svc.parseBatchPlan("{}");
|
|
assertNotNull(p);
|
|
assertTrue(p.isEmpty());
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("garbage input returns null so caller can skip cleanly")
|
|
void garbageReturnsNull() {
|
|
assertNull(svc.parseBatchPlan(""));
|
|
assertNull(svc.parseBatchPlan("not json at all"));
|
|
}
|
|
}
|