|
|
@@ -58,11 +58,11 @@ class AiRuleVerifierTest {
|
|
|
@Test
|
|
|
@DisplayName("单列错误率超 5% 该列被拒绝绑定,而不是整体降分")
|
|
|
void badColumnIsRejectedNotDampened() {
|
|
|
- // 10 行里 4 行金额非法 → 40%,远超 5% 拒绝线
|
|
|
+ // 10 行里 4 行必填金额非法 → 40%,远超 5% 拒绝线
|
|
|
List<Map<Integer, String>> data = new ArrayList<>(rows(6, "100.00", "张三"));
|
|
|
data.addAll(rows(4, "约100元", "李四"));
|
|
|
VerifyReport r = AiRuleVerifier.verify(data,
|
|
|
- List.of(col(0, "amt", "MONEY", false), col(1, "name", "TEXT", false)), 0.9, 0.8, 10);
|
|
|
+ List.of(col(0, "amt", "MONEY", true), col(1, "name", "TEXT", false)), 0.9, 0.8, 10);
|
|
|
assertTrue(r.rejectedCols().contains(0), r.perColErrorRate().toString());
|
|
|
// 另一列不受牵连
|
|
|
assertFalse(r.rejectedCols().contains(1));
|
|
|
@@ -71,15 +71,27 @@ class AiRuleVerifierTest {
|
|
|
@Test
|
|
|
@DisplayName("错误率在 1%~5% 之间:只够走出口 B,不够往既有业务表写")
|
|
|
void midErrorRateOnlyPassesAiTable() {
|
|
|
- // 200 行里 5 行坏 = 2.5%
|
|
|
+ // 200 行里 5 行必填金额坏 = 2.5%
|
|
|
List<Map<Integer, String>> data = new ArrayList<>(rows(195, "100.00", "张三"));
|
|
|
data.addAll(rows(5, "脏值", "张三"));
|
|
|
VerifyReport r = AiRuleVerifier.verify(data,
|
|
|
- List.of(col(0, "amt", "MONEY", false), col(1, "name", "TEXT", true)), 0.9, 0.8, 200);
|
|
|
+ List.of(col(0, "amt", "MONEY", true), col(1, "name", "TEXT", true)), 0.9, 0.8, 200);
|
|
|
assertTrue(r.pass(AiCleanExitEnum.B));
|
|
|
assertFalse(r.pass(AiCleanExitEnum.A));
|
|
|
}
|
|
|
|
|
|
+ @Test
|
|
|
+ @DisplayName("非必填脏值只置空、不阻塞行:出口 A 也放行")
|
|
|
+ void optionalErrorsDoNotBlock() {
|
|
|
+ List<Map<Integer, String>> data = new ArrayList<>(rows(195, "100.00", "张三"));
|
|
|
+ data.addAll(rows(5, "脏值", "张三"));
|
|
|
+ VerifyReport r = AiRuleVerifier.verify(data,
|
|
|
+ List.of(col(0, "amt", "MONEY", false), col(1, "name", "TEXT", true)), 0.95, 0.9, 200);
|
|
|
+ assertEquals(0d, r.perColErrorRate().get(0), 0.0001,
|
|
|
+ "非必填脏值不应计入阻塞错误率");
|
|
|
+ assertTrue(r.pass(AiCleanExitEnum.A));
|
|
|
+ }
|
|
|
+
|
|
|
@Test
|
|
|
@DisplayName("有效行率过低:两个出口都不放行")
|
|
|
void lowRowYieldBlocksBoth() {
|