// cloudversion_test.go — t177:托盤「知識庫需要更新」的判斷(wiki 事故 D)。 // // 🔴 為什麼補這支:這個 bug **有兩份**(collector/cloud_version.go + 本 package 的 // trayCloudVersionStale),collector 那份一直有測試、**tray 這份沒有** ⇒ 沒人擋得住它出貨。 // leo 08-04 實撞:兩個帳號都更新到 1.4.6 了,托盤仍掛「知識庫需要更新(點我)」。 // 真兇=`"1.4.6" < "2026-07-28"` 是**字串比較**("1" < "2" 恆成立)⇒ 任何 semver 都被判過舊。 package main import "testing" func TestTrayCloudVersionStale(t *testing.T) { cases := []struct { name string version string checkOK bool wantStale bool }{ // ── t177 回歸守衛:semver 世代 ──────────────────────────────────── {"semver 最新版不得判過舊(leo 08-04 實撞的那一版)", "1.4.6", true, false}, {"semver 舊版也不判過舊(吐得出 semver=已是新契約)", "1.4.1", true, false}, {"semver 帶 +sha 後綴同樣正確解析", "1.4.6+deadbee", true, false}, // ── 相容性:舊格式仍要判得出過舊,否則老實例被漏報 ────────────────── {"舊日期格式過舊仍要提示(不可為修 semver 而漏報)", "2026-07-01+abc1234", true, true}, {"舊日期格式剛好達標=不提示", "2026-07-28+abc1234", true, false}, // ── 邊界 ────────────────────────────────────────────────────────── {"空版本(老實例)→ 提示", "", true, true}, {"/health 不可達 → 不判定(呼叫端另以『查不到版本』誠實顯示)", "", false, false}, {"怪字串不得被誤認為 semver", "1.4", true, true}, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { if got := trayCloudVersionStale(tc.version, tc.checkOK); got != tc.wantStale { t.Errorf("trayCloudVersionStale(%q, %v) = %v,want %v", tc.version, tc.checkOK, got, tc.wantStale) } }) } } // isSemverLike 是上面那條判斷的關鍵——它認錯格式就會整條判斷跟著錯,故單獨釘死。 func TestIsSemverLike(t *testing.T) { yes := []string{"1.4.6", "0.0.1", "10.20.30", "1.4.10"} no := []string{"1.4", "1.4.6.7", "2026-07-28", "v1.4.6", "1.4.x", "", "a.b.c", "1..6"} for _, s := range yes { if !isSemverLike(s) { t.Errorf("isSemverLike(%q) = false,want true", s) } } for _, s := range no { if isSemverLike(s) { t.Errorf("isSemverLike(%q) = true,want false", s) } } }