|
|
@@ -246,7 +246,7 @@ class LeshouyingPropertiesTest {
|
|
|
placeholderDefault(yml, "LESHOUYING_INST_NO"),
|
|
|
"DOC_TEST_INST_NO 与 application.yml 的 ${LESHOUYING_INST_NO:...} 默认值不一致");
|
|
|
assertEquals(LeshouyingProperties.DOC_TEST_BASE_URL,
|
|
|
- ymlLine(yml, "base-url"),
|
|
|
+ ymlLine(yml, "leshouying", "base-url"),
|
|
|
"DOC_TEST_BASE_URL 与 application.yml 的 base-url 不一致");
|
|
|
}
|
|
|
|
|
|
@@ -282,7 +282,7 @@ class LeshouyingPropertiesTest {
|
|
|
for (String[] pair : keyToEnv) {
|
|
|
String key = pair[0];
|
|
|
String env = pair[1];
|
|
|
- assertEquals("${" + env + ":}", ymlLine(yml, key),
|
|
|
+ assertEquals("${" + env + ":}", ymlLine(yml, "leshouying", key),
|
|
|
"leshouying." + key + " 的值必须恰好是 ${" + env
|
|
|
+ ":}(键名或环境变量名漂移都会让它在运行时静默失效)");
|
|
|
assertEquals("", placeholderDefault(yml, env),
|
|
|
@@ -297,10 +297,34 @@ class LeshouyingPropertiesTest {
|
|
|
return m.group(1);
|
|
|
}
|
|
|
|
|
|
- /** 取 `key: value` 这种平铺配置项的值(去空白)。只匹配第一次出现。 */
|
|
|
- private static String ymlLine(String yml, String key) {
|
|
|
- Matcher m = Pattern.compile("(?m)^\\s*" + Pattern.quote(key) + "\\s*:\\s*(\\S+)\\s*$").matcher(yml);
|
|
|
- assertTrue(m.find(), "application.yml 里找不到 " + key);
|
|
|
+ /**
|
|
|
+ * 取 application.yml **指定段内** `key: value` 这种平铺配置项的值(去空白)。
|
|
|
+ *
|
|
|
+ * ★ 为什么必须限定段(2026-09-24 实测):原实现是整文件取「第一次出现」,
|
|
|
+ * 隐含依赖「键名在整个文件里唯一」。并入汇安融(HAR)通道时这份 yml 新增了
|
|
|
+ * `har.base-url`,而它排在 `leshouying.base-url` **之前**
|
|
|
+ * ⇒ 原实现返回 HAR 的空串,`DOC_TEST_BASE_URL` 那条断言报
|
|
|
+ * `expected: <https://test.gdyfsk.com/yfpay> but was: <"">`。
|
|
|
+ * 键名全文件唯一**不是**本函数该依赖的性质:若将来两个段的 base-url 被配成
|
|
|
+ * 同一个值,取错键还会**报绿**(假绿比假红贵)。段内唯一是可靠的 ——
|
|
|
+ * 同一个段里同名键本来就是 YAML 错误。
|
|
|
+ */
|
|
|
+ private static String ymlLine(String yml, String section, String key) {
|
|
|
+ String sec = sectionText(yml, section);
|
|
|
+ Matcher m = Pattern.compile("(?m)^\\s*" + Pattern.quote(key) + "\\s*:\\s*(\\S+)\\s*$").matcher(sec);
|
|
|
+ assertTrue(m.find(), "application.yml 的 " + section + " 段里找不到 " + key);
|
|
|
return m.group(1);
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 截出顶级段 `section:` 的正文:从该行之后,到下一个**顶级键**(行首为字母/下划线)为止。
|
|
|
+ * 空行与行首 `#` 注释不算边界,故段内注释穿插不会把段提前截断。
|
|
|
+ */
|
|
|
+ private static String sectionText(String yml, String section) {
|
|
|
+ Matcher head = Pattern.compile("(?m)^" + Pattern.quote(section) + ":\\s*$").matcher(yml);
|
|
|
+ assertTrue(head.find(), "application.yml 里找不到顶级段 " + section + ":");
|
|
|
+ Matcher next = Pattern.compile("(?m)^[A-Za-z_]").matcher(yml);
|
|
|
+ int end = next.find(head.end()) ? next.start() : yml.length();
|
|
|
+ return yml.substring(head.end(), end);
|
|
|
+ }
|
|
|
}
|