feat: P1 合盘/星座/问答与测测完整设计包及模拟器取证工具

落地 synastry/star/ask API 与 H5 页面,补齐 cece-frontend-re complete-design 证据文档,并加入 Android 模拟器截图抓取脚本。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
jackyu66git
2026-08-03 11:37:53 +08:00
co-authored by Cursor
parent 15a9db374a
commit bd22d9dddd
248 changed files with 26309 additions and 842 deletions
+83
View File
@@ -0,0 +1,83 @@
package star
import (
"encoding/json"
"strings"
"testing"
"time"
)
func TestBuildDeterministic(t *testing.T) {
birth := time.Date(1990, 5, 12, 0, 0, 0, 0, time.UTC)
asOf := time.Date(2026, 8, 2, 12, 0, 0, 0, time.UTC)
opts := BuildOpts{Birth: birth, Name: "小愈", AsOf: asOf}
a, err := BuildWith(opts)
if err != nil {
t.Fatal(err)
}
b, err := BuildWith(opts)
if err != nil {
t.Fatal(err)
}
if a.Summary["headline"] != b.Summary["headline"] {
t.Fatal("not deterministic")
}
if a.Summary["sun_sign"] == nil || a.Detail["sections"] == nil {
t.Fatal("missing fields")
}
if a.Summary["sign_cards"] == nil || a.Summary["fortune"] == nil || a.Summary["planets"] == nil {
t.Fatal("missing sign_cards, fortune or planets")
}
if a.Summary["aspects_preview"] == nil {
t.Fatal("missing aspects_preview")
}
chart, _ := a.Summary["chart"].(map[string]any)
if chart["asc_lon"] == nil {
t.Fatal("missing chart.asc_lon")
}
if a.Detail["aspects"] == nil {
t.Fatal("missing detail.aspects")
}
raw, _ := json.Marshal(a)
blob := string(raw)
for _, bad := range []string{"算命"} {
if strings.Contains(blob, bad) {
t.Fatalf("forbidden %q", bad)
}
}
}
func TestBuildWithBirthTimeChangesRise(t *testing.T) {
birth := time.Date(1990, 5, 12, 0, 0, 0, 0, time.UTC)
bt := "14:30"
place := "北京"
a, err := BuildWith(BuildOpts{Birth: birth, Name: "我"})
if err != nil {
t.Fatal(err)
}
b, err := BuildWith(BuildOpts{Birth: birth, BirthTime: &bt, BirthPlace: &place, Name: "我"})
if err != nil {
t.Fatal(err)
}
if a.Summary["planets"] == nil || b.Summary["planets"] == nil {
t.Fatal("missing planets")
}
_ = a.Summary["rise_sign"]
_ = b.Summary["rise_sign"]
}
func TestBuildFortuneScores(t *testing.T) {
birth := time.Date(1990, 5, 12, 0, 0, 0, 0, time.UTC)
out, err := BuildWith(BuildOpts{Birth: birth, Name: "测", AsOf: time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC)})
if err != nil {
t.Fatal(err)
}
fort, ok := out.Summary["fortune"].(map[string]any)
if !ok {
t.Fatal("fortune missing")
}
daily, ok := fort["daily"].(map[string]any)
if !ok || daily["score"] == nil {
t.Fatal("daily score missing")
}
}