1" Test for $HOME on Windows.
2
3if !has('win32')
4  finish
5endif
6
7let s:env = {}
8
9func s:restore_env()
10  for i in keys(s:env)
11    exe 'let ' . i . '=s:env["' . i . '"]'
12  endfor
13endfunc
14
15func s:save_env(...)
16  for i in a:000
17    exe 'let s:env["' . i . '"]=' . i
18  endfor
19endfunc
20
21func s:unlet_env(...)
22  for i in a:000
23    exe 'let ' . i . '=""'
24  endfor
25endfunc
26
27func CheckHomeIsMissingFromSubprocessEnvironment()
28  silent! let out = system('set')
29  let env = filter(split(out, "\n"), 'v:val=~"^HOME="')
30  call assert_equal(0, len(env))
31endfunc
32
33func CheckHomeIsInSubprocessEnvironment(exp)
34  silent! let out = system('set')
35  let env = filter(split(out, "\n"), 'v:val=~"^HOME="')
36  let home = len(env) == 0 ? "" : substitute(env[0], '[^=]\+=', '', '')
37  call assert_equal(a:exp, home)
38endfunc
39
40func CheckHome(exp, ...)
41  call assert_equal(a:exp, $HOME)
42  call assert_equal(a:exp, expand('~', ':p'))
43  if !a:0
44    call CheckHomeIsMissingFromSubprocessEnvironment()
45  else
46    call CheckHomeIsInSubprocessEnvironment(a:1)
47  endif
48endfunc
49
50func Test_WindowsHome()
51  command! -nargs=* SaveEnv call <SID>save_env(<f-args>)
52  command! -nargs=* RestoreEnv call <SID>restore_env()
53  command! -nargs=* UnletEnv call <SID>unlet_env(<f-args>)
54  set noshellslash
55
56  let save_home = $HOME
57  SaveEnv $USERPROFILE $HOMEDRIVE $HOMEPATH
58  try
59    " Normal behavior: use $HOMEDRIVE and $HOMEPATH, ignore $USERPROFILE
60    let $USERPROFILE = 'unused'
61    let $HOMEDRIVE = 'C:'
62    let $HOMEPATH = '\foobar'
63    let $HOME = ''  " Force recomputing "homedir"
64    call CheckHome('C:\foobar')
65
66    " Same, but with $HOMEPATH not set
67    UnletEnv $HOMEPATH
68    let $HOME = ''  " Force recomputing "homedir"
69    call CheckHome('C:\')
70
71    " Use $USERPROFILE if $HOMEPATH and $HOMEDRIVE are empty
72    UnletEnv $HOMEDRIVE $HOMEPATH
73    let $USERPROFILE = 'C:\foo'
74    let $HOME = ''  " Force recomputing "homedir"
75    call CheckHome('C:\foo')
76
77    " If $HOME is set the others don't matter
78    let $HOME = 'C:\bar'
79    let $USERPROFILE = 'unused'
80    let $HOMEDRIVE = 'unused'
81    let $HOMEPATH = 'unused'
82    call CheckHome('C:\bar', 'C:\bar')
83
84    " If $HOME contains %USERPROFILE% it is expanded
85    let $USERPROFILE = 'C:\foo'
86    let $HOME = '%USERPROFILE%\bar'
87    let $HOMEDRIVE = 'unused'
88    let $HOMEPATH = 'unused'
89    call CheckHome('C:\foo\bar', '%USERPROFILE%\bar')
90
91    " Invalid $HOME is kept
92    let $USERPROFILE = 'C:\foo'
93    let $HOME = '%USERPROFILE'
94    let $HOMEDRIVE = 'unused'
95    let $HOMEPATH = 'unused'
96    call CheckHome('%USERPROFILE', '%USERPROFILE')
97
98    " %USERPROFILE% not at start of $HOME is not expanded
99    let $USERPROFILE = 'unused'
100    let $HOME = 'C:\%USERPROFILE%'
101    let $HOMEDRIVE = 'unused'
102    let $HOMEPATH = 'unused'
103    call CheckHome('C:\%USERPROFILE%', 'C:\%USERPROFILE%')
104
105    if has('channel')
106      RestoreEnv
107      let $HOME = save_home
108      let env = ''
109      let job = job_start('cmd /c set', {'out_cb': {ch,x->[env,execute('let env=x')]}})
110      sleep 1
111      let env = filter(split(env, "\n"), 'v:val=="HOME"')
112      let home = len(env) == 0 ? "" : env[0]
113      call assert_equal('', home)
114    endif
115  finally
116    RestoreEnv
117    delcommand SaveEnv
118    delcommand RestoreEnv
119    delcommand UnletEnv
120  endtry
121endfunc
122