bug处理

This commit is contained in:
truewhile
2026-10-02 15:14:36 +08:00
parent 83ec494a36
commit 2c6646beea
23 changed files with 1900 additions and 108 deletions
@@ -0,0 +1,92 @@
package rule
import (
"strings"
"testing"
)
// TestJavaValueStringMatchesJavaMapToString 书源正则依赖 Java 的 Map.toString 形态。
// 真实案例:拷贝漫画的 author 规则 `$.author##.*name=(.*?)\,.*##$1`,
// 期望拿到 `{name=岸本斉史, alias=…}`;Go 的 `map[...]` 形态匹配不到,作者会退化成一串 map 文本。
func TestJavaValueStringMatchesJavaMapToString(t *testing.T) {
ar := NewAnalyzeRule()
ar.SetContent(`{"author":[{"name":"岸本斉史","alias":"岸本齐史,キシモトマサ","path_word":"anbenqishi"}]}`, "https://api.example.com")
got, err := ar.GetString(`$.author##.*name=(.*?)\,.*##$1`, nil, false)
if err != nil {
t.Fatalf("err=%v", err)
}
if got != "岸本斉史" {
t.Fatalf("author = %q,期望 岸本斉史(Java Map 形态没对上)", got)
}
// 对象/数组/标量的字符串形态
str, err := ar.GetString(`$.author[0]`, nil, false)
if err != nil {
t.Fatalf("err=%v", err)
}
for _, want := range []string{"{", "name=岸本斉史", "alias=岸本齐史,キシモトマサ", "path_word=anbenqishi"} {
if !strings.Contains(str, want) {
t.Errorf("对象字符串 %q 缺少 %q", str, want)
}
}
if strings.Contains(str, "map[") {
t.Errorf("仍是 Go 的 map 形态: %q", str)
}
}
// TestJavaValueStringScalars 标量与嵌套结构按 Java 习惯输出。
func TestJavaValueStringScalars(t *testing.T) {
cases := []struct {
in any
want string
}{
{nil, "null"},
{"x", "x"},
{true, "true"},
{float64(399), "399"},
{float64(1.5), "1.5"},
{[]any{float64(1), "a"}, "[1, a]"},
{map[string]any{"b": float64(1), "a": "x"}, "{a=x, b=1}"},
{map[string]any{"n": []any{"x", "y"}}, "{n=[x, y]}"},
}
for _, c := range cases {
if got := javaValueString(c.in); got != c.want {
t.Errorf("javaValueString(%#v) = %q,期望 %q", c.in, got, c.want)
}
}
}
// TestJavaToURL legado JsURL 的四个属性(并兼容 Java Map 的 searchParams.get)。
func TestJavaToURL(t *testing.T) {
r := NewJSRunner(JSConfig{})
ar := NewAnalyzeRule()
check := func(expr, want string) {
t.Helper()
v, err := r.Run(ar, expr, nil, "")
if err != nil {
t.Fatalf("%s 失败: %v", expr, err)
}
if got := anyToString(v); got != want {
t.Errorf("%s = %q,期望 %q", expr, got, want)
}
}
check(`java.toURL('https://api.example.com:8443/a/b?x=1&y=%E4%B8%AD%E6%96%87').host`, "api.example.com")
check(`java.toURL('https://api.example.com:8443/a/b?x=1&y=%E4%B8%AD%E6%96%87').origin`, "https://api.example.com:8443")
check(`java.toURL('https://api.example.com/a/b').origin`, "https://api.example.com")
check(`java.toURL('https://api.example.com/a/b?x=1').pathname`, "/a/b")
check(`java.toURL('https://api.example.com/a/b?x=1&y=%E4%B8%AD%E6%96%87').searchParams.x`, "1")
check(`java.toURL('https://api.example.com/a/b?x=1&y=%E4%B8%AD%E6%96%87').searchParams.y`, "中文")
check(`java.toURL('https://api.example.com/a/b?x=1').searchParams.get('x')`, "1")
// 相对地址按 baseUrl 解析(对应 Java 的 URL(base, url))
check(`java.toURL('/next?p=2', 'https://api.example.com/a/b').origin`, "https://api.example.com")
check(`java.toURL('/next?p=2', 'https://api.example.com/a/b').pathname`, "/next")
// 不存在的参数给 null(对应 Java Map.get 返回 null)
check(`String(java.toURL('https://api.example.com/a').searchParams.get('nope'))`, "null")
// 非绝对地址必须报错(Java 抛 MalformedURLException),不能静默给一个空对象
if _, err := r.Run(ar, `java.toURL('not-a-url').host`, nil, ""); err == nil {
t.Error("非绝对地址应当报错")
}
}