| 1 | package main |
| 2 | |
| 3 | import ( |
| 4 | "os" |
| 5 | "path/filepath" |
| 6 | "strings" |
| 7 | "testing" |
| 8 | |
| 9 | "github.com/wailsapp/wails/v2/pkg/options" |
| 10 | ) |
| 11 | |
| 12 | func TestSingleInstanceLockRestoresExistingInstance(t *testing.T) { |
| 13 | t.Setenv("REASONIX_HOME", t.TempDir()) |
| 14 | app := NewApp() |
| 15 | lock := singleInstanceLock(app) |
| 16 | |
| 17 | if lock == nil { |
| 18 | t.Fatal("singleInstanceLock returned nil") |
| 19 | } |
| 20 | id := singleInstanceID() |
| 21 | if lock.UniqueId != id { |
| 22 | t.Fatalf("UniqueId = %q, want %q", lock.UniqueId, id) |
| 23 | } |
| 24 | if !strings.HasPrefix(lock.UniqueId, singleInstanceIDPrefix+".") { |
| 25 | t.Fatalf("UniqueId = %q, want prefix %s.", lock.UniqueId, singleInstanceIDPrefix) |
| 26 | } |
| 27 | if lock.OnSecondInstanceLaunch == nil { |
| 28 | t.Fatal("OnSecondInstanceLaunch should restore the existing window") |
| 29 | } |
| 30 | |
| 31 | lock.OnSecondInstanceLaunch(options.SecondInstanceData{}) |
| 32 | } |
| 33 | |
| 34 | func TestSingleInstanceIDScopesToReasonixHome(t *testing.T) { |
| 35 | first := filepath.Join(t.TempDir(), "first") |
| 36 | second := filepath.Join(t.TempDir(), "second") |
| 37 | t.Setenv("REASONIX_HOME", first) |
| 38 | firstID := singleInstanceID() |
| 39 | t.Setenv("REASONIX_HOME", filepath.Join(first, ".")) |
| 40 | if got := singleInstanceID(); got != firstID { |
| 41 | t.Fatalf("same data home produced different ids: %q != %q", got, firstID) |
| 42 | } |
| 43 | t.Setenv("REASONIX_HOME", second) |
| 44 | if got := singleInstanceID(); got == firstID { |
| 45 | t.Fatalf("different data homes produced the same id %q", got) |
| 46 | } |
| 47 | } |
| 48 | |
| 49 | func TestSingleInstanceIDDoesNotSplitReleaseChannels(t *testing.T) { |
| 50 | t.Setenv("REASONIX_HOME", t.TempDir()) |
| 51 | oldChannel := channel |
| 52 | t.Cleanup(func() { channel = oldChannel }) |
| 53 | channel = "stable" |
| 54 | stableID := singleInstanceID() |
| 55 | channel = "canary" |
| 56 | if got := singleInstanceID(); got != stableID { |
| 57 | t.Fatalf("same data home split by channel: stable=%q canary=%q", stableID, got) |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | func TestSingleInstanceIDResolvesMissingHomeThroughSymlink(t *testing.T) { |
| 62 | root := t.TempDir() |
| 63 | realParent := filepath.Join(root, "real") |
| 64 | if err := os.MkdirAll(realParent, 0o755); err != nil { |
| 65 | t.Fatal(err) |
| 66 | } |
| 67 | aliasParent := filepath.Join(root, "alias") |
| 68 | if err := os.Symlink(realParent, aliasParent); err != nil { |
| 69 | t.Skipf("symlink unavailable: %v", err) |
| 70 | } |
| 71 | t.Setenv("REASONIX_HOME", filepath.Join(realParent, "not-created", "home")) |
| 72 | realID := singleInstanceID() |
| 73 | t.Setenv("REASONIX_HOME", filepath.Join(aliasParent, "not-created", "home")) |
| 74 | if got := singleInstanceID(); got != realID { |
| 75 | t.Fatalf("aliased missing data home produced different ids: %q != %q", got, realID) |
| 76 | } |
| 77 | } |
| 78 | |
| 79 | func TestSingleInstanceLockSkipsInDevMode(t *testing.T) { |
| 80 | t.Setenv("REASONIX_DEV", "1") |
| 81 | if lock := singleInstanceLock(NewApp()); lock != nil { |
| 82 | t.Fatalf("singleInstanceLock returned %#v, want nil in dev mode", lock) |
| 83 | } |
| 84 | } |
| 85 |