feat: 项目整体命名修改cache-schema-checker
All checks were successful
缓存序列化结构检查 / cache-schema-check (push) Has been skipped
All checks were successful
缓存序列化结构检查 / cache-schema-check (push) Has been skipped
This commit is contained in:
92
src/test/java/com/codechecker/cache/TenantScenarioTest.java
vendored
Normal file
92
src/test/java/com/codechecker/cache/TenantScenarioTest.java
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
package com.codechecker.cache;
|
||||
|
||||
import com.codechecker.cache.detector.RedisWritePointDetector;
|
||||
import com.codechecker.cache.detector.WritePoint;
|
||||
import com.codechecker.cache.diff.ChangeType;
|
||||
import com.codechecker.cache.diff.SchemaChange;
|
||||
import com.codechecker.cache.diff.SchemaDiffer;
|
||||
import com.codechecker.cache.schema.JavaSchemaExtractor;
|
||||
import com.codechecker.cache.schema.SourceIndex;
|
||||
import com.codechecker.cache.schema.TypeSchema;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* 端到端组件级验证:租户缓存由 TenantVO 变为 CacheEnvelope{vo, expiresAtMs} 的结构变更。
|
||||
*/
|
||||
class TenantScenarioTest {
|
||||
|
||||
private static final Set<String> PATTERNS = new HashSet<>();
|
||||
|
||||
static {
|
||||
PATTERNS.add("W01");
|
||||
PATTERNS.add("W02");
|
||||
PATTERNS.add("W03");
|
||||
}
|
||||
|
||||
@Test
|
||||
void detectsTenantEnvelopeWrapping() {
|
||||
String tenantVo = TestSupport.fixture("fixtures/tenant/TenantVO.txt");
|
||||
String tenantLink = TestSupport.fixture("fixtures/tenant/TenantLinkModel.txt");
|
||||
String helperOld = TestSupport.fixture("fixtures/tenant/HelperOld.txt");
|
||||
String helperNew = TestSupport.fixture("fixtures/tenant/HelperNew.txt");
|
||||
|
||||
SourceIndex oldIndex = new SourceIndex();
|
||||
oldIndex.addSource(tenantVo);
|
||||
oldIndex.addSource(tenantLink);
|
||||
oldIndex.addSource(helperOld);
|
||||
|
||||
SourceIndex newIndex = new SourceIndex();
|
||||
newIndex.addSource(tenantVo);
|
||||
newIndex.addSource(tenantLink);
|
||||
newIndex.addSource(helperNew);
|
||||
|
||||
WritePoint oldWp = single(new RedisWritePointDetector(oldIndex, PATTERNS)
|
||||
.detect("Helper.java", helperOld));
|
||||
WritePoint newWp = single(new RedisWritePointDetector(newIndex, PATTERNS)
|
||||
.detect("Helper.java", helperNew));
|
||||
|
||||
// key 推断
|
||||
assertEquals("tenant:db:content:*", oldWp.getResolvedKeyPattern());
|
||||
assertEquals("tenant:db:content:*", newWp.getResolvedKeyPattern());
|
||||
// 写入点配对签名一致
|
||||
assertEquals(oldWp.signature(), newWp.signature());
|
||||
|
||||
// value 类型推断
|
||||
assertEquals("jnpf.model.TenantVO", oldWp.getResolvedValueType());
|
||||
assertNotNull(newWp.getResolvedValueType());
|
||||
assertTrue(newWp.getResolvedValueType().endsWith("CacheEnvelope"));
|
||||
|
||||
JavaSchemaExtractor oldEx = new JavaSchemaExtractor(oldIndex, 8);
|
||||
JavaSchemaExtractor newEx = new JavaSchemaExtractor(newIndex, 8);
|
||||
TypeSchema oldSchema = oldEx.extract(oldWp.getResolvedValueType(), oldWp.isRootArray());
|
||||
TypeSchema newSchema = newEx.extract(newWp.getResolvedValueType(), newWp.isRootArray());
|
||||
|
||||
// 旧结构包含顶层 dbName、linkList[].id
|
||||
assertTrue(oldSchema.getFields().containsKey("dbName"));
|
||||
assertTrue(oldSchema.getFields().containsKey("linkList[].id"));
|
||||
// 新结构包含 vo.dbName、expiresAtMs
|
||||
assertTrue(newSchema.getFields().containsKey("vo.dbName"));
|
||||
assertTrue(newSchema.getFields().containsKey("expiresAtMs"));
|
||||
|
||||
List<SchemaChange> changes = new SchemaDiffer().diff(oldSchema, newSchema);
|
||||
List<ChangeType> types = changes.stream().map(SchemaChange::getChangeType).collect(Collectors.toList());
|
||||
|
||||
assertTrue(types.contains(ChangeType.WRAPPER_ADDED), "应检测到包装层 vo");
|
||||
assertTrue(types.contains(ChangeType.FIELD_PATH_MOVED), "应检测到字段路径迁移");
|
||||
assertTrue(types.contains(ChangeType.FIELD_ADDED), "应检测到 expiresAtMs 新增");
|
||||
}
|
||||
|
||||
private WritePoint single(List<WritePoint> wps) {
|
||||
assertEquals(1, wps.size(), "应恰好检测到 1 个写入点");
|
||||
return wps.get(0);
|
||||
}
|
||||
}
|
||||
33
src/test/java/com/codechecker/cache/TestSupport.java
vendored
Normal file
33
src/test/java/com/codechecker/cache/TestSupport.java
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
package com.codechecker.cache;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
/**
|
||||
* 测试通用工具:加载 classpath 下的 fixture 文本。
|
||||
*/
|
||||
public final class TestSupport {
|
||||
|
||||
private TestSupport() {
|
||||
}
|
||||
|
||||
public static String fixture(String path) {
|
||||
try (InputStream in = TestSupport.class.getClassLoader().getResourceAsStream(path)) {
|
||||
if (in == null) {
|
||||
throw new IllegalArgumentException("fixture 不存在: " + path);
|
||||
}
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
byte[] chunk = new byte[8192];
|
||||
int read;
|
||||
while ((read = in.read(chunk)) != -1) {
|
||||
buffer.write(chunk, 0, read);
|
||||
}
|
||||
return new String(buffer.toByteArray(), StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
28
src/test/java/com/codechecker/cache/analyze/GlobMatcherTest.java
vendored
Normal file
28
src/test/java/com/codechecker/cache/analyze/GlobMatcherTest.java
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
package com.codechecker.cache.analyze;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class GlobMatcherTest {
|
||||
|
||||
@Test
|
||||
void matchesPrefixWildcard() {
|
||||
assertTrue(GlobMatcher.matches("tenant:db:content:*", "tenant:db:content:abc"));
|
||||
assertTrue(GlobMatcher.matches("*:lock", "device:add:lock"));
|
||||
assertTrue(GlobMatcher.matches("*lock*", "abTaskDetailUpdate:lock:x"));
|
||||
assertTrue(GlobMatcher.matches("loginCount:*", "loginCount:13800000000"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void matchesDoubleStarPath() {
|
||||
assertTrue(GlobMatcher.matches("**/test/**", "jnpf-x/src/test/java/Foo.java"));
|
||||
assertFalse(GlobMatcher.matches("**/test/**", "jnpf-x/src/main/java/Foo.java"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void literalNoMatch() {
|
||||
assertFalse(GlobMatcher.matches("tenant:db:content:*", "other:key"));
|
||||
}
|
||||
}
|
||||
67
src/test/java/com/codechecker/cache/config/ConfigLoaderTest.java
vendored
Normal file
67
src/test/java/com/codechecker/cache/config/ConfigLoaderTest.java
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
package com.codechecker.cache.config;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
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 ConfigLoaderTest {
|
||||
|
||||
@Test
|
||||
void loadsDefaultsWhenNoBusinessConfig() {
|
||||
CheckerConfig config = ConfigLoader.load(null);
|
||||
assertTrue(config.isEnabled());
|
||||
assertEquals("notify", config.getMode());
|
||||
assertTrue(config.getDetection().getPatterns().contains("W01"));
|
||||
assertFalse(config.isScanTestSources());
|
||||
}
|
||||
|
||||
@Test
|
||||
void businessConfigOverridesDefaults(@org.junit.jupiter.api.io.TempDir Path tmp) throws IOException {
|
||||
Path cfg = tmp.resolve("biz.yaml");
|
||||
Files.write(cfg, ("enabled: false\n"
|
||||
+ "mode: block\n"
|
||||
+ "include_modules:\n - jnpf-tenant\n"
|
||||
+ "notify:\n enabled: false\n").getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
CheckerConfig config = ConfigLoader.load(cfg);
|
||||
assertFalse(config.isEnabled());
|
||||
assertEquals("block", config.getMode());
|
||||
assertTrue(config.isBlockMode());
|
||||
assertEquals(1, config.getIncludeModules().size());
|
||||
assertEquals("jnpf-tenant", config.getIncludeModules().get(0));
|
||||
// 未覆盖项保留默认
|
||||
assertFalse(config.getNotify().isEnabled());
|
||||
assertTrue(config.getDetection().getPatterns().contains("W01"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadsWebhookUrlFromConfig(@org.junit.jupiter.api.io.TempDir Path tmp) throws IOException {
|
||||
Path cfg = tmp.resolve("biz.yaml");
|
||||
Files.write(cfg, ("notify:\n"
|
||||
+ " webhook_url: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=test\n"
|
||||
).getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
CheckerConfig config = ConfigLoader.load(cfg);
|
||||
assertEquals("https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=test",
|
||||
config.getNotify().getWebhookUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
void legacyWebhookEnvUrlStillWorks(@org.junit.jupiter.api.io.TempDir Path tmp) throws IOException {
|
||||
Path cfg = tmp.resolve("biz.yaml");
|
||||
Files.write(cfg, ("notify:\n"
|
||||
+ " webhook_env: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=legacy\n"
|
||||
).getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
CheckerConfig config = ConfigLoader.load(cfg);
|
||||
assertEquals("https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=legacy",
|
||||
config.getNotify().getWebhookUrl());
|
||||
}
|
||||
}
|
||||
64
src/test/java/com/codechecker/cache/diff/SchemaDifferTest.java
vendored
Normal file
64
src/test/java/com/codechecker/cache/diff/SchemaDifferTest.java
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
package com.codechecker.cache.diff;
|
||||
|
||||
import com.codechecker.cache.schema.FieldSchema;
|
||||
import com.codechecker.cache.schema.JsonType;
|
||||
import com.codechecker.cache.schema.TypeSchema;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class SchemaDifferTest {
|
||||
|
||||
@Test
|
||||
void detectsWrapperMoveAndAddition() {
|
||||
TypeSchema oldS = new TypeSchema("TenantVO");
|
||||
oldS.add(new FieldSchema("dbName", JsonType.STRING, "String"));
|
||||
oldS.add(new FieldSchema("linkList", JsonType.ARRAY, "List"));
|
||||
oldS.add(new FieldSchema("linkList[]", JsonType.OBJECT, "TenantLinkModel"));
|
||||
oldS.add(new FieldSchema("linkList[].id", JsonType.STRING, "String"));
|
||||
|
||||
TypeSchema newS = new TypeSchema("CacheEnvelope");
|
||||
newS.add(new FieldSchema("vo", JsonType.OBJECT, "TenantVO"));
|
||||
newS.add(new FieldSchema("vo.dbName", JsonType.STRING, "String"));
|
||||
newS.add(new FieldSchema("vo.linkList", JsonType.ARRAY, "List"));
|
||||
newS.add(new FieldSchema("vo.linkList[]", JsonType.OBJECT, "TenantLinkModel"));
|
||||
newS.add(new FieldSchema("vo.linkList[].id", JsonType.STRING, "String"));
|
||||
newS.add(new FieldSchema("expiresAtMs", JsonType.NUMBER, "Long"));
|
||||
|
||||
List<SchemaChange> changes = new SchemaDiffer().diff(oldS, newS);
|
||||
List<ChangeType> types = changes.stream().map(SchemaChange::getChangeType).collect(Collectors.toList());
|
||||
|
||||
assertTrue(types.contains(ChangeType.WRAPPER_ADDED), "应检测到包装层新增");
|
||||
assertTrue(types.contains(ChangeType.FIELD_PATH_MOVED), "应检测到字段路径迁移");
|
||||
assertTrue(types.contains(ChangeType.FIELD_ADDED), "应检测到新增字段 expiresAtMs");
|
||||
|
||||
long moved = changes.stream().filter(c -> c.getChangeType() == ChangeType.FIELD_PATH_MOVED).count();
|
||||
assertEquals(2, moved, "dbName 与 linkList[].id 均应迁移");
|
||||
}
|
||||
|
||||
@Test
|
||||
void detectsTypeChange() {
|
||||
TypeSchema oldS = new TypeSchema("A");
|
||||
oldS.add(new FieldSchema("count", JsonType.STRING, "String"));
|
||||
TypeSchema newS = new TypeSchema("A");
|
||||
newS.add(new FieldSchema("count", JsonType.NUMBER, "Integer"));
|
||||
|
||||
List<SchemaChange> changes = new SchemaDiffer().diff(oldS, newS);
|
||||
assertEquals(1, changes.size());
|
||||
assertEquals(ChangeType.TYPE_CHANGED, changes.get(0).getChangeType());
|
||||
assertEquals(Severity.P0, changes.get(0).getSeverity());
|
||||
}
|
||||
|
||||
@Test
|
||||
void noChangeWhenIdentical() {
|
||||
TypeSchema a = new TypeSchema("A");
|
||||
a.add(new FieldSchema("x", JsonType.STRING, "String"));
|
||||
TypeSchema b = new TypeSchema("A");
|
||||
b.add(new FieldSchema("x", JsonType.STRING, "String"));
|
||||
assertTrue(new SchemaDiffer().diff(a, b).isEmpty());
|
||||
}
|
||||
}
|
||||
79
src/test/java/com/codechecker/cache/report/ReportBuilderTest.java
vendored
Normal file
79
src/test/java/com/codechecker/cache/report/ReportBuilderTest.java
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
package com.codechecker.cache.report;
|
||||
|
||||
import com.codechecker.cache.diff.ChangeType;
|
||||
import com.codechecker.cache.diff.SchemaChange;
|
||||
import com.codechecker.cache.diff.Severity;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class ReportBuilderTest {
|
||||
|
||||
@Test
|
||||
void wecomMarkdownShowsSkeletonWithoutSeverityAndLocation() {
|
||||
CheckReport report = new CheckReport();
|
||||
report.setRepository("jnpf-java-cloud");
|
||||
report.setBranch("code/redis_change_detection_v1.0");
|
||||
report.setOldSha("cedd161c");
|
||||
report.setNewSha("67c8a6eb");
|
||||
report.setModifier("dongzi");
|
||||
report.setModifyTime("2026-07-13 16:54:17");
|
||||
|
||||
SchemaChange detail = new SchemaChange(ChangeType.WRAPPER_ADDED);
|
||||
detail.setSeverity(Severity.P0);
|
||||
detail.setKeyPattern("tenant:db:content:*");
|
||||
detail.setWriteLocation("Helper#put:10");
|
||||
detail.setFieldPath("vo");
|
||||
detail.setMessage("新增包装层 vo");
|
||||
report.getChanges().add(detail);
|
||||
|
||||
KeyStructureChange key = new KeyStructureChange();
|
||||
key.setKeyPattern("tenant:db:content:*");
|
||||
key.setOldSkeletonJson("{\"dbName\":\"\",\"linkList\":[{\"id\":\"\"}]}");
|
||||
key.setNewSkeletonJson("{\"vo\":{\"dbName\":\"\",\"linkList\":[{\"id\":\"\"}]},\"expiresAtMs\":0}");
|
||||
key.setSeverity(Severity.P0);
|
||||
report.getKeyChanges().add(key);
|
||||
|
||||
String md = new ReportBuilder("[缓存结构变更]").toMarkdown(report);
|
||||
|
||||
assertTrue(md.startsWith("## [缓存结构变更] jnpf-java-cloud"));
|
||||
assertTrue(md.contains("> **分支**: code/redis_change_detection_v1.0"));
|
||||
assertTrue(md.contains("> **时间**: 2026-07-13 16:54:17"));
|
||||
assertTrue(md.contains("`tenant:db:content:*`"));
|
||||
assertTrue(md.contains("value 值从 “{\"dbName\":\"\""));
|
||||
assertTrue(md.contains("变更为 “{\"vo\":"));
|
||||
assertFalse(md.contains("### P0"));
|
||||
assertFalse(md.contains("位置"));
|
||||
assertFalse(md.contains("模式"));
|
||||
assertFalse(md.contains("汇总"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void consoleContainsFieldDetailsAndWecomMarkdown() {
|
||||
CheckReport report = new CheckReport();
|
||||
report.setRepository("demo");
|
||||
report.setOldSha("aaa");
|
||||
report.setNewSha("bbb");
|
||||
|
||||
SchemaChange detail = new SchemaChange(ChangeType.FIELD_REMOVED);
|
||||
detail.setSeverity(Severity.P0);
|
||||
detail.setKeyPattern("k1");
|
||||
detail.setWriteLocation("Foo#bar:1");
|
||||
detail.setMessage("删除字段 x");
|
||||
report.getChanges().add(detail);
|
||||
|
||||
KeyStructureChange key = new KeyStructureChange();
|
||||
key.setKeyPattern("k1");
|
||||
key.setOldSkeletonJson("{\"x\":\"\"}");
|
||||
key.setNewSkeletonJson("{}");
|
||||
report.getKeyChanges().add(key);
|
||||
|
||||
String console = new ReportBuilder("[缓存结构变更]").toConsole(report);
|
||||
assertTrue(console.contains("======== 字段明细 ========"));
|
||||
assertTrue(console.contains("**位置**: Foo#bar:1"));
|
||||
assertTrue(console.contains("**删除字段**: x"));
|
||||
assertTrue(console.contains("======== 企微 Markdown ========"));
|
||||
assertTrue(console.contains("value 值从"));
|
||||
}
|
||||
}
|
||||
83
src/test/java/com/codechecker/cache/schema/SkeletonJsonRendererTest.java
vendored
Normal file
83
src/test/java/com/codechecker/cache/schema/SkeletonJsonRendererTest.java
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
package com.codechecker.cache.schema;
|
||||
|
||||
import com.codechecker.cache.TestSupport;
|
||||
import com.codechecker.cache.detector.RedisWritePointDetector;
|
||||
import com.codechecker.cache.detector.WritePoint;
|
||||
import com.codechecker.cache.diff.SchemaChange;
|
||||
import com.codechecker.cache.diff.SchemaDiffer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class SkeletonJsonRendererTest {
|
||||
|
||||
@Test
|
||||
void rendersTenantVoThenEnvelopeSkeletons() {
|
||||
String tenantVo = TestSupport.fixture("fixtures/tenant/TenantVO.txt");
|
||||
String tenantLink = TestSupport.fixture("fixtures/tenant/TenantLinkModel.txt");
|
||||
String helperOld = TestSupport.fixture("fixtures/tenant/HelperOld.txt");
|
||||
String helperNew = TestSupport.fixture("fixtures/tenant/HelperNew.txt");
|
||||
|
||||
Set<String> patterns = new HashSet<>();
|
||||
patterns.add("W01");
|
||||
patterns.add("W02");
|
||||
patterns.add("W03");
|
||||
|
||||
SourceIndex oldIndex = new SourceIndex();
|
||||
oldIndex.addSource(tenantVo);
|
||||
oldIndex.addSource(tenantLink);
|
||||
oldIndex.addSource(helperOld);
|
||||
|
||||
SourceIndex newIndex = new SourceIndex();
|
||||
newIndex.addSource(tenantVo);
|
||||
newIndex.addSource(tenantLink);
|
||||
newIndex.addSource(helperNew);
|
||||
|
||||
WritePoint oldWp = new RedisWritePointDetector(oldIndex, patterns)
|
||||
.detect("Helper.java", helperOld).get(0);
|
||||
WritePoint newWp = new RedisWritePointDetector(newIndex, patterns)
|
||||
.detect("Helper.java", helperNew).get(0);
|
||||
|
||||
TypeSchema oldSchema = new JavaSchemaExtractor(oldIndex, 8)
|
||||
.extract(oldWp.getResolvedValueType(), oldWp.isRootArray());
|
||||
TypeSchema newSchema = new JavaSchemaExtractor(newIndex, 8)
|
||||
.extract(newWp.getResolvedValueType(), newWp.isRootArray());
|
||||
|
||||
List<SchemaChange> changes = new SchemaDiffer().diff(oldSchema, newSchema);
|
||||
Set<String> protectedPaths = changes.stream()
|
||||
.map(SchemaChange::getFieldPath)
|
||||
.filter(p -> p != null && !p.isEmpty())
|
||||
.collect(Collectors.toCollection(HashSet::new));
|
||||
changes.stream()
|
||||
.filter(c -> c.getOldValue() != null && c.getOldValue().contains("."))
|
||||
.forEach(c -> protectedPaths.add(c.getOldValue()));
|
||||
// also plain old paths without dot
|
||||
changes.forEach(c -> {
|
||||
if (c.getOldValue() != null && !c.getOldValue().isEmpty()
|
||||
&& c.getOldValue().indexOf(' ') < 0) {
|
||||
protectedPaths.add(c.getOldValue());
|
||||
}
|
||||
});
|
||||
|
||||
SkeletonJsonRenderer renderer = new SkeletonJsonRenderer();
|
||||
String oldJson = renderer.render(oldSchema);
|
||||
String newJson = renderer.render(newSchema);
|
||||
|
||||
assertTrue(oldJson.contains("\"dbName\":\"\""));
|
||||
assertTrue(oldJson.contains("\"linkList\":["));
|
||||
assertTrue(newJson.contains("\"vo\":{"));
|
||||
assertTrue(newJson.contains("\"expiresAtMs\":0"));
|
||||
assertTrue(newJson.contains("\"dbName\":\"\""));
|
||||
|
||||
String truncated = renderer.render(newSchema, protectedPaths, 80);
|
||||
assertTrue(truncated.contains("expiresAtMs") || truncated.contains("vo"),
|
||||
"截断后仍应保留改动相关字段: " + truncated);
|
||||
assertEquals(true, truncated.length() >= 10);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user