|
4 | 4 | let(:leeway) { RUBY_VERSION < '3.2.0' ? 0 : 3 } |
5 | 5 | let(:program) { 'completely-test' } |
6 | 6 | let(:script_path) { 'completions.bash' } |
7 | | - let(:targets) { subject.target_directories.map { |dir| "#{dir}/#{program}" } } |
8 | | - let(:install_command) do |
9 | | - %W[sudo cp #{subject.script_path} #{subject.target_path}] |
10 | | - end |
11 | | - |
12 | | - let(:uninstall_command) do |
13 | | - %w[sudo rm -f] + targets |
14 | | - end |
| 7 | + let(:target_path) { "#{Dir.home}/.local/share/bash-completion/completions/#{program}" } |
| 8 | + let(:install_command) { %W[cp #{subject.script_path} #{subject.target_path}] } |
| 9 | + let(:uninstall_command) { %W[rm -f #{subject.target_path}] } |
15 | 10 |
|
16 | 11 | describe '::from_io' do |
17 | 12 | subject { described_class.from_io program:, io: } |
|
33 | 28 | end |
34 | 29 | end |
35 | 30 |
|
36 | | - describe '#target_directories' do |
37 | | - it 'returns an array of potential completion directories' do |
38 | | - expect(subject.target_directories).to be_an Array |
39 | | - expect(subject.target_directories.size).to eq 4 |
| 31 | + describe '#target_path' do |
| 32 | + it 'returns a user-level target path' do |
| 33 | + expect(subject.target_path).to eq target_path |
40 | 34 | end |
41 | | - end |
42 | 35 |
|
43 | | - describe '#target_path' do |
44 | | - it 'returns the first matching path' do |
45 | | - expect(subject.target_path) |
46 | | - .to eq '/usr/share/bash-completion/completions/completely-test' |
| 36 | + context 'when BASH_COMPLETION_USER_DIR is set' do |
| 37 | + around do |example| |
| 38 | + original = ENV['BASH_COMPLETION_USER_DIR'] |
| 39 | + ENV['BASH_COMPLETION_USER_DIR'] = '/tmp/completely-user-dir' |
| 40 | + example.run |
| 41 | + ensure |
| 42 | + ENV['BASH_COMPLETION_USER_DIR'] = original |
| 43 | + end |
| 44 | + |
| 45 | + it 'uses BASH_COMPLETION_USER_DIR/completions' do |
| 46 | + expect(subject.target_path).to eq '/tmp/completely-user-dir/completions/completely-test' |
| 47 | + end |
47 | 48 | end |
48 | | - end |
49 | 49 |
|
50 | | - describe '#install_command' do |
51 | | - it 'returns a copy command as an array' do |
52 | | - expect(subject.install_command) |
53 | | - .to eq %w[sudo cp completions.bash /usr/share/bash-completion/completions/completely-test] |
| 50 | + context 'when XDG_DATA_HOME is set' do |
| 51 | + around do |example| |
| 52 | + original = ENV['XDG_DATA_HOME'] |
| 53 | + ENV['XDG_DATA_HOME'] = '/tmp/completely-xdg' |
| 54 | + example.run |
| 55 | + ensure |
| 56 | + ENV['XDG_DATA_HOME'] = original |
| 57 | + end |
| 58 | + |
| 59 | + it 'uses XDG_DATA_HOME/bash-completion/completions' do |
| 60 | + expect(subject.target_path).to eq '/tmp/completely-xdg/bash-completion/completions/completely-test' |
| 61 | + end |
54 | 62 | end |
55 | 63 |
|
56 | | - context 'when the user is root' do |
57 | | - it 'returns the command without sudo' do |
58 | | - allow(subject).to receive(:root_user?).and_return true |
| 64 | + context 'when BASH_COMPLETION_USER_DIR has multiple entries' do |
| 65 | + around do |example| |
| 66 | + original = ENV['BASH_COMPLETION_USER_DIR'] |
| 67 | + ENV['BASH_COMPLETION_USER_DIR'] = ':/tmp/completely-first:/tmp/completely-second' |
| 68 | + example.run |
| 69 | + ensure |
| 70 | + ENV['BASH_COMPLETION_USER_DIR'] = original |
| 71 | + end |
59 | 72 |
|
60 | | - expect(subject.install_command) |
61 | | - .to eq %w[cp completions.bash /usr/share/bash-completion/completions/completely-test] |
| 73 | + it 'uses the first non-empty entry' do |
| 74 | + expect(subject.target_path).to eq '/tmp/completely-first/completions/completely-test' |
62 | 75 | end |
63 | 76 | end |
64 | 77 | end |
65 | 78 |
|
| 79 | + describe '#install_command' do |
| 80 | + it 'returns a copy command as an array' do |
| 81 | + expect(subject.install_command) |
| 82 | + .to eq %W[cp completions.bash #{target_path}] |
| 83 | + end |
| 84 | + end |
| 85 | + |
66 | 86 | describe '#install_command_string' do |
67 | 87 | it 'returns the install command as a string' do |
68 | 88 | expect(subject.install_command_string).to eq subject.install_command.join(' ') |
|
71 | 91 |
|
72 | 92 | describe '#uninstall_command' do |
73 | 93 | it 'returns an rm command as an array' do |
74 | | - expect(subject.uninstall_command).to eq %w[sudo rm -f] + targets |
75 | | - end |
76 | | - |
77 | | - context 'when the user is root' do |
78 | | - it 'returns the command without sudo' do |
79 | | - allow(subject).to receive(:root_user?).and_return true |
80 | | - |
81 | | - expect(subject.uninstall_command).to eq %w[rm -f] + targets |
82 | | - end |
| 94 | + expect(subject.uninstall_command).to eq %W[rm -f #{target_path}] |
83 | 95 | end |
84 | 96 | end |
85 | 97 |
|
|
95 | 107 |
|
96 | 108 | before do |
97 | 109 | allow(subject).to receive_messages(script_path: existing_file, target_path: missing_file) |
98 | | - end |
99 | | - |
100 | | - context 'when the completions_path cannot be found' do |
101 | | - it 'raises an error' do |
102 | | - allow(subject).to receive(:completions_path).and_return nil |
103 | | - |
104 | | - expect { subject.install }.to raise_approval('installer/install-no-dir') |
105 | | - .diff(leeway) |
106 | | - end |
| 110 | + allow(FileUtils).to receive(:mkdir_p) |
107 | 111 | end |
108 | 112 |
|
109 | 113 | context 'when the script cannot be found' do |
|
128 | 132 | it 'proceeds to install' do |
129 | 133 | allow(subject).to receive(:target_path).and_return existing_file |
130 | 134 |
|
| 135 | + expect(FileUtils).to receive(:mkdir_p) |
131 | 136 | expect(subject).to receive(:system).with(*install_command) |
132 | 137 |
|
133 | 138 | subject.install force: true |
|
138 | 143 | it 'proceeds to install' do |
139 | 144 | allow(subject).to receive(:target_path).and_return missing_file |
140 | 145 |
|
| 146 | + expect(FileUtils).to receive(:mkdir_p) |
141 | 147 | expect(subject).to receive(:system).with(*install_command) |
142 | 148 |
|
143 | 149 | subject.install |
|
0 commit comments