turbo-editors/turbo-pythonpublic Fork 0
v1.0.2
Commits
Clone
git clone https://git.rickub.com/turbo-editors/turbo-python.git
git clone ssh://git@rickub.com/turbo-editors/turbo-python.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

profile_test.go · 178 lines · 5.4 KBGo Blame HistoryRaw
📦 Turbo Python 6fc62ea k33g 9h ago1package pythonlang_test
2
3import (
4 "os"
5 "path/filepath"
6 "runtime"
7 "slices"
8 "testing"
9
10 "rickub.com/turbo-editors/turbo-core/ui"
11
12 "rickub.com/turbo-editors/turbo-python/internal/pythonlang"
13)
14
15// The slug is load-bearing: four different names are derived from it, and
16// changing it renames a directory in everybody's projects.
17func TestTheSlugNamesTheProjectDirectoryAndEveryEnvironmentVariable(t *testing.T) {
18 p := pythonlang.Profile()
19
20 for _, c := range []struct {
21 what string
22 got string
23 want string
24 }{
25 {"ProjectDir", p.ProjectDir(), ".turbo-python"},
26 {"DirEnvVar", p.DirEnvVar(), "TURBO_PYTHON_DIR"},
27 {"ThemeDirEnvVar", p.ThemeDirEnvVar(), "TURBO_PYTHON_THEME_DIR"},
28 {"SnippetDirEnvVar", p.SnippetDirEnvVar(), "TURBO_PYTHON_SNIPPET_DIR"},
29 } {
30 if c.got != c.want {
31 t.Errorf("%s() = %q, want %q", c.what, c.got, c.want)
32 }
33 }
34}
35
36func TestTheUserDirectoryFollowsItsEnvironmentVariable(t *testing.T) {
37 p := pythonlang.Profile()
38 dir := t.TempDir()
39 t.Setenv(p.DirEnvVar(), dir)
40
41 if got := p.UserDir(); got != dir {
42 t.Errorf("UserDir() = %q, want %q", got, dir)
43 }
44}
45
46// The theme directory's variable names the directory itself, not the one above
47// it — the one asymmetry in the derived paths, and the one worth a test.
48func TestTheThemeDirectoryFollowsItsOwnVariable(t *testing.T) {
49 p := pythonlang.Profile()
50 dir := t.TempDir()
51 t.Setenv(p.ThemeDirEnvVar(), dir)
52
53 if got := p.ThemeDir(); got != dir {
54 t.Errorf("ThemeDir() = %q, want %q", got, dir)
55 }
56}
57
58// P is free because the fixed menus take F, E, S, R, C, O, W, N and H. That the
59// bar agrees is TestTheToolchainMenuIsCalledPython's job, against the real menu
60// bar; this one holds the label itself to what was decided.
61//
62// The key comes back in lower case: a hot key is matched against what the
63// terminal delivers, and Alt-P and Alt-Shift-P are the same menu.
64func TestTheToolchainMenuIsPythonOnP(t *testing.T) {
65 label, hot, _ := ui.SplitHotKey(pythonlang.Profile().ToolsMenu)
66
67 if label != "Python" {
68 t.Errorf("the toolchain menu is labelled %q, want %q", label, "Python")
69 }
70 if hot != 'p' {
71 t.Errorf("its hot key is %q, want %q", hot, 'p')
72 }
73}
74
75func TestTheProjectRootIsLookedForInThreeMarkersInOrder(t *testing.T) {
76 want := []string{"pyproject.toml", "setup.py", "setup.cfg"}
77
78 if got := pythonlang.Profile().RootMarkers; !slices.Equal(got, want) {
79 t.Errorf("RootMarkers = %q, want %q", got, want)
80 }
81}
82
83func TestTheServerIsPylspWithNoArguments(t *testing.T) {
84 server := pythonlang.Profile().Server
85
86 if server.Command != "pylsp" {
87 t.Errorf("Server.Command = %q, want %q", server.Command, "pylsp")
88 }
89 if len(server.Args) != 0 {
90 t.Errorf("Server.Args = %q, want none", server.Args)
91 }
92 if server.InstallHint == "" {
93 t.Error("Server.InstallHint is empty; a missing server would be reported with no way out")
94 }
95}
96
97// An active environment is the most specific answer there is, so it goes first:
98// a server installed into this project's environment must win over one the user
99// installed years ago.
100func TestAnActiveVirtualEnvironmentIsTheFirstPlaceLookedAfterPath(t *testing.T) {
101 env := t.TempDir()
102 t.Setenv("VIRTUAL_ENV", env)
103
104 dirs := pythonlang.ServerDirs()
105
106 if len(dirs) == 0 || dirs[0] != filepath.Join(env, "bin") {
107 t.Errorf("ServerDirs() = %q, want %q first", dirs, filepath.Join(env, "bin"))
108 }
109}
110
111func TestNoActiveEnvironmentContributesNothing(t *testing.T) {
112 t.Setenv("VIRTUAL_ENV", "")
113
114 if got := pythonlang.VirtualEnvBinDir(); got != "" {
115 t.Errorf("VirtualEnvBinDir() = %q with VIRTUAL_ENV unset, want empty", got)
116 }
117}
118
119func TestPyenvIsLookedForUnderItsOwnRootWhenOneIsSet(t *testing.T) {
120 root := t.TempDir()
121 t.Setenv("PYENV_ROOT", root)
122
123 if got, want := pythonlang.PyenvShimDir(), filepath.Join(root, "shims"); got != want {
124 t.Errorf("PyenvShimDir() = %q, want %q", got, want)
125 }
126}
127
128func TestPyenvFallsBackToTheHomeDirectory(t *testing.T) {
129 home := useTemporaryHome(t)
130 t.Setenv("PYENV_ROOT", "")
131
132 if got, want := pythonlang.PyenvShimDir(), filepath.Join(home, ".pyenv", "shims"); got != want {
133 t.Errorf("PyenvShimDir() = %q, want %q", got, want)
134 }
135}
136
137// The macOS user-scripts directory carries a version number nobody can predict,
138// so it is read off the disk. A machine with no such directory — every Linux
139// one — must contribute nothing rather than a path that cannot exist.
140func TestTheMacOSUserScriptDirectoriesAreReadRatherThanGuessed(t *testing.T) {
141 home := useTemporaryHome(t)
142
143 if got := pythonlang.FrameworkScriptDirs(); len(got) != 0 {
144 t.Fatalf("FrameworkScriptDirs() = %q with no Library/Python, want none", got)
145 }
146
147 makeDir(t, filepath.Join(home, "Library", "Python", "3.9", "bin"))
148 makeDir(t, filepath.Join(home, "Library", "Python", "3.13", "bin"))
149
150 want := []string{
151 filepath.Join(home, "Library", "Python", "3.13", "bin"),
152 filepath.Join(home, "Library", "Python", "3.9", "bin"),
153 }
154 if got := pythonlang.FrameworkScriptDirs(); !slices.Equal(got, want) {
155 t.Errorf("FrameworkScriptDirs() = %q, want %q", got, want)
156 }
157}
158
159// useTemporaryHome points the home directory at an empty one, so that the tests
160// never read the directories of whoever is running them.
161func useTemporaryHome(t *testing.T) string {
162 t.Helper()
163 if runtime.GOOS == "windows" {
164 t.Skip("the home directory is not read from HOME on Windows")
165 }
166
167 home := t.TempDir()
168 t.Setenv("HOME", home)
169 return home
170}
171
172// makeDir creates a directory and every parent it needs.
173func makeDir(t *testing.T, path string) {
174 t.Helper()
175 if err := os.MkdirAll(path, 0o755); err != nil {
176 t.Fatalf("creating %s: %v", path, err)
177 }
178}