Files
arcrun-collector/cmd/arcrun-tray/t184_test.go
T
Leo 9fcd82b517 v0.15.7:改名 Arcrun.app+發 DMG(拖進 Applications)+MSIX 正式身分
leo 08-04:「如果當初 mac 打包就是 dmg 用拖的,現在 oscar 那裡就解決了,
如果當初 msix 就用了,現在另一個人也是更新就可以」——遠慮該在第一版就有。
原則:**用戶好用、白癡化**。

① 改名 Arcrun RAG.app → Arcrun.app(leo:「不要 rag,要 arcrun.app」)
   五處引用一起改(selfupdate.go/build-mac.sh/build-dmg.sh/t184_test.go/README)

② 新增 build-dmg.sh:DMG 內含 Arcrun.app + Applications 捷徑
   =Mac 幾十年的標準做法,開起來就暗示你拖進去 ⇒ **從源頭讓 app 待在對的位置**。
   坑:hdiutil 預設檔案系統會把「Arcrun RAG.app」截成「RAG.app」⇒ 加 -fs HFS+ 解。
   DMG 治源頭、t184 是安全網,兩個都要(已裝在別處的人不會因改發 DMG 就自動變好)。

③ MSIX 用 .env 的正式 Partner Center 身分重打(**不是佔位值**)
   回讀 AppxManifest 逐欄驗證:
     Identity Name        Uncle6.Arcrun
     Publisher            CN=DE038286-31A5-47CF-B83F-FF6B206BF591
     PublisherDisplayName Uncle6
     Version              0.15.7.0
     仍含 PLACEHOLDER      False

實測(t184 端到端,模擬 Oscar 的情境):
  app 放 /tmp/oscar-test/Downloads/(不在 /Applications)→ 跑更新覆蓋
  → 該處 app 變成 v0.15.7 
  → /Applications 沒有被無中生有一個副本 
  路徑推導三種放置位置皆正確(Downloads/Applications/Desktop)

產物 sha256:
  dmg  0eb3f76b60bf6891   mac zip f264dda7391f3006
  win  32fe44450ca77c62   msix    5bf7c911b8f3a817

 誠實標記:MSIX 能否實際安裝**這台 Mac 驗不到**(Add-AppxPackage 只有 Windows)。
   已驗的是包結構合法(unpack 過 blockmap 雜湊)+身分欄位正確。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 18:12:53 +08:00

56 lines
2.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package main
import (
"os"
"path/filepath"
"strings"
"testing"
)
// t184:更新必須蓋在「正在跑的那個 .app」,不是寫死 /Applications。
// leo 08-04 實撞:Oscar 從下載資料夾跑 → ditto 自動建 /Applications 副本並回成功
// → 他重開仍是舊版,畫面卻說更新完成(靜默失敗)。
func TestRunningAppBundlePathNotHardcoded(t *testing.T) {
got, err := runningAppBundlePath()
// 測試執行檔不在 .app 裡 → 應誠實回錯,**不可**回傳寫死的 /Applications 路徑
if err == nil && strings.HasPrefix(got, "/Applications/") {
t.Errorf("不該回寫死的 /Applications 路徑:%q", got)
}
if err == nil && !strings.HasSuffix(got, ".app") {
t.Errorf("回傳的不是 .app%q", got)
}
}
// 模擬真實 .app 結構:<dir>/Arcrun.app/Contents/MacOS/arcrun-tray
// 驗證「往上三層」的推導正確——放在哪個目錄都要算得出來。
func TestAppBundleDerivationFromExePath(t *testing.T) {
for _, base := range []string{"/Applications", "/Users/oscar/Downloads", "/Volumes/USB"} {
exe := filepath.Join(base, "Arcrun.app", "Contents", "MacOS", "arcrun-tray")
app := filepath.Dir(filepath.Dir(filepath.Dir(exe)))
want := filepath.Join(base, "Arcrun.app")
if app != want {
t.Errorf("從 %s 推導錯:got %q want %q", base, app, want)
}
}
}
// ditto 對不存在的目標會自動建目錄且回成功——這正是靜默失敗的成因,留測防回歸認知。
func TestDittoCreatesMissingTargetSilently(t *testing.T) {
dir := t.TempDir()
src := filepath.Join(dir, "Fake.app", "Contents")
if err := os.MkdirAll(src, 0o755); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(src, "x"), []byte("hi"), 0o644); err != nil {
t.Fatal(err)
}
dst := filepath.Join(dir, "nowhere", "Fake.app")
if _, err := runCmd("ditto", filepath.Join(dir, "Fake.app"), dst); err != nil {
t.Skipf("此環境沒有 ditto%v", err)
}
if _, err := os.Stat(dst); err != nil {
t.Fatal("前提失效:ditto 應自動建出目標")
}
t.Log("確認:ditto 蓋到不存在的路徑會成功建出 ⇒ 寫死路徑必然靜默失敗")
}