1// Copyright (c) 2013-2014 The btcsuite developers
2// Use of this source code is governed by an ISC
3// license that can be found in the LICENSE file.
4
5package btcutil_test
6
7import (
8	"os"
9	"os/user"
10	"path/filepath"
11	"runtime"
12	"testing"
13	"unicode"
14
15	"github.com/btcsuite/btcutil"
16)
17
18// TestAppDataDir tests the API for AppDataDir to ensure it gives expected
19// results for various operating systems.
20func TestAppDataDir(t *testing.T) {
21	// App name plus upper and lowercase variants.
22	appName := "myapp"
23	appNameUpper := string(unicode.ToUpper(rune(appName[0]))) + appName[1:]
24	appNameLower := string(unicode.ToLower(rune(appName[0]))) + appName[1:]
25
26	// When we're on Windows, set the expected local and roaming directories
27	// per the environment vars.  When we aren't on Windows, the function
28	// should return the current directory when forced to provide the
29	// Windows path since the environment variables won't exist.
30	winLocal := "."
31	winRoaming := "."
32	if runtime.GOOS == "windows" {
33		localAppData := os.Getenv("LOCALAPPDATA")
34		roamingAppData := os.Getenv("APPDATA")
35		if localAppData == "" {
36			localAppData = roamingAppData
37		}
38		winLocal = filepath.Join(localAppData, appNameUpper)
39		winRoaming = filepath.Join(roamingAppData, appNameUpper)
40	}
41
42	// Get the home directory to use for testing expected results.
43	var homeDir string
44	usr, err := user.Current()
45	if err != nil {
46		t.Errorf("user.Current: %v", err)
47		return
48	}
49	homeDir = usr.HomeDir
50
51	// Mac app data directory.
52	macAppData := filepath.Join(homeDir, "Library", "Application Support")
53
54	tests := []struct {
55		goos    string
56		appName string
57		roaming bool
58		want    string
59	}{
60		// Various combinations of application name casing, leading
61		// period, operating system, and roaming flags.
62		{"windows", appNameLower, false, winLocal},
63		{"windows", appNameUpper, false, winLocal},
64		{"windows", "." + appNameLower, false, winLocal},
65		{"windows", "." + appNameUpper, false, winLocal},
66		{"windows", appNameLower, true, winRoaming},
67		{"windows", appNameUpper, true, winRoaming},
68		{"windows", "." + appNameLower, true, winRoaming},
69		{"windows", "." + appNameUpper, true, winRoaming},
70		{"linux", appNameLower, false, filepath.Join(homeDir, "."+appNameLower)},
71		{"linux", appNameUpper, false, filepath.Join(homeDir, "."+appNameLower)},
72		{"linux", "." + appNameLower, false, filepath.Join(homeDir, "."+appNameLower)},
73		{"linux", "." + appNameUpper, false, filepath.Join(homeDir, "."+appNameLower)},
74		{"darwin", appNameLower, false, filepath.Join(macAppData, appNameUpper)},
75		{"darwin", appNameUpper, false, filepath.Join(macAppData, appNameUpper)},
76		{"darwin", "." + appNameLower, false, filepath.Join(macAppData, appNameUpper)},
77		{"darwin", "." + appNameUpper, false, filepath.Join(macAppData, appNameUpper)},
78		{"openbsd", appNameLower, false, filepath.Join(homeDir, "."+appNameLower)},
79		{"openbsd", appNameUpper, false, filepath.Join(homeDir, "."+appNameLower)},
80		{"openbsd", "." + appNameLower, false, filepath.Join(homeDir, "."+appNameLower)},
81		{"openbsd", "." + appNameUpper, false, filepath.Join(homeDir, "."+appNameLower)},
82		{"freebsd", appNameLower, false, filepath.Join(homeDir, "."+appNameLower)},
83		{"freebsd", appNameUpper, false, filepath.Join(homeDir, "."+appNameLower)},
84		{"freebsd", "." + appNameLower, false, filepath.Join(homeDir, "."+appNameLower)},
85		{"freebsd", "." + appNameUpper, false, filepath.Join(homeDir, "."+appNameLower)},
86		{"netbsd", appNameLower, false, filepath.Join(homeDir, "."+appNameLower)},
87		{"netbsd", appNameUpper, false, filepath.Join(homeDir, "."+appNameLower)},
88		{"netbsd", "." + appNameLower, false, filepath.Join(homeDir, "."+appNameLower)},
89		{"netbsd", "." + appNameUpper, false, filepath.Join(homeDir, "."+appNameLower)},
90		{"plan9", appNameLower, false, filepath.Join(homeDir, appNameLower)},
91		{"plan9", appNameUpper, false, filepath.Join(homeDir, appNameLower)},
92		{"plan9", "." + appNameLower, false, filepath.Join(homeDir, appNameLower)},
93		{"plan9", "." + appNameUpper, false, filepath.Join(homeDir, appNameLower)},
94		{"unrecognized", appNameLower, false, filepath.Join(homeDir, "."+appNameLower)},
95		{"unrecognized", appNameUpper, false, filepath.Join(homeDir, "."+appNameLower)},
96		{"unrecognized", "." + appNameLower, false, filepath.Join(homeDir, "."+appNameLower)},
97		{"unrecognized", "." + appNameUpper, false, filepath.Join(homeDir, "."+appNameLower)},
98
99		// No application name provided, so expect current directory.
100		{"windows", "", false, "."},
101		{"windows", "", true, "."},
102		{"linux", "", false, "."},
103		{"darwin", "", false, "."},
104		{"openbsd", "", false, "."},
105		{"freebsd", "", false, "."},
106		{"netbsd", "", false, "."},
107		{"plan9", "", false, "."},
108		{"unrecognized", "", false, "."},
109
110		// Single dot provided for application name, so expect current
111		// directory.
112		{"windows", ".", false, "."},
113		{"windows", ".", true, "."},
114		{"linux", ".", false, "."},
115		{"darwin", ".", false, "."},
116		{"openbsd", ".", false, "."},
117		{"freebsd", ".", false, "."},
118		{"netbsd", ".", false, "."},
119		{"plan9", ".", false, "."},
120		{"unrecognized", ".", false, "."},
121	}
122
123	t.Logf("Running %d tests", len(tests))
124	for i, test := range tests {
125		ret := btcutil.TstAppDataDir(test.goos, test.appName, test.roaming)
126		if ret != test.want {
127			t.Errorf("appDataDir #%d (%s) does not match - "+
128				"expected got %s, want %s", i, test.goos, ret,
129				test.want)
130			continue
131		}
132	}
133}
134