cuprum-cli 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +43 -0
- data/README.md +10 -0
- data/lib/cuprum/cli/argument.rb +2 -2
- data/lib/cuprum/cli/command.rb +2 -4
- data/lib/cuprum/cli/commands/ci/rspec_each_command.rb +34 -8
- data/lib/cuprum/cli/commands/ci.rb +8 -0
- data/lib/cuprum/cli/commands/file/new_command.rb +42 -49
- data/lib/cuprum/cli/commands/file.rb +8 -5
- data/lib/cuprum/cli/dependencies/clock/mock.rb +28 -0
- data/lib/cuprum/cli/dependencies/clock.rb +29 -0
- data/lib/cuprum/cli/dependencies/file_system/mock.rb +150 -18
- data/lib/cuprum/cli/dependencies/file_system.rb +145 -10
- data/lib/cuprum/cli/dependencies.rb +2 -0
- data/lib/cuprum/cli/errors.rb +0 -1
- data/lib/cuprum/cli/{commands/file/generate_file.rb → files/create_file.rb} +6 -48
- data/lib/cuprum/cli/{commands/file → files/engines}/render_erb.rb +6 -6
- data/lib/cuprum/cli/files/engines.rb +76 -0
- data/lib/cuprum/cli/{errors/files → files/errors}/file_not_writeable.rb +3 -3
- data/lib/cuprum/cli/files/errors/generator_error.rb +46 -0
- data/lib/cuprum/cli/{errors/files → files/errors}/missing_parameter.rb +5 -5
- data/lib/cuprum/cli/{errors/files → files/errors}/missing_template.rb +3 -3
- data/lib/cuprum/cli/{errors/files → files/errors}/template_error.rb +3 -3
- data/lib/cuprum/cli/files/errors.rb +19 -0
- data/lib/cuprum/cli/files/generator.rb +431 -0
- data/lib/cuprum/cli/files/generators/basic_generator.rb +15 -0
- data/lib/cuprum/cli/files/generators/rspec_generator.rb +19 -0
- data/lib/cuprum/cli/files/generators/ruby_generator.rb +32 -0
- data/lib/cuprum/cli/files/generators.rb +25 -0
- data/lib/cuprum/cli/files/template.rb +62 -0
- data/lib/cuprum/cli/files/templates/basic_template.rb +39 -0
- data/lib/cuprum/cli/files/templates/file_template.rb +60 -0
- data/lib/cuprum/cli/files/templates/string_template.rb +29 -0
- data/lib/cuprum/cli/files/templates.rb +59 -0
- data/lib/cuprum/cli/files.rb +18 -0
- data/lib/cuprum/cli/integrations/async/commands/rspec_each_command.rb +32 -0
- data/lib/cuprum/cli/integrations/async/commands.rb +11 -0
- data/lib/cuprum/cli/integrations/async.rb +21 -0
- data/lib/cuprum/cli/integrations/thor/registry.rb +7 -29
- data/lib/cuprum/cli/integrations/thor/task.rb +37 -7
- data/lib/cuprum/cli/metadata.rb +54 -5
- data/lib/cuprum/cli/option.rb +10 -4
- data/lib/cuprum/cli/options/class_methods.rb +19 -1
- data/lib/cuprum/cli/registry.rb +131 -55
- data/lib/cuprum/cli/rspec/deferred/dependencies/file_system_examples.rb +1303 -1001
- data/lib/cuprum/cli/rspec/deferred/generators_examples.rb +112 -0
- data/lib/cuprum/cli/rspec/deferred/metadata_examples.rb +300 -0
- data/lib/cuprum/cli/rspec/deferred/options_examples.rb +8 -2
- data/lib/cuprum/cli/rspec/deferred/registry_examples.rb +343 -108
- data/lib/cuprum/cli/rspec/deferred/templates_examples.rb +183 -0
- data/lib/cuprum/cli/version.rb +1 -1
- data/lib/cuprum/cli.rb +1 -0
- metadata +31 -14
- data/lib/cuprum/cli/commands/file/resolve_template.rb +0 -136
- data/lib/cuprum/cli/commands/file/templates.rb +0 -71
- data/lib/cuprum/cli/errors/files/template_not_resolved.rb +0 -54
- data/lib/cuprum/cli/errors/files.rb +0 -19
- /data/lib/cuprum/cli/{commands/file → files}/templates/rspec.rb.erb +0 -0
- /data/lib/cuprum/cli/{commands/file → files}/templates/ruby.rb.erb +0 -0
|
@@ -9,1457 +9,1759 @@ module Cuprum::Cli::RSpec::Deferred::Dependencies
|
|
|
9
9
|
module FileSystemExamples
|
|
10
10
|
include RSpec::SleepingKingStudios::Deferred::Provider
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
let(:path) { nil }
|
|
12
|
+
define_method :absolute_path? do |path|
|
|
13
|
+
path.start_with?('/')
|
|
14
|
+
end
|
|
16
15
|
|
|
17
|
-
|
|
16
|
+
define_method :qualified_path? do |path|
|
|
17
|
+
path.start_with?('*')
|
|
18
|
+
end
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
deferred_context 'with fixture files and directories' do
|
|
21
|
+
let(:fixtures_path) do
|
|
22
|
+
defined?(super()) ? super() : '.'
|
|
23
|
+
end
|
|
24
|
+
let(:fixtures) do
|
|
25
|
+
{
|
|
26
|
+
'root_dir' => {
|
|
27
|
+
'child_dir' => {},
|
|
28
|
+
'child_file.txt' => 'Contents of root_dir/child_file.txt'
|
|
29
|
+
},
|
|
30
|
+
'root_file.txt' => 'Contents of root_file.txt'
|
|
31
|
+
}
|
|
32
|
+
end
|
|
33
|
+
let(:flattened_fixture_names) do
|
|
34
|
+
[
|
|
35
|
+
'root_dir',
|
|
36
|
+
'root_dir/child_dir',
|
|
37
|
+
'root_dir/child_file.txt',
|
|
38
|
+
'root_file.txt'
|
|
39
|
+
]
|
|
40
|
+
end
|
|
20
41
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
42
|
+
define_method :read_fixture do |path|
|
|
43
|
+
return super(path) if defined?(super(path))
|
|
44
|
+
|
|
45
|
+
fixtures.dig(*path.split(File::SEPARATOR))
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
deferred_examples 'should handle a directory when a file is expected' \
|
|
50
|
+
do |path_parameter = 'path', &block|
|
|
51
|
+
context "when the #{path_parameter.to_s.tr('_', ' ')} is a directory" do
|
|
52
|
+
let(path_parameter) do
|
|
53
|
+
if absolute_path?(super())
|
|
54
|
+
absolute_directory_path
|
|
55
|
+
elsif qualified_path?(super())
|
|
56
|
+
qualified_directory_path
|
|
57
|
+
else
|
|
58
|
+
relative_directory_path
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
let(:error_class) do
|
|
62
|
+
Cuprum::Cli::Dependencies::FileSystem::FileIsADirectoryError
|
|
63
|
+
end
|
|
64
|
+
let(:error_message) do
|
|
65
|
+
"#{error_reason} - file is a directory"
|
|
26
66
|
end
|
|
27
67
|
|
|
28
|
-
it 'should
|
|
29
|
-
expect(
|
|
30
|
-
.to have_aliased_method(:create_directory)
|
|
31
|
-
.as(:make_directory)
|
|
68
|
+
it 'should raise an exception' do
|
|
69
|
+
expect { call_method }.to raise_error(error_class, error_message)
|
|
32
70
|
end
|
|
33
71
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
72
|
+
instance_exec(&block) if block
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
deferred_examples 'should handle a file that already exists' \
|
|
77
|
+
do |path_parameter = 'path', &block|
|
|
78
|
+
context "when the #{path_parameter.to_s.tr('_', ' ')} is a file" do
|
|
79
|
+
let(path_parameter) do
|
|
80
|
+
if absolute_path?(super())
|
|
81
|
+
absolute_file_path
|
|
82
|
+
elsif qualified_path?(super())
|
|
83
|
+
qualified_file_path
|
|
84
|
+
else
|
|
85
|
+
relative_file_path
|
|
37
86
|
end
|
|
87
|
+
end
|
|
88
|
+
let(:error_class) do
|
|
89
|
+
Cuprum::Cli::Dependencies::FileSystem::FileAlreadyExistsError
|
|
90
|
+
end
|
|
91
|
+
let(:error_message) do
|
|
92
|
+
"#{error_reason} - file already exists"
|
|
93
|
+
end
|
|
38
94
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
95
|
+
it 'should raise an exception' do
|
|
96
|
+
expect { call_method }.to raise_error(error_class, error_message)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
instance_exec(&block) if block
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
deferred_examples 'should handle a file when a directory is expected' \
|
|
104
|
+
do |path_parameter = 'path', &block|
|
|
105
|
+
context "when the #{path_parameter.to_s.tr('_', ' ')} is a file" do
|
|
106
|
+
let(path_parameter) do
|
|
107
|
+
if absolute_path?(super())
|
|
108
|
+
absolute_file_path
|
|
109
|
+
elsif qualified_path?(super())
|
|
110
|
+
qualified_file_path
|
|
111
|
+
else
|
|
112
|
+
relative_file_path
|
|
42
113
|
end
|
|
43
114
|
end
|
|
115
|
+
let(:error_class) do
|
|
116
|
+
Cuprum::Cli::Dependencies::FileSystem::DirectoryIsAFileError
|
|
117
|
+
end
|
|
118
|
+
let(:error_message) do
|
|
119
|
+
"#{error_reason} - directory is a file"
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it 'should raise an exception' do
|
|
123
|
+
expect { call_method }.to raise_error(error_class, error_message)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
instance_exec(&block) if block
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
deferred_examples 'should handle a path that includes a file' \
|
|
131
|
+
do |path_parameter = 'path', &block|
|
|
132
|
+
context "when the #{path_parameter.to_s.tr('_', ' ')} includes a file" do
|
|
133
|
+
let(path_parameter) do
|
|
134
|
+
dirname =
|
|
135
|
+
if absolute_path?(super())
|
|
136
|
+
absolute_file_path
|
|
137
|
+
elsif qualified_path?(super())
|
|
138
|
+
qualified_file_path
|
|
139
|
+
else
|
|
140
|
+
relative_file_path
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
File.join(dirname, File.basename(super()))
|
|
144
|
+
end
|
|
145
|
+
let(:error_class) do
|
|
146
|
+
Cuprum::Cli::Dependencies::FileSystem::DirectoryIsAFileError
|
|
147
|
+
end
|
|
148
|
+
let(:error_message) do
|
|
149
|
+
"#{error_reason} - directory is a file"
|
|
150
|
+
end
|
|
44
151
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
152
|
+
it 'should raise an exception' do
|
|
153
|
+
expect { call_method }.to raise_error(error_class, error_message)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
instance_exec(&block) if block
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
deferred_examples 'should handle a path with missing directory' \
|
|
161
|
+
do |path_parameter = 'path', &block|
|
|
162
|
+
parameter_name = path_parameter.to_s.tr('_', ' ')
|
|
163
|
+
|
|
164
|
+
context "when the #{parameter_name} includes a missing directory" do
|
|
165
|
+
let(:error_class) do
|
|
166
|
+
Cuprum::Cli::Dependencies::FileSystem::DirectoryNotFoundError
|
|
167
|
+
end
|
|
168
|
+
let(:error_message) do
|
|
169
|
+
"#{error_reason} - directory not found"
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
context "when the #{parameter_name} is an absolute path" do
|
|
173
|
+
let(path_parameter) do
|
|
174
|
+
File.join(
|
|
175
|
+
absolute_directory_path,
|
|
176
|
+
'missing_directory',
|
|
177
|
+
File.basename(super())
|
|
178
|
+
)
|
|
48
179
|
end
|
|
49
180
|
|
|
50
181
|
it 'should raise an exception' do
|
|
51
|
-
expect {
|
|
52
|
-
.to raise_error ArgumentError, error_message
|
|
182
|
+
expect { call_method }.to raise_error(error_class, error_message)
|
|
53
183
|
end
|
|
184
|
+
|
|
185
|
+
instance_exec(&block) if block
|
|
54
186
|
end
|
|
55
187
|
|
|
56
|
-
|
|
57
|
-
let(
|
|
58
|
-
|
|
188
|
+
context "when the #{parameter_name} is a qualified path" do
|
|
189
|
+
let(path_parameter) do
|
|
190
|
+
File.join(
|
|
191
|
+
qualified_directory_path,
|
|
192
|
+
'missing_directory',
|
|
193
|
+
File.basename(super())
|
|
194
|
+
)
|
|
59
195
|
end
|
|
60
196
|
|
|
61
197
|
it 'should raise an exception' do
|
|
62
|
-
expect {
|
|
63
|
-
.to raise_error ArgumentError, error_message
|
|
198
|
+
expect { call_method }.to raise_error(error_class, error_message)
|
|
64
199
|
end
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
describe 'with an absolute path' do
|
|
68
|
-
let(:base_path) { absolute_directory_path }
|
|
69
|
-
let(:path) { File.join(base_path, 'custom_dir') }
|
|
70
200
|
|
|
71
|
-
|
|
201
|
+
instance_exec(&block) if block
|
|
202
|
+
end
|
|
72
203
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
204
|
+
context "when the #{parameter_name} is a relative path" do
|
|
205
|
+
let(path_parameter) do
|
|
206
|
+
File.join(
|
|
207
|
+
relative_directory_path,
|
|
208
|
+
'missing_directory',
|
|
209
|
+
File.basename(super())
|
|
76
210
|
)
|
|
77
211
|
end
|
|
78
212
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
Cuprum::Cli::Dependencies::FileSystem::DirectoryNotFoundError
|
|
83
|
-
end
|
|
84
|
-
let(:error_message) do
|
|
85
|
-
"unable to create directory #{path} - directory not found"
|
|
86
|
-
end
|
|
213
|
+
it 'should raise an exception' do
|
|
214
|
+
expect { call_method }.to raise_error(error_class, error_message)
|
|
215
|
+
end
|
|
87
216
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
217
|
+
instance_exec(&block) if block
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
end
|
|
92
221
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
.to be == path
|
|
97
|
-
end
|
|
222
|
+
deferred_examples 'should handle a path with missing file' \
|
|
223
|
+
do |path_parameter = 'path', &block|
|
|
224
|
+
parameter_name = path_parameter.to_s.tr('_', ' ')
|
|
98
225
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
226
|
+
context "when the #{parameter_name} includes a missing file" do
|
|
227
|
+
let(:error_class) do
|
|
228
|
+
Cuprum::Cli::Dependencies::FileSystem::FileNotFoundError
|
|
229
|
+
end
|
|
230
|
+
let(:error_message) do
|
|
231
|
+
"#{error_reason} - file not found"
|
|
232
|
+
end
|
|
104
233
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
subject.create_directory(path, recursive: true)
|
|
108
|
-
end
|
|
234
|
+
context "when the #{parameter_name} is an absolute path" do
|
|
235
|
+
let(path_parameter) { invalid_absolute_path }
|
|
109
236
|
|
|
110
|
-
|
|
111
|
-
|
|
237
|
+
it 'should raise an exception' do
|
|
238
|
+
expect { call_method }.to raise_error(error_class, error_message)
|
|
239
|
+
end
|
|
112
240
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
Cuprum::Cli::Dependencies::FileSystem::DirectoryIsAFileError
|
|
116
|
-
end
|
|
117
|
-
let(:error_message) do
|
|
118
|
-
"unable to create directory #{path} - directory is a file"
|
|
119
|
-
end
|
|
120
|
-
let(:file_path) { File.join(base_path, 'custom_dir') }
|
|
241
|
+
instance_exec(&block) if block
|
|
242
|
+
end
|
|
121
243
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
end
|
|
244
|
+
context "when the #{parameter_name} is a qualified path" do
|
|
245
|
+
let(path_parameter) { invalid_qualified_path }
|
|
125
246
|
|
|
126
|
-
|
|
247
|
+
it 'should raise an exception' do
|
|
248
|
+
expect { call_method }.to raise_error(error_class, error_message)
|
|
249
|
+
end
|
|
127
250
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
.to raise_error(error_class, error_message)
|
|
131
|
-
end
|
|
251
|
+
instance_exec(&block) if block
|
|
252
|
+
end
|
|
132
253
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
end
|
|
139
|
-
end
|
|
254
|
+
context "when the #{parameter_name} is a relative path" do
|
|
255
|
+
let(path_parameter) { invalid_relative_path }
|
|
256
|
+
|
|
257
|
+
it 'should raise an exception' do
|
|
258
|
+
expect { call_method }.to raise_error(error_class, error_message)
|
|
140
259
|
end
|
|
141
260
|
|
|
142
|
-
|
|
143
|
-
|
|
261
|
+
instance_exec(&block) if block
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
end
|
|
144
265
|
|
|
145
|
-
|
|
146
|
-
|
|
266
|
+
deferred_examples 'should validate the path' \
|
|
267
|
+
do |path_parameter = 'path', &block|
|
|
268
|
+
describe "with #{path_parameter.to_s.tr('_', ' ')}: nil" do
|
|
269
|
+
let(path_parameter) { nil }
|
|
270
|
+
let(:error_message) do
|
|
271
|
+
tools
|
|
272
|
+
.assertions
|
|
273
|
+
.error_message_for('presence', as: path_parameter)
|
|
274
|
+
end
|
|
147
275
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
276
|
+
it 'should raise an exception' do
|
|
277
|
+
expect { call_method }
|
|
278
|
+
.to raise_error ArgumentError, error_message
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
instance_exec(&block) if block
|
|
282
|
+
end
|
|
155
283
|
|
|
156
|
-
|
|
284
|
+
describe "with #{path_parameter.to_s.tr('_', ' ')}: an Object" do
|
|
285
|
+
let(path_parameter) { Object.new.freeze }
|
|
286
|
+
let(:error_message) do
|
|
287
|
+
"#{path_parameter} is not an instance of String"
|
|
288
|
+
end
|
|
157
289
|
|
|
158
|
-
|
|
290
|
+
it 'should raise an exception' do
|
|
291
|
+
expect { call_method }
|
|
292
|
+
.to raise_error ArgumentError, error_message
|
|
293
|
+
end
|
|
159
294
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
.to raise_error(error_class, error_message)
|
|
163
|
-
end
|
|
295
|
+
instance_exec(&block) if block
|
|
296
|
+
end
|
|
164
297
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
298
|
+
describe "with #{path_parameter.to_s.tr('_', ' ')}: an empty String" do
|
|
299
|
+
let(path_parameter) { '' }
|
|
300
|
+
let(:error_message) do
|
|
301
|
+
tools
|
|
302
|
+
.assertions
|
|
303
|
+
.error_message_for('presence', as: path_parameter)
|
|
171
304
|
end
|
|
172
305
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
306
|
+
it 'should raise an exception' do
|
|
307
|
+
expect { call_method }
|
|
308
|
+
.to raise_error ArgumentError, error_message
|
|
309
|
+
end
|
|
176
310
|
|
|
177
|
-
|
|
311
|
+
instance_exec(&block) if block
|
|
312
|
+
end
|
|
313
|
+
end
|
|
178
314
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
315
|
+
deferred_examples 'should validate the file or path' \
|
|
316
|
+
do |path_parameter = 'path', &block|
|
|
317
|
+
describe "with #{path_parameter.to_s.tr('_', ' ')}: nil" do
|
|
318
|
+
let(path_parameter) { nil }
|
|
319
|
+
let(:error_message) do
|
|
320
|
+
tools
|
|
321
|
+
.assertions
|
|
322
|
+
.error_message_for('presence', as: path_parameter)
|
|
323
|
+
end
|
|
187
324
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
325
|
+
it 'should raise an exception' do
|
|
326
|
+
expect { call_method }
|
|
327
|
+
.to raise_error ArgumentError, error_message
|
|
328
|
+
end
|
|
192
329
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
expect(subject.create_directory(path, recursive: true))
|
|
196
|
-
.to be == path
|
|
197
|
-
end
|
|
330
|
+
instance_exec(&block) if block
|
|
331
|
+
end
|
|
198
332
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
333
|
+
describe "with #{path_parameter.to_s.tr('_', ' ')}: an Object" do
|
|
334
|
+
let(path_parameter) { Object.new.freeze }
|
|
335
|
+
let(:error_message) do
|
|
336
|
+
"#{path_parameter} is not a String or IO stream"
|
|
337
|
+
end
|
|
204
338
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
339
|
+
it 'should raise an exception' do
|
|
340
|
+
expect { call_method }
|
|
341
|
+
.to raise_error ArgumentError, error_message
|
|
342
|
+
end
|
|
209
343
|
|
|
210
|
-
|
|
211
|
-
|
|
344
|
+
instance_exec(&block) if block
|
|
345
|
+
end
|
|
212
346
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
let(:file_path) { File.join(base_path, 'custom_dir') }
|
|
347
|
+
describe "with #{path_parameter.to_s.tr('_', ' ')}: an empty String" do
|
|
348
|
+
let(path_parameter) { '' }
|
|
349
|
+
let(:error_message) do
|
|
350
|
+
tools
|
|
351
|
+
.assertions
|
|
352
|
+
.error_message_for('presence', as: path_parameter)
|
|
353
|
+
end
|
|
221
354
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
355
|
+
it 'should raise an exception' do
|
|
356
|
+
expect { call_method }
|
|
357
|
+
.to raise_error ArgumentError, error_message
|
|
358
|
+
end
|
|
225
359
|
|
|
226
|
-
|
|
360
|
+
instance_exec(&block) if block
|
|
361
|
+
end
|
|
362
|
+
end
|
|
227
363
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
364
|
+
deferred_examples 'should implement the file_system dependency' do
|
|
365
|
+
let(:invalid_absolute_path) do
|
|
366
|
+
defined?(super()) ? super() : '/invalid-absolute-path'
|
|
367
|
+
end
|
|
368
|
+
let(:invalid_qualified_path) do
|
|
369
|
+
defined?(super()) ? super() : '../invalid-qualified-path'
|
|
370
|
+
end
|
|
371
|
+
let(:invalid_relative_path) do
|
|
372
|
+
defined?(super()) ? super() : 'invalid-relative-path'
|
|
373
|
+
end
|
|
232
374
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
375
|
+
describe '#copy_file' do
|
|
376
|
+
deferred_context 'with destination_path: an absolute path' do
|
|
377
|
+
let(:destination_path) do
|
|
378
|
+
path = absolute_file_path
|
|
379
|
+
dirname = File.dirname(path)
|
|
380
|
+
basename = File.basename(path)
|
|
381
|
+
extname = File.extname(path)
|
|
382
|
+
|
|
383
|
+
File.join(
|
|
384
|
+
dirname,
|
|
385
|
+
basename.sub(/#{extname}\z/, "_copy#{extname}")
|
|
386
|
+
)
|
|
387
|
+
end
|
|
388
|
+
let(:path) { destination_path }
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
deferred_context 'with destination_path: a relative path' do
|
|
392
|
+
let(:destination_path) do
|
|
393
|
+
path = relative_file_path
|
|
394
|
+
dirname = File.dirname(path)
|
|
395
|
+
basename = File.basename(path)
|
|
396
|
+
extname = File.extname(path)
|
|
397
|
+
|
|
398
|
+
File.join(
|
|
399
|
+
dirname,
|
|
400
|
+
basename.sub(/#{extname}\z/, "_copy#{extname}")
|
|
401
|
+
)
|
|
402
|
+
end
|
|
403
|
+
let(:path) { destination_path }
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
deferred_context 'with destination_path: a qualified path' do
|
|
407
|
+
let(:destination_path) do
|
|
408
|
+
path =
|
|
409
|
+
if defined?(root_path) && root_path
|
|
410
|
+
"../#{root_path.split(File::SEPARATOR).last}/" \
|
|
411
|
+
"#{File.basename(qualified_file_path)}"
|
|
412
|
+
else
|
|
413
|
+
qualified_file_path
|
|
238
414
|
end
|
|
239
|
-
|
|
415
|
+
|
|
416
|
+
dirname = File.dirname(path)
|
|
417
|
+
basename = File.basename(path)
|
|
418
|
+
extname = File.extname(path)
|
|
419
|
+
|
|
420
|
+
File.join(
|
|
421
|
+
dirname,
|
|
422
|
+
basename.sub(/#{extname}\z/, "_copy#{extname}")
|
|
423
|
+
)
|
|
240
424
|
end
|
|
425
|
+
let(:path) { destination_path }
|
|
426
|
+
end
|
|
241
427
|
|
|
242
|
-
|
|
243
|
-
|
|
428
|
+
deferred_examples 'should not copy the file' do
|
|
429
|
+
it 'should not copy the file' do
|
|
430
|
+
expect { safe_copy_file }
|
|
431
|
+
.not_to(change { subject.file?(destination_path) })
|
|
432
|
+
end
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
deferred_examples 'should copy the file' do
|
|
436
|
+
it 'should not change the source file', :aggregate_failures do
|
|
437
|
+
copy_file
|
|
244
438
|
|
|
245
|
-
|
|
439
|
+
expect(subject.file?(source_path)).to be true
|
|
440
|
+
expect(subject.read_file(source_path)).to eq expected_contents
|
|
246
441
|
end
|
|
247
442
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
Cuprum::Cli::Dependencies::FileSystem::DirectoryIsAFileError
|
|
251
|
-
end
|
|
252
|
-
let(:error_message) do
|
|
253
|
-
"unable to create directory #{path} - directory is a file"
|
|
254
|
-
end
|
|
443
|
+
it 'should create the destination file', :aggregate_failures do
|
|
444
|
+
copy_file
|
|
255
445
|
|
|
256
|
-
|
|
446
|
+
expect(subject.file?(destination_path)).to be true
|
|
447
|
+
expect(subject.read_file(destination_path))
|
|
448
|
+
.to eq expected_contents
|
|
449
|
+
end
|
|
257
450
|
|
|
258
|
-
|
|
451
|
+
describe 'with a transform block' do
|
|
452
|
+
let(:block) { ->(data) { data.upcase } } # rubocop:disable Style/SymbolProc
|
|
453
|
+
let(:expected_contents) { super().upcase }
|
|
259
454
|
|
|
260
|
-
it 'should
|
|
261
|
-
|
|
262
|
-
.to raise_error(error_class, error_message)
|
|
263
|
-
end
|
|
455
|
+
it 'should create the destination file', :aggregate_failures do
|
|
456
|
+
copy_file
|
|
264
457
|
|
|
265
|
-
|
|
266
|
-
subject.
|
|
267
|
-
|
|
268
|
-
expect(subject.directory?(path)).to be false
|
|
458
|
+
expect(subject.file?(destination_path)).to be true
|
|
459
|
+
expect(subject.read_file(destination_path))
|
|
460
|
+
.to eq expected_contents
|
|
269
461
|
end
|
|
270
462
|
end
|
|
271
463
|
end
|
|
272
464
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
465
|
+
deferred_examples 'should copy the file to a valid destination' do
|
|
466
|
+
include_deferred 'should copy the file'
|
|
467
|
+
|
|
468
|
+
include_deferred 'should handle a directory when a file is expected',
|
|
469
|
+
:destination_path \
|
|
470
|
+
do
|
|
471
|
+
include_deferred 'should not copy the file'
|
|
472
|
+
end
|
|
276
473
|
|
|
277
|
-
|
|
474
|
+
include_deferred 'should handle a file that already exists',
|
|
475
|
+
:destination_path \
|
|
476
|
+
do
|
|
477
|
+
include_deferred 'should not copy the file'
|
|
278
478
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
let(:error_class) do
|
|
282
|
-
Cuprum::Cli::Dependencies::FileSystem::DirectoryNotFoundError
|
|
283
|
-
end
|
|
284
|
-
let(:error_message) do
|
|
285
|
-
"unable to create directory #{path} - directory not found"
|
|
286
|
-
end
|
|
479
|
+
describe 'with force: true' do
|
|
480
|
+
let(:copy_options) { super().merge(force: true) }
|
|
287
481
|
|
|
288
|
-
|
|
289
|
-
expect { subject.create_directory(path) }
|
|
290
|
-
.to raise_error(error_class, error_message)
|
|
482
|
+
include_deferred 'should copy the file'
|
|
291
483
|
end
|
|
484
|
+
end
|
|
292
485
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
486
|
+
include_deferred 'should handle a path that includes a file',
|
|
487
|
+
:destination_path \
|
|
488
|
+
do
|
|
489
|
+
include_deferred 'should not copy the file'
|
|
490
|
+
end
|
|
298
491
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
492
|
+
include_deferred 'should handle a path with missing directory',
|
|
493
|
+
:destination_path \
|
|
494
|
+
do
|
|
495
|
+
include_deferred 'should not copy the file'
|
|
496
|
+
end
|
|
497
|
+
end
|
|
304
498
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
499
|
+
let(:source_path) { 'path/to/source.txt' }
|
|
500
|
+
let(:destination_path) { 'path/to/destination.txt' }
|
|
501
|
+
let(:copy_options) { {} }
|
|
502
|
+
let(:block) { nil }
|
|
503
|
+
let(:expected_contents) { subject.read_file(source_path) }
|
|
504
|
+
let(:error_reason) { "unable to write file #{destination_path}" }
|
|
309
505
|
|
|
310
|
-
|
|
311
|
-
|
|
506
|
+
define_method :copy_file do
|
|
507
|
+
subject.copy_file(
|
|
508
|
+
source_path,
|
|
509
|
+
destination_path,
|
|
510
|
+
**copy_options,
|
|
511
|
+
&block
|
|
512
|
+
)
|
|
513
|
+
end
|
|
514
|
+
alias_method :call_method, :copy_file
|
|
312
515
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
"unable to create directory #{path} - directory is a file"
|
|
319
|
-
end
|
|
320
|
-
let(:file_path) { File.join(base_path, 'custom_dir') }
|
|
516
|
+
define_method :safe_copy_file do
|
|
517
|
+
copy_file
|
|
518
|
+
rescue StandardError
|
|
519
|
+
nil
|
|
520
|
+
end
|
|
321
521
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
522
|
+
include_deferred 'with valid file paths'
|
|
523
|
+
|
|
524
|
+
it 'should define the method' do
|
|
525
|
+
expect(subject)
|
|
526
|
+
.to respond_to(:copy_file)
|
|
527
|
+
.with(2).arguments
|
|
528
|
+
.and_keywords(:force)
|
|
529
|
+
.and_a_block
|
|
530
|
+
end
|
|
325
531
|
|
|
326
|
-
|
|
532
|
+
include_deferred 'should validate the path', :destination_path
|
|
327
533
|
|
|
328
|
-
|
|
329
|
-
expect { subject.create_directory(path, recursive: true) }
|
|
330
|
-
.to raise_error(error_class, error_message)
|
|
331
|
-
end
|
|
534
|
+
include_deferred 'should validate the path', :source_path
|
|
332
535
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
end
|
|
338
|
-
end
|
|
339
|
-
end
|
|
340
|
-
end
|
|
536
|
+
include_deferred 'should handle a path with missing file',
|
|
537
|
+
:source_path \
|
|
538
|
+
do
|
|
539
|
+
let(:error_reason) { "unable to read file #{source_path}" }
|
|
341
540
|
|
|
342
|
-
|
|
343
|
-
|
|
541
|
+
include_deferred 'should not copy the file'
|
|
542
|
+
end
|
|
344
543
|
|
|
345
|
-
|
|
346
|
-
|
|
544
|
+
wrap_deferred 'with valid file paths' do
|
|
545
|
+
describe 'with source_path: an absolute path' do
|
|
546
|
+
let(:source_path) { absolute_file_path }
|
|
347
547
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
"unable to create directory #{path} - directory is a file"
|
|
354
|
-
end
|
|
548
|
+
include_deferred \
|
|
549
|
+
'should handle a directory when a file is expected',
|
|
550
|
+
:source_path \
|
|
551
|
+
do
|
|
552
|
+
let(:error_reason) { "unable to read file #{source_path}" }
|
|
355
553
|
|
|
356
|
-
|
|
554
|
+
include_deferred 'should not copy the file'
|
|
555
|
+
end
|
|
357
556
|
|
|
358
|
-
|
|
557
|
+
wrap_deferred 'with destination_path: an absolute path' do
|
|
558
|
+
include_deferred 'should copy the file to a valid destination'
|
|
559
|
+
end
|
|
359
560
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
.to raise_error(error_class, error_message)
|
|
561
|
+
wrap_deferred 'with destination_path: a qualified path' do
|
|
562
|
+
include_deferred 'should copy the file to a valid destination'
|
|
363
563
|
end
|
|
364
564
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
rescue error_class
|
|
368
|
-
expect(subject.directory?(path)).to be false
|
|
565
|
+
wrap_deferred 'with destination_path: a relative path' do
|
|
566
|
+
include_deferred 'should copy the file to a valid destination'
|
|
369
567
|
end
|
|
370
568
|
end
|
|
371
|
-
end
|
|
372
569
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
let(:base_path) { File.join('..', '..', 'tmp', 'files') }
|
|
376
|
-
let(:path) { File.join(base_path, 'custom_dir') }
|
|
570
|
+
describe 'with source_path: a qualified path to a file' do
|
|
571
|
+
let(:source_path) { qualified_file_path }
|
|
377
572
|
|
|
378
|
-
|
|
573
|
+
include_deferred \
|
|
574
|
+
'should handle a directory when a file is expected',
|
|
575
|
+
:source_path \
|
|
576
|
+
do
|
|
577
|
+
let(:error_reason) { "unable to read file #{source_path}" }
|
|
379
578
|
|
|
380
|
-
|
|
381
|
-
expect { subject.create_directory(path) }.to(
|
|
382
|
-
change { subject.directory?(path) }.to(be true)
|
|
383
|
-
)
|
|
579
|
+
include_deferred 'should not copy the file'
|
|
384
580
|
end
|
|
385
581
|
|
|
386
|
-
|
|
387
|
-
|
|
582
|
+
wrap_deferred 'with destination_path: an absolute path' do
|
|
583
|
+
include_deferred 'should copy the file to a valid destination'
|
|
584
|
+
end
|
|
388
585
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
.to be == path
|
|
393
|
-
end
|
|
586
|
+
wrap_deferred 'with destination_path: a qualified path' do
|
|
587
|
+
include_deferred 'should copy the file to a valid destination'
|
|
588
|
+
end
|
|
394
589
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
change { subject.directory?(path) }.to(be true)
|
|
398
|
-
)
|
|
399
|
-
end
|
|
400
|
-
end
|
|
590
|
+
wrap_deferred 'with destination_path: a relative path' do
|
|
591
|
+
include_deferred 'should copy the file to a valid destination'
|
|
401
592
|
end
|
|
402
593
|
end
|
|
403
594
|
|
|
404
|
-
describe 'with a relative path' do
|
|
405
|
-
let(:
|
|
406
|
-
let(:path) { File.join(base_path, 'custom_dir') }
|
|
595
|
+
describe 'with source_path: a relative path' do
|
|
596
|
+
let(:source_path) { relative_file_path }
|
|
407
597
|
|
|
408
|
-
|
|
598
|
+
include_deferred \
|
|
599
|
+
'should handle a directory when a file is expected',
|
|
600
|
+
:source_path \
|
|
601
|
+
do
|
|
602
|
+
let(:error_reason) { "unable to read file #{source_path}" }
|
|
409
603
|
|
|
410
|
-
|
|
411
|
-
expect { subject.create_directory(path) }.to(
|
|
412
|
-
change { subject.directory?(path) }.to(be true)
|
|
413
|
-
)
|
|
604
|
+
include_deferred 'should not copy the file'
|
|
414
605
|
end
|
|
415
606
|
|
|
416
|
-
|
|
417
|
-
|
|
607
|
+
wrap_deferred 'with destination_path: an absolute path' do
|
|
608
|
+
include_deferred 'should copy the file to a valid destination'
|
|
609
|
+
end
|
|
418
610
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
.to be == path
|
|
423
|
-
end
|
|
611
|
+
wrap_deferred 'with destination_path: a qualified path' do
|
|
612
|
+
include_deferred 'should copy the file to a valid destination'
|
|
613
|
+
end
|
|
424
614
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
change { subject.directory?(path) }.to(be true)
|
|
428
|
-
)
|
|
429
|
-
end
|
|
430
|
-
end
|
|
615
|
+
wrap_deferred 'with destination_path: a relative path' do
|
|
616
|
+
include_deferred 'should copy the file to a valid destination'
|
|
431
617
|
end
|
|
432
618
|
end
|
|
433
|
-
end
|
|
434
|
-
end
|
|
435
619
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
end
|
|
440
|
-
let(:invalid_qualified_path) do
|
|
441
|
-
defined?(super()) ? super() : '../invalid-qualified-path'
|
|
442
|
-
end
|
|
443
|
-
let(:invalid_relative_path) do
|
|
444
|
-
defined?(super()) ? super() : 'invalid-absolute-path'
|
|
445
|
-
end
|
|
620
|
+
wrap_deferred 'when initialized with root_path: value' do
|
|
621
|
+
describe 'with source_path: a qualified path' do
|
|
622
|
+
let(:source_path) { qualified_file_path }
|
|
446
623
|
|
|
447
|
-
|
|
624
|
+
include_deferred \
|
|
625
|
+
'should handle a directory when a file is expected',
|
|
626
|
+
:source_path \
|
|
627
|
+
do
|
|
628
|
+
let(:error_reason) { "unable to read file #{source_path}" }
|
|
448
629
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
end
|
|
630
|
+
include_deferred 'should not copy the file'
|
|
631
|
+
end
|
|
452
632
|
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
.as(:directory_exists?)
|
|
457
|
-
end
|
|
633
|
+
wrap_deferred 'with destination_path: an absolute path' do
|
|
634
|
+
include_deferred 'should copy the file to a valid destination'
|
|
635
|
+
end
|
|
458
636
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
end
|
|
637
|
+
wrap_deferred 'with destination_path: a qualified path' do
|
|
638
|
+
include_deferred 'should copy the file to a valid destination'
|
|
639
|
+
end
|
|
463
640
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
641
|
+
wrap_deferred 'with destination_path: a relative path' do
|
|
642
|
+
include_deferred 'should copy the file to a valid destination'
|
|
643
|
+
end
|
|
644
|
+
end
|
|
645
|
+
|
|
646
|
+
describe 'with source_path: a relative path to a file' do
|
|
647
|
+
let(:source_path) { relative_file_path }
|
|
648
|
+
|
|
649
|
+
include_deferred \
|
|
650
|
+
'should handle a directory when a file is expected',
|
|
651
|
+
:source_path \
|
|
652
|
+
do
|
|
653
|
+
let(:error_reason) { "unable to read file #{source_path}" }
|
|
654
|
+
|
|
655
|
+
include_deferred 'should not copy the file'
|
|
656
|
+
end
|
|
657
|
+
|
|
658
|
+
wrap_deferred 'with destination_path: an absolute path' do
|
|
659
|
+
include_deferred 'should copy the file to a valid destination'
|
|
660
|
+
end
|
|
661
|
+
|
|
662
|
+
wrap_deferred 'with destination_path: a qualified path' do
|
|
663
|
+
include_deferred 'should copy the file to a valid destination'
|
|
664
|
+
end
|
|
665
|
+
|
|
666
|
+
wrap_deferred 'with destination_path: a relative path' do
|
|
667
|
+
include_deferred 'should copy the file to a valid destination'
|
|
668
|
+
end
|
|
669
|
+
end
|
|
467
670
|
end
|
|
468
671
|
end
|
|
672
|
+
end
|
|
469
673
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
674
|
+
describe '#create_directory' do
|
|
675
|
+
deferred_examples 'should not create the directory' do
|
|
676
|
+
it 'should not create the directory' do
|
|
677
|
+
expect { safe_create_directory }.not_to(
|
|
678
|
+
change { subject.directory?(path) }
|
|
679
|
+
)
|
|
473
680
|
end
|
|
681
|
+
end
|
|
474
682
|
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
683
|
+
deferred_examples 'should create the directory' do
|
|
684
|
+
it { expect(create_directory).to be == path }
|
|
685
|
+
|
|
686
|
+
it 'should create the directory' do
|
|
687
|
+
expect { create_directory }.to(
|
|
688
|
+
change { subject.directory?(path) }.to(be true)
|
|
689
|
+
)
|
|
478
690
|
end
|
|
479
691
|
end
|
|
480
692
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
693
|
+
deferred_examples 'should create the directory for a valid path' do
|
|
694
|
+
include_deferred 'should create the directory'
|
|
695
|
+
|
|
696
|
+
context 'when the directory already exists' do
|
|
697
|
+
let(:path) do
|
|
698
|
+
if absolute_path?(super())
|
|
699
|
+
absolute_directory_path
|
|
700
|
+
elsif qualified_path?(super())
|
|
701
|
+
qualified_directory_path
|
|
702
|
+
else
|
|
703
|
+
relative_directory_path
|
|
704
|
+
end
|
|
705
|
+
end
|
|
706
|
+
|
|
707
|
+
it { expect(create_directory).to be == path }
|
|
708
|
+
|
|
709
|
+
include_deferred 'should not create the directory'
|
|
484
710
|
end
|
|
485
711
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
712
|
+
include_deferred 'should handle a file when a directory is expected' \
|
|
713
|
+
do
|
|
714
|
+
include_deferred 'should not create the directory'
|
|
489
715
|
end
|
|
490
|
-
end
|
|
491
716
|
|
|
492
|
-
|
|
493
|
-
|
|
717
|
+
include_deferred 'should handle a path with missing directory' \
|
|
718
|
+
do
|
|
719
|
+
include_deferred 'should not create the directory'
|
|
494
720
|
|
|
495
|
-
|
|
496
|
-
|
|
721
|
+
describe 'with recursive: true' do
|
|
722
|
+
let(:create_options) { super().merge(recursive: true) }
|
|
497
723
|
|
|
498
|
-
|
|
499
|
-
|
|
724
|
+
include_deferred 'should create the directory'
|
|
725
|
+
end
|
|
726
|
+
end
|
|
500
727
|
|
|
501
|
-
|
|
728
|
+
include_deferred 'should handle a path that includes a file' do
|
|
729
|
+
include_deferred 'should not create the directory'
|
|
730
|
+
end
|
|
502
731
|
end
|
|
503
732
|
|
|
504
|
-
|
|
505
|
-
|
|
733
|
+
let(:path) { nil }
|
|
734
|
+
let(:create_options) { {} }
|
|
735
|
+
let(:error_reason) { "unable to create directory #{path}" }
|
|
506
736
|
|
|
507
|
-
|
|
737
|
+
define_method :create_directory do
|
|
738
|
+
subject.create_directory(path, **create_options)
|
|
508
739
|
end
|
|
740
|
+
alias_method :call_method, :create_directory
|
|
509
741
|
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
742
|
+
define_method :safe_create_directory do
|
|
743
|
+
create_directory
|
|
744
|
+
rescue StandardError
|
|
745
|
+
nil
|
|
514
746
|
end
|
|
515
747
|
|
|
516
|
-
|
|
517
|
-
let(:path) { absolute_file_path }
|
|
748
|
+
include_deferred 'with valid file paths'
|
|
518
749
|
|
|
519
|
-
|
|
750
|
+
it 'should define the method' do
|
|
751
|
+
expect(subject)
|
|
752
|
+
.to respond_to(:create_directory)
|
|
753
|
+
.with(1).argument
|
|
754
|
+
.and_keywords(:recursive)
|
|
520
755
|
end
|
|
521
756
|
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
757
|
+
it 'should define the aliased method' do
|
|
758
|
+
expect(subject)
|
|
759
|
+
.to have_aliased_method(:create_directory)
|
|
760
|
+
.as(:make_directory)
|
|
526
761
|
end
|
|
527
762
|
|
|
528
|
-
|
|
529
|
-
let(:path) { qualified_file_path }
|
|
763
|
+
include_deferred 'should validate the path'
|
|
530
764
|
|
|
531
|
-
|
|
765
|
+
describe 'with an absolute path' do
|
|
766
|
+
let(:path) { File.join(absolute_directory_path, 'custom_dir') }
|
|
767
|
+
|
|
768
|
+
include_deferred 'should create the directory for a valid path'
|
|
532
769
|
end
|
|
533
770
|
|
|
534
|
-
describe 'with a relative path
|
|
535
|
-
let(:path) { relative_directory_path }
|
|
771
|
+
describe 'with a relative path' do
|
|
772
|
+
let(:path) { File.join(relative_directory_path, 'custom_dir') }
|
|
536
773
|
|
|
537
|
-
|
|
774
|
+
include_deferred 'should create the directory for a valid path'
|
|
538
775
|
end
|
|
539
776
|
|
|
540
|
-
describe 'with a
|
|
541
|
-
let(:path) {
|
|
777
|
+
describe 'with a qualified path' do
|
|
778
|
+
let(:path) { File.join(qualified_directory_path, 'custom_dir') }
|
|
542
779
|
|
|
543
|
-
|
|
780
|
+
include_deferred 'should create the directory for a valid path'
|
|
544
781
|
end
|
|
545
782
|
|
|
546
783
|
wrap_deferred 'when initialized with root_path: value' do
|
|
547
|
-
describe 'with a
|
|
548
|
-
let(:path) {
|
|
784
|
+
describe 'with a relative path' do
|
|
785
|
+
let(:path) { File.join(relative_directory_path, 'custom_dir') }
|
|
549
786
|
|
|
550
|
-
|
|
787
|
+
include_deferred 'should create the directory for a valid path'
|
|
551
788
|
end
|
|
552
789
|
|
|
553
|
-
describe 'with a qualified path
|
|
554
|
-
let(:path) {
|
|
790
|
+
describe 'with a qualified path' do
|
|
791
|
+
let(:path) { File.join(qualified_directory_path, 'custom_dir') }
|
|
555
792
|
|
|
556
|
-
|
|
793
|
+
include_deferred 'should create the directory for a valid path'
|
|
557
794
|
end
|
|
795
|
+
end
|
|
796
|
+
end
|
|
558
797
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
798
|
+
describe '#delete_directory' do
|
|
799
|
+
deferred_examples 'should not delete the directory' do
|
|
800
|
+
it 'should not delete the directory' do
|
|
801
|
+
expect { safe_delete_directory }.not_to(
|
|
802
|
+
change { subject.directory?(path) }
|
|
803
|
+
)
|
|
563
804
|
end
|
|
805
|
+
end
|
|
564
806
|
|
|
565
|
-
|
|
566
|
-
|
|
807
|
+
deferred_examples 'should delete the directory' do
|
|
808
|
+
it { expect(delete_directory).to be == path }
|
|
567
809
|
|
|
568
|
-
|
|
810
|
+
it 'should delete the directory' do
|
|
811
|
+
expect { delete_directory }.to(
|
|
812
|
+
change { subject.directory?(path) }.to(be false)
|
|
813
|
+
)
|
|
569
814
|
end
|
|
570
815
|
end
|
|
571
|
-
end
|
|
572
816
|
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
817
|
+
deferred_examples 'should delete the directory for a valid path' do
|
|
818
|
+
include_deferred 'should handle a path that includes a file' do
|
|
819
|
+
include_deferred 'should not delete the directory'
|
|
820
|
+
end
|
|
577
821
|
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
end
|
|
822
|
+
include_deferred 'should handle a path with missing directory' do
|
|
823
|
+
include_deferred 'should not delete the directory'
|
|
581
824
|
end
|
|
582
825
|
|
|
583
|
-
|
|
584
|
-
|
|
826
|
+
include_deferred 'should handle a path with missing directory' do
|
|
827
|
+
include_deferred 'should not delete the directory'
|
|
828
|
+
end
|
|
585
829
|
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
expectation.not_to(yield_control)
|
|
591
|
-
else
|
|
592
|
-
expectation.to yield_successive_args(*expected_files)
|
|
593
|
-
end
|
|
594
|
-
end
|
|
595
|
-
end
|
|
830
|
+
context 'when the directory is empty' do
|
|
831
|
+
let(:path) { File.join(super(), 'empty_dir') }
|
|
832
|
+
|
|
833
|
+
include_deferred 'should delete the directory'
|
|
596
834
|
end
|
|
597
|
-
end
|
|
598
835
|
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
836
|
+
context 'when the directory contains empty directories' do
|
|
837
|
+
let(:path) { File.join(super(), 'dir_with_directories') }
|
|
838
|
+
let(:error_class) do
|
|
839
|
+
Cuprum::Cli::Dependencies::FileSystem::DirectoryNotEmptyError
|
|
840
|
+
end
|
|
841
|
+
let(:error_message) do
|
|
842
|
+
"#{error_reason} - directory is not empty"
|
|
843
|
+
end
|
|
604
844
|
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
.and_a_block
|
|
610
|
-
end
|
|
845
|
+
it 'should raise an exception' do
|
|
846
|
+
expect { delete_directory }
|
|
847
|
+
.to raise_error(error_class, error_message)
|
|
848
|
+
end
|
|
611
849
|
|
|
612
|
-
|
|
850
|
+
include_deferred 'should not delete the directory'
|
|
613
851
|
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
852
|
+
it 'should not change the directory contents' do
|
|
853
|
+
expect { safe_delete_directory }
|
|
854
|
+
.not_to(change { Dir[File.join(path, '**')] })
|
|
855
|
+
end
|
|
618
856
|
|
|
619
|
-
|
|
857
|
+
describe 'with force: true' do
|
|
858
|
+
let(:delete_options) { super().merge(force: true) }
|
|
859
|
+
|
|
860
|
+
include_deferred 'should delete the directory'
|
|
861
|
+
end
|
|
862
|
+
|
|
863
|
+
describe 'with recursive: true' do
|
|
864
|
+
let(:delete_options) { super().merge(recursive: true) }
|
|
865
|
+
|
|
866
|
+
include_deferred 'should delete the directory'
|
|
867
|
+
end
|
|
620
868
|
end
|
|
621
869
|
|
|
622
|
-
|
|
623
|
-
let(:
|
|
624
|
-
let(:
|
|
625
|
-
|
|
870
|
+
context 'when the directory contains files' do
|
|
871
|
+
let(:path) { File.join(super(), 'dir_with_files') }
|
|
872
|
+
let(:error_class) do
|
|
873
|
+
Cuprum::Cli::Dependencies::FileSystem::DirectoryNotEmptyError
|
|
874
|
+
end
|
|
875
|
+
let(:error_message) do
|
|
876
|
+
"#{error_reason} - directory is not empty"
|
|
877
|
+
end
|
|
626
878
|
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
879
|
+
it 'should raise an exception' do
|
|
880
|
+
expect { delete_directory }
|
|
881
|
+
.to raise_error(error_class, error_message)
|
|
630
882
|
end
|
|
631
883
|
|
|
632
|
-
include_deferred 'should
|
|
633
|
-
end
|
|
884
|
+
include_deferred 'should not delete the directory'
|
|
634
885
|
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
886
|
+
it 'should not change the directory contents' do
|
|
887
|
+
expect { safe_delete_directory }
|
|
888
|
+
.not_to(change { Dir[File.join(path, '**')] })
|
|
889
|
+
end
|
|
639
890
|
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
891
|
+
describe 'with force: true' do
|
|
892
|
+
let(:delete_options) { super().merge(force: true) }
|
|
893
|
+
|
|
894
|
+
include_deferred 'should delete the directory'
|
|
643
895
|
end
|
|
644
896
|
|
|
645
|
-
|
|
646
|
-
|
|
897
|
+
describe 'with recursive: true' do
|
|
898
|
+
let(:delete_options) { super().merge(recursive: true) }
|
|
647
899
|
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
900
|
+
it 'should raise an exception' do
|
|
901
|
+
expect { delete_directory }
|
|
902
|
+
.to raise_error(error_class, error_message)
|
|
903
|
+
end
|
|
652
904
|
|
|
653
|
-
|
|
654
|
-
|
|
905
|
+
include_deferred 'should not delete the directory'
|
|
906
|
+
|
|
907
|
+
it 'should not change the directory contents' do
|
|
908
|
+
expect { safe_delete_directory }
|
|
909
|
+
.not_to(change { Dir[File.join(path, '**')] })
|
|
655
910
|
end
|
|
656
911
|
end
|
|
657
|
-
|
|
658
|
-
include_deferred 'should return or yield the matching file names'
|
|
659
912
|
end
|
|
660
913
|
end
|
|
661
|
-
end
|
|
662
914
|
|
|
663
|
-
|
|
664
|
-
let(:
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
end
|
|
670
|
-
let(:invalid_relative_path) do
|
|
671
|
-
defined?(super()) ? super() : 'invalid-absolute-path'
|
|
915
|
+
let(:path) { nil }
|
|
916
|
+
let(:delete_options) { {} }
|
|
917
|
+
let(:error_reason) { "unable to delete directory #{path}" }
|
|
918
|
+
|
|
919
|
+
define_method :delete_directory do
|
|
920
|
+
subject.delete_directory(path, **delete_options)
|
|
672
921
|
end
|
|
922
|
+
alias_method :call_method, :delete_directory
|
|
673
923
|
|
|
674
|
-
|
|
924
|
+
define_method :safe_delete_directory do
|
|
925
|
+
delete_directory
|
|
926
|
+
rescue StandardError
|
|
927
|
+
nil
|
|
928
|
+
end
|
|
675
929
|
|
|
676
930
|
it 'should define the method' do
|
|
677
|
-
expect(subject)
|
|
931
|
+
expect(subject)
|
|
932
|
+
.to respond_to(:delete_directory)
|
|
933
|
+
.with(1).argument
|
|
934
|
+
.and_keywords(:force, :recursive)
|
|
678
935
|
end
|
|
679
936
|
|
|
680
|
-
it 'should
|
|
937
|
+
it 'should alias the method' do
|
|
681
938
|
expect(subject)
|
|
682
|
-
.to have_aliased_method(:
|
|
683
|
-
.as(:
|
|
939
|
+
.to have_aliased_method(:delete_directory)
|
|
940
|
+
.as(:remove_directory)
|
|
684
941
|
end
|
|
685
942
|
|
|
686
|
-
|
|
687
|
-
let(:error_message) do
|
|
688
|
-
tools.assertions.error_message_for('presence', as: 'path')
|
|
689
|
-
end
|
|
943
|
+
include_deferred 'should validate the path'
|
|
690
944
|
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
945
|
+
wrap_deferred 'with valid file paths' do
|
|
946
|
+
let(:directory_fixtures) do
|
|
947
|
+
{
|
|
948
|
+
'dir_with_directories' => {
|
|
949
|
+
'empty_child' => {},
|
|
950
|
+
'non_empty_child' => {
|
|
951
|
+
'empty_grandchild' => {}
|
|
952
|
+
}
|
|
953
|
+
},
|
|
954
|
+
'dir_with_files' => {
|
|
955
|
+
'empty_child' => {},
|
|
956
|
+
'non_empty_child' => {
|
|
957
|
+
'file.txt' => 'Existing contents.'
|
|
958
|
+
}
|
|
959
|
+
},
|
|
960
|
+
'empty_dir' => {}
|
|
961
|
+
}
|
|
962
|
+
end
|
|
963
|
+
let(:fixtures) do
|
|
964
|
+
root_path = defined?(self.root_path) ? self.root_path : Dir.pwd
|
|
965
|
+
base_path = fixtures_path
|
|
966
|
+
|
|
967
|
+
if base_path.start_with?('.')
|
|
968
|
+
base_path = File.expand_path(File.join(root_path, base_path))
|
|
969
|
+
end
|
|
970
|
+
|
|
971
|
+
relative_path = absolute_directory_path[(1 + base_path.size)...]
|
|
972
|
+
|
|
973
|
+
merge_fixtures(
|
|
974
|
+
super(),
|
|
975
|
+
*relative_path.split(File::SEPARATOR),
|
|
976
|
+
directory_fixtures
|
|
977
|
+
)
|
|
694
978
|
end
|
|
695
|
-
end
|
|
696
979
|
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
980
|
+
define_method :merge_fixtures do |fixtures, *path, value|
|
|
981
|
+
return fixtures.merge(value) if path.empty?
|
|
982
|
+
|
|
983
|
+
head, *tail = path
|
|
984
|
+
|
|
985
|
+
fixtures.merge(head => merge_fixtures(fixtures[head], *tail, value))
|
|
700
986
|
end
|
|
701
987
|
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
988
|
+
describe 'with an absolute path' do
|
|
989
|
+
let(:path) { absolute_directory_path }
|
|
990
|
+
|
|
991
|
+
include_deferred 'should delete the directory for a valid path'
|
|
705
992
|
end
|
|
706
|
-
end
|
|
707
993
|
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
994
|
+
describe 'with a qualified path' do
|
|
995
|
+
let(:path) { qualified_directory_path }
|
|
996
|
+
|
|
997
|
+
include_deferred 'should delete the directory for a valid path'
|
|
711
998
|
end
|
|
712
999
|
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
1000
|
+
describe 'with a relative path' do
|
|
1001
|
+
let(:path) { relative_directory_path }
|
|
1002
|
+
|
|
1003
|
+
include_deferred 'should delete the directory for a valid path'
|
|
716
1004
|
end
|
|
717
|
-
end
|
|
718
1005
|
|
|
719
|
-
|
|
720
|
-
|
|
1006
|
+
wrap_deferred 'when initialized with root_path: value' do
|
|
1007
|
+
describe 'with a relative path' do
|
|
1008
|
+
let(:path) { File.join(relative_directory_path) }
|
|
721
1009
|
|
|
722
|
-
|
|
723
|
-
|
|
1010
|
+
include_deferred 'should delete the directory for a valid path'
|
|
1011
|
+
end
|
|
724
1012
|
|
|
725
|
-
|
|
726
|
-
|
|
1013
|
+
describe 'with a qualified path' do
|
|
1014
|
+
let(:path) { File.join(qualified_directory_path) }
|
|
727
1015
|
|
|
728
|
-
|
|
1016
|
+
include_deferred 'should delete the directory for a valid path'
|
|
1017
|
+
end
|
|
1018
|
+
end
|
|
729
1019
|
end
|
|
1020
|
+
end
|
|
730
1021
|
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
1022
|
+
describe '#delete_file' do
|
|
1023
|
+
deferred_examples 'should not delete the file' do
|
|
1024
|
+
it 'should not delete the file' do
|
|
1025
|
+
expect { safe_delete_file }.not_to(
|
|
1026
|
+
change { subject.file?(path) }
|
|
1027
|
+
)
|
|
1028
|
+
end
|
|
735
1029
|
end
|
|
736
1030
|
|
|
737
|
-
|
|
738
|
-
|
|
1031
|
+
deferred_examples 'should delete the file' do
|
|
1032
|
+
it { expect(delete_file).to be == path }
|
|
739
1033
|
|
|
740
|
-
it
|
|
1034
|
+
it 'should delete the file' do
|
|
1035
|
+
expect { delete_file }.to(
|
|
1036
|
+
change { subject.file?(path) }.to(be false)
|
|
1037
|
+
)
|
|
1038
|
+
end
|
|
741
1039
|
end
|
|
742
1040
|
|
|
743
|
-
|
|
744
|
-
|
|
1041
|
+
deferred_examples 'should delete the file for a valid path' do
|
|
1042
|
+
include_deferred 'should delete the file'
|
|
745
1043
|
|
|
746
|
-
|
|
1044
|
+
include_deferred 'should handle a directory when a file is expected' \
|
|
1045
|
+
do
|
|
1046
|
+
include_deferred 'should not delete the file'
|
|
1047
|
+
end
|
|
747
1048
|
end
|
|
748
1049
|
|
|
749
|
-
|
|
750
|
-
|
|
1050
|
+
let(:path) { nil }
|
|
1051
|
+
let(:error_reason) { "unable to delete file #{path}" }
|
|
751
1052
|
|
|
752
|
-
|
|
1053
|
+
define_method :delete_file do
|
|
1054
|
+
subject.delete_file(path)
|
|
753
1055
|
end
|
|
1056
|
+
alias_method :call_method, :delete_file
|
|
754
1057
|
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
1058
|
+
define_method :safe_delete_file do
|
|
1059
|
+
delete_file
|
|
1060
|
+
rescue StandardError
|
|
1061
|
+
nil
|
|
759
1062
|
end
|
|
760
1063
|
|
|
761
|
-
|
|
762
|
-
let(:path) { relative_directory_path }
|
|
1064
|
+
it { expect(subject).to respond_to(:delete_file).with(1).argument }
|
|
763
1065
|
|
|
764
|
-
|
|
1066
|
+
it 'should define the aliased method' do
|
|
1067
|
+
expect(subject).to have_aliased_method(:delete_file).as(:remove_file)
|
|
765
1068
|
end
|
|
766
1069
|
|
|
767
|
-
|
|
768
|
-
let(:path) { relative_file_path }
|
|
1070
|
+
include_deferred 'should validate the path'
|
|
769
1071
|
|
|
770
|
-
|
|
771
|
-
end
|
|
1072
|
+
include_deferred 'should handle a path with missing file'
|
|
772
1073
|
|
|
773
|
-
wrap_deferred '
|
|
774
|
-
describe 'with
|
|
775
|
-
let(:path) {
|
|
1074
|
+
wrap_deferred 'with valid file paths' do
|
|
1075
|
+
describe 'with an absolute path' do
|
|
1076
|
+
let(:path) { absolute_file_path }
|
|
776
1077
|
|
|
777
|
-
|
|
1078
|
+
include_deferred 'should delete the file for a valid path'
|
|
778
1079
|
end
|
|
779
1080
|
|
|
780
|
-
describe 'with a qualified path
|
|
1081
|
+
describe 'with a qualified path' do
|
|
781
1082
|
let(:path) { qualified_file_path }
|
|
782
1083
|
|
|
783
|
-
|
|
1084
|
+
include_deferred 'should delete the file for a valid path'
|
|
784
1085
|
end
|
|
785
1086
|
|
|
786
|
-
describe 'with a relative path
|
|
787
|
-
let(:path) {
|
|
1087
|
+
describe 'with a relative path' do
|
|
1088
|
+
let(:path) { relative_file_path }
|
|
788
1089
|
|
|
789
|
-
|
|
1090
|
+
include_deferred 'should delete the file for a valid path'
|
|
790
1091
|
end
|
|
791
1092
|
|
|
792
|
-
|
|
793
|
-
|
|
1093
|
+
wrap_deferred 'when initialized with root_path: value' do
|
|
1094
|
+
describe 'with a qualified path' do
|
|
1095
|
+
let(:path) { qualified_file_path }
|
|
794
1096
|
|
|
795
|
-
|
|
1097
|
+
include_deferred 'should delete the file for a valid path'
|
|
1098
|
+
end
|
|
1099
|
+
|
|
1100
|
+
describe 'with a relative path' do
|
|
1101
|
+
let(:path) { relative_file_path }
|
|
1102
|
+
|
|
1103
|
+
include_deferred 'should delete the file for a valid path'
|
|
1104
|
+
end
|
|
796
1105
|
end
|
|
797
1106
|
end
|
|
798
1107
|
end
|
|
799
1108
|
|
|
800
|
-
describe '#
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
end
|
|
804
|
-
let(:invalid_qualified_path) do
|
|
805
|
-
defined?(super()) ? super() : '../invalid-qualified-path'
|
|
806
|
-
end
|
|
807
|
-
let(:invalid_relative_path) do
|
|
808
|
-
defined?(super()) ? super() : 'invalid-relative-path'
|
|
1109
|
+
describe '#directory?' do
|
|
1110
|
+
define_method :check_directory do
|
|
1111
|
+
subject.directory?(path)
|
|
809
1112
|
end
|
|
810
|
-
|
|
811
|
-
path = self.path
|
|
1113
|
+
alias_method :call_method, :check_directory
|
|
812
1114
|
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
end
|
|
816
|
-
|
|
817
|
-
path = path.sub(%r{\A#{subject.root_path}/?}, '')
|
|
818
|
-
|
|
819
|
-
"Contents of #{path}"
|
|
1115
|
+
it 'should define the method' do
|
|
1116
|
+
expect(subject).to respond_to(:directory?).with(1).argument
|
|
820
1117
|
end
|
|
821
1118
|
|
|
822
|
-
it { expect(subject).to respond_to(:read_file).with(1).argument }
|
|
823
|
-
|
|
824
1119
|
it 'should define the aliased method' do
|
|
825
|
-
expect(subject)
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
describe 'with nil' do
|
|
829
|
-
let(:error_message) do
|
|
830
|
-
tools.assertions.error_message_for('presence', as: :file)
|
|
831
|
-
end
|
|
832
|
-
|
|
833
|
-
it 'should raise an exception' do
|
|
834
|
-
expect { subject.read_file(nil) }
|
|
835
|
-
.to raise_error ArgumentError, error_message
|
|
836
|
-
end
|
|
837
|
-
end
|
|
838
|
-
|
|
839
|
-
describe 'with an Object' do
|
|
840
|
-
let(:error_message) do
|
|
841
|
-
'file is not a String or IO stream'
|
|
842
|
-
end
|
|
843
|
-
|
|
844
|
-
it 'should raise an exception' do
|
|
845
|
-
expect { subject.read_file(Object.new.freeze) }
|
|
846
|
-
.to raise_error ArgumentError, error_message
|
|
847
|
-
end
|
|
848
|
-
end
|
|
849
|
-
|
|
850
|
-
describe 'with an empty String' do
|
|
851
|
-
let(:error_message) do
|
|
852
|
-
tools.assertions.error_message_for('presence', as: :file)
|
|
853
|
-
end
|
|
854
|
-
|
|
855
|
-
it 'should raise an exception' do
|
|
856
|
-
expect { subject.read_file('') }
|
|
857
|
-
.to raise_error ArgumentError, error_message
|
|
858
|
-
end
|
|
1120
|
+
expect(subject)
|
|
1121
|
+
.to have_aliased_method(:directory?)
|
|
1122
|
+
.as(:directory_exists?)
|
|
859
1123
|
end
|
|
860
1124
|
|
|
861
|
-
|
|
862
|
-
let(:stream) { StringIO.new('Greetings, programs!') }
|
|
863
|
-
|
|
864
|
-
it { expect(subject.read_file(stream)).to be == stream.string }
|
|
865
|
-
end
|
|
1125
|
+
include_deferred 'should validate the path'
|
|
866
1126
|
|
|
867
1127
|
describe 'with an invalid absolute path' do
|
|
868
1128
|
let(:path) { invalid_absolute_path }
|
|
869
|
-
let(:error_class) do
|
|
870
|
-
Cuprum::Cli::Dependencies::FileSystem::FileNotFoundError
|
|
871
|
-
end
|
|
872
|
-
let(:error_message) do
|
|
873
|
-
"unable to read file #{path} - file not found"
|
|
874
|
-
end
|
|
875
1129
|
|
|
876
|
-
it
|
|
877
|
-
expect { subject.read_file(path) }
|
|
878
|
-
.to raise_error(error_class, error_message)
|
|
879
|
-
end
|
|
1130
|
+
it { expect(subject.directory?(path)).to be false }
|
|
880
1131
|
end
|
|
881
1132
|
|
|
882
1133
|
describe 'with an invalid qualified path' do
|
|
883
1134
|
let(:path) { invalid_qualified_path }
|
|
884
|
-
let(:error_class) do
|
|
885
|
-
Cuprum::Cli::Dependencies::FileSystem::FileNotFoundError
|
|
886
|
-
end
|
|
887
|
-
let(:error_message) do
|
|
888
|
-
"unable to read file #{path} - file not found"
|
|
889
|
-
end
|
|
890
1135
|
|
|
891
|
-
it
|
|
892
|
-
expect { subject.read_file(path) }
|
|
893
|
-
.to raise_error(error_class, error_message)
|
|
894
|
-
end
|
|
1136
|
+
it { expect(subject.directory?(path)).to be false }
|
|
895
1137
|
end
|
|
896
1138
|
|
|
897
1139
|
describe 'with an invalid relative path' do
|
|
898
1140
|
let(:path) { invalid_relative_path }
|
|
899
|
-
let(:error_class) do
|
|
900
|
-
Cuprum::Cli::Dependencies::FileSystem::FileNotFoundError
|
|
901
|
-
end
|
|
902
|
-
let(:error_message) do
|
|
903
|
-
"unable to read file #{path} - file not found"
|
|
904
|
-
end
|
|
905
1141
|
|
|
906
|
-
it
|
|
907
|
-
expect { subject.read_file(path) }
|
|
908
|
-
.to raise_error(error_class, error_message)
|
|
909
|
-
end
|
|
1142
|
+
it { expect(subject.directory?(path)).to be false }
|
|
910
1143
|
end
|
|
911
1144
|
|
|
912
1145
|
wrap_deferred 'with valid file paths' do
|
|
913
1146
|
describe 'with an absolute path to a directory' do
|
|
914
1147
|
let(:path) { absolute_directory_path }
|
|
915
|
-
let(:error_class) do
|
|
916
|
-
Cuprum::Cli::Dependencies::FileSystem::FileIsADirectoryError
|
|
917
|
-
end
|
|
918
|
-
let(:error_message) do
|
|
919
|
-
"unable to read file #{path} - file is a directory"
|
|
920
|
-
end
|
|
921
1148
|
|
|
922
|
-
it
|
|
923
|
-
expect { subject.read_file(path) }
|
|
924
|
-
.to raise_error(error_class, error_message)
|
|
925
|
-
end
|
|
1149
|
+
it { expect(subject.directory?(path)).to be true }
|
|
926
1150
|
end
|
|
927
1151
|
|
|
928
1152
|
describe 'with an absolute path to a file' do
|
|
929
1153
|
let(:path) { absolute_file_path }
|
|
930
1154
|
|
|
931
|
-
it { expect(subject.
|
|
1155
|
+
it { expect(subject.directory?(path)).to be false }
|
|
932
1156
|
end
|
|
933
1157
|
|
|
934
1158
|
describe 'with a qualified path to a directory' do
|
|
935
1159
|
let(:path) { qualified_directory_path }
|
|
936
|
-
let(:error_class) do
|
|
937
|
-
Cuprum::Cli::Dependencies::FileSystem::FileIsADirectoryError
|
|
938
|
-
end
|
|
939
|
-
let(:error_message) do
|
|
940
|
-
"unable to read file #{path} - file is a directory"
|
|
941
|
-
end
|
|
942
1160
|
|
|
943
|
-
it
|
|
944
|
-
expect { subject.read_file(path) }
|
|
945
|
-
.to raise_error(error_class, error_message)
|
|
946
|
-
end
|
|
1161
|
+
it { expect(subject.directory?(path)).to be true }
|
|
947
1162
|
end
|
|
948
1163
|
|
|
949
1164
|
describe 'with a qualified path to a file' do
|
|
950
1165
|
let(:path) { qualified_file_path }
|
|
951
1166
|
|
|
952
|
-
it { expect(subject.
|
|
1167
|
+
it { expect(subject.directory?(path)).to be false }
|
|
953
1168
|
end
|
|
954
1169
|
|
|
955
1170
|
describe 'with a relative path to a directory' do
|
|
956
1171
|
let(:path) { relative_directory_path }
|
|
957
|
-
let(:error_class) do
|
|
958
|
-
Cuprum::Cli::Dependencies::FileSystem::FileIsADirectoryError
|
|
959
|
-
end
|
|
960
|
-
let(:error_message) do
|
|
961
|
-
"unable to read file #{path} - file is a directory"
|
|
962
|
-
end
|
|
963
1172
|
|
|
964
|
-
it
|
|
965
|
-
expect { subject.read_file(path) }
|
|
966
|
-
.to raise_error(error_class, error_message)
|
|
967
|
-
end
|
|
1173
|
+
it { expect(subject.directory?(path)).to be true }
|
|
968
1174
|
end
|
|
969
1175
|
|
|
970
1176
|
describe 'with a relative path to a file' do
|
|
971
1177
|
let(:path) { relative_file_path }
|
|
972
1178
|
|
|
973
|
-
it { expect(subject.
|
|
1179
|
+
it { expect(subject.directory?(path)).to be false }
|
|
974
1180
|
end
|
|
975
1181
|
|
|
976
|
-
wrap_deferred 'with
|
|
1182
|
+
wrap_deferred 'when initialized with root_path: value' do
|
|
977
1183
|
describe 'with a qualified path to a directory' do
|
|
978
1184
|
let(:path) { qualified_directory_path }
|
|
979
|
-
let(:error_class) do
|
|
980
|
-
Cuprum::Cli::Dependencies::FileSystem::FileIsADirectoryError
|
|
981
|
-
end
|
|
982
|
-
let(:error_message) do
|
|
983
|
-
"unable to read file #{path} - file is a directory"
|
|
984
|
-
end
|
|
985
1185
|
|
|
986
|
-
it
|
|
987
|
-
expect { subject.read_file(path) }
|
|
988
|
-
.to raise_error(error_class, error_message)
|
|
989
|
-
end
|
|
1186
|
+
it { expect(subject.directory?(path)).to be true }
|
|
990
1187
|
end
|
|
991
1188
|
|
|
992
1189
|
describe 'with a qualified path to a file' do
|
|
993
1190
|
let(:path) { qualified_file_path }
|
|
994
1191
|
|
|
995
|
-
it { expect(subject.
|
|
1192
|
+
it { expect(subject.directory?(path)).to be false }
|
|
996
1193
|
end
|
|
997
1194
|
|
|
998
1195
|
describe 'with a relative path to a directory' do
|
|
999
1196
|
let(:path) { relative_directory_path }
|
|
1000
|
-
let(:error_class) do
|
|
1001
|
-
Cuprum::Cli::Dependencies::FileSystem::FileIsADirectoryError
|
|
1002
|
-
end
|
|
1003
|
-
let(:error_message) do
|
|
1004
|
-
"unable to read file #{path} - file is a directory"
|
|
1005
|
-
end
|
|
1006
1197
|
|
|
1007
|
-
it
|
|
1008
|
-
expect { subject.read_file(path) }
|
|
1009
|
-
.to raise_error(error_class, error_message)
|
|
1010
|
-
end
|
|
1198
|
+
it { expect(subject.directory?(path)).to be true }
|
|
1011
1199
|
end
|
|
1012
1200
|
|
|
1013
1201
|
describe 'with a relative path to a file' do
|
|
1014
1202
|
let(:path) { relative_file_path }
|
|
1015
1203
|
|
|
1016
|
-
it { expect(subject.
|
|
1204
|
+
it { expect(subject.directory?(path)).to be false }
|
|
1017
1205
|
end
|
|
1018
1206
|
end
|
|
1019
1207
|
end
|
|
1020
1208
|
end
|
|
1021
1209
|
|
|
1022
|
-
describe '#
|
|
1023
|
-
|
|
1210
|
+
describe '#each_file' do
|
|
1211
|
+
deferred_examples 'should return or yield the matching file names' do
|
|
1212
|
+
describe 'without a block' do
|
|
1213
|
+
it { expect(subject.each_file(pattern)).to be_a Enumerator }
|
|
1024
1214
|
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1215
|
+
it 'should return the matching file names' do
|
|
1216
|
+
expect(subject.each_file(pattern).to_a).to be == expected_files
|
|
1217
|
+
end
|
|
1218
|
+
end
|
|
1029
1219
|
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1220
|
+
describe 'with a block' do
|
|
1221
|
+
it { expect(subject.each_file(pattern) { nil }).to be nil }
|
|
1222
|
+
|
|
1223
|
+
it 'should yield the matching file names' do
|
|
1224
|
+
expect { |block| subject.each_file(pattern, &block) }.then \
|
|
1225
|
+
do |expectation|
|
|
1226
|
+
if expected_files.empty?
|
|
1227
|
+
expectation.not_to(yield_control)
|
|
1228
|
+
else
|
|
1229
|
+
expectation.to yield_successive_args(*expected_files)
|
|
1230
|
+
end
|
|
1231
|
+
end
|
|
1232
|
+
end
|
|
1233
|
+
end
|
|
1035
1234
|
end
|
|
1036
1235
|
|
|
1236
|
+
let(:defined_files) { flattened_fixture_names }
|
|
1237
|
+
|
|
1037
1238
|
it 'should define the method' do
|
|
1038
1239
|
expect(subject)
|
|
1039
|
-
.to respond_to(:
|
|
1040
|
-
.with(
|
|
1240
|
+
.to respond_to(:each_file)
|
|
1241
|
+
.with(1).argument
|
|
1041
1242
|
.and_a_block
|
|
1042
1243
|
end
|
|
1043
1244
|
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
.to yield_with_args(expected_tempfile)
|
|
1047
|
-
end
|
|
1048
|
-
end
|
|
1049
|
-
|
|
1050
|
-
describe '#write_file', writeable_root_path: true do
|
|
1051
|
-
let(:invalid_absolute_path) do
|
|
1052
|
-
defined?(super()) ? super() : '/invalid-absolute-path'
|
|
1053
|
-
end
|
|
1054
|
-
let(:invalid_qualified_path) do
|
|
1055
|
-
defined?(super()) ? super() : '../invalid-qualified-path'
|
|
1056
|
-
end
|
|
1057
|
-
let(:invalid_relative_path) do
|
|
1058
|
-
defined?(super()) ? super() : 'invalid-relative-path'
|
|
1059
|
-
end
|
|
1060
|
-
let(:file_name) { "#{SecureRandom.uuid}.txt" }
|
|
1061
|
-
let(:data) { "Greetings, programs!\n" }
|
|
1062
|
-
|
|
1063
|
-
include_deferred 'with valid file paths'
|
|
1064
|
-
|
|
1065
|
-
it { expect(subject).to respond_to(:write_file).with(2).arguments }
|
|
1066
|
-
|
|
1067
|
-
it 'should define the aliased method' do
|
|
1068
|
-
expect(subject).to have_aliased_method(:write_file).as(:write)
|
|
1069
|
-
end
|
|
1245
|
+
wrap_deferred 'with valid file paths' do
|
|
1246
|
+
let(:expected_files) { defined_files }
|
|
1070
1247
|
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1248
|
+
describe 'with a pattern that does not match any files' do
|
|
1249
|
+
let(:pattern) { '*.xml' }
|
|
1250
|
+
let(:expected_files) { [] }
|
|
1074
1251
|
|
|
1075
|
-
|
|
1076
|
-
expect { subject.write_file(stream, data) }
|
|
1077
|
-
.not_to change(stream, :string)
|
|
1252
|
+
include_deferred 'should return or yield the matching file names'
|
|
1078
1253
|
end
|
|
1079
|
-
end
|
|
1080
|
-
|
|
1081
|
-
describe 'with data: an Object' do
|
|
1082
|
-
let(:data) { Object.new.freeze }
|
|
1083
|
-
let(:stream) { StringIO.new }
|
|
1084
1254
|
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
end
|
|
1090
|
-
end
|
|
1255
|
+
describe 'with a globbed pattern' do
|
|
1256
|
+
let(:pattern) { '*.txt' }
|
|
1257
|
+
let(:expected_files) do
|
|
1258
|
+
rxp = /\A\w+\.txt\z/
|
|
1091
1259
|
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
let(:stream) { StringIO.new }
|
|
1260
|
+
defined_files.grep(rxp)
|
|
1261
|
+
end
|
|
1095
1262
|
|
|
1096
|
-
|
|
1097
|
-
expect { subject.write_file(stream, data) }
|
|
1098
|
-
.not_to change(stream, :string)
|
|
1263
|
+
include_deferred 'should return or yield the matching file names'
|
|
1099
1264
|
end
|
|
1100
|
-
end
|
|
1101
1265
|
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1266
|
+
describe 'with a globbed pattern with fixed segments' do
|
|
1267
|
+
let(:pattern) { File.join('root_dir', '*.txt') }
|
|
1268
|
+
let(:expected_files) do
|
|
1269
|
+
rxp = %r{\Aroot_dir/\w+\.txt\z}
|
|
1106
1270
|
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
.to raise_error ArgumentError, error_message
|
|
1110
|
-
end
|
|
1111
|
-
end
|
|
1271
|
+
defined_files.grep(rxp)
|
|
1272
|
+
end
|
|
1112
1273
|
|
|
1113
|
-
|
|
1114
|
-
let(:error_message) do
|
|
1115
|
-
'file is not a String or IO stream'
|
|
1274
|
+
include_deferred 'should return or yield the matching file names'
|
|
1116
1275
|
end
|
|
1117
1276
|
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
end
|
|
1277
|
+
describe 'with a globbed pattern without extension filter' do
|
|
1278
|
+
let(:pattern) { '*' }
|
|
1279
|
+
let(:expected_files) do
|
|
1280
|
+
rxp = /\A\w+(\.\w+)?\z/
|
|
1123
1281
|
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
tools.assertions.error_message_for('presence', as: :file)
|
|
1127
|
-
end
|
|
1282
|
+
defined_files.grep(rxp)
|
|
1283
|
+
end
|
|
1128
1284
|
|
|
1129
|
-
|
|
1130
|
-
expect { subject.write_file('', data) }
|
|
1131
|
-
.to raise_error ArgumentError, error_message
|
|
1285
|
+
include_deferred 'should return or yield the matching file names'
|
|
1132
1286
|
end
|
|
1133
|
-
end
|
|
1134
1287
|
|
|
1135
|
-
|
|
1136
|
-
|
|
1288
|
+
describe 'with a recursive globbed pattern' do
|
|
1289
|
+
let(:pattern) { File.join('**', '*.txt') }
|
|
1290
|
+
let(:expected_files) do
|
|
1291
|
+
rxp = /\.txt\z/
|
|
1137
1292
|
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
.to change(stream, :string)
|
|
1141
|
-
.to be == data
|
|
1142
|
-
end
|
|
1143
|
-
end
|
|
1293
|
+
defined_files.grep(rxp)
|
|
1294
|
+
end
|
|
1144
1295
|
|
|
1145
|
-
|
|
1146
|
-
let(:directory) do
|
|
1147
|
-
File.join(subject.root_path, writeable_path)
|
|
1148
|
-
end
|
|
1149
|
-
let(:path) do
|
|
1150
|
-
File.join(directory, "#{SecureRandom.uuid}.txt")
|
|
1296
|
+
include_deferred 'should return or yield the matching file names'
|
|
1151
1297
|
end
|
|
1152
1298
|
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
expect(subject.read_file(path)).to be == data
|
|
1159
|
-
end
|
|
1299
|
+
describe 'with a recursive globbed pattern with prefix' do
|
|
1300
|
+
let(:pattern) { File.join('root_dir', '**') }
|
|
1301
|
+
let(:expected_files) do
|
|
1302
|
+
rxp = %r{\Aroot_dir/}
|
|
1160
1303
|
|
|
1161
|
-
|
|
1162
|
-
let(:directory) { invalid_absolute_path }
|
|
1163
|
-
let(:error_class) do
|
|
1164
|
-
Cuprum::Cli::Dependencies::FileSystem::DirectoryNotFoundError
|
|
1165
|
-
end
|
|
1166
|
-
let(:error_message) do
|
|
1167
|
-
"unable to write file #{path} - directory not found"
|
|
1304
|
+
defined_files.grep(rxp)
|
|
1168
1305
|
end
|
|
1169
1306
|
|
|
1170
|
-
|
|
1171
|
-
expect { subject.write_file(path, data) }
|
|
1172
|
-
.to raise_error(error_class, error_message)
|
|
1173
|
-
end
|
|
1307
|
+
include_deferred 'should return or yield the matching file names'
|
|
1174
1308
|
end
|
|
1175
1309
|
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1310
|
+
describe 'with a pattern that includes the root path' do
|
|
1311
|
+
let(:pattern) { File.join(subject.root_path, '*.txt') }
|
|
1312
|
+
let(:expected_files) do
|
|
1313
|
+
rxp = /\A\w+\.txt\z/
|
|
1180
1314
|
|
|
1181
|
-
|
|
1182
|
-
|
|
1315
|
+
defined_files
|
|
1316
|
+
.map do |path|
|
|
1317
|
+
path = File.expand_path(File.join(fixtures_path, path))
|
|
1183
1318
|
|
|
1184
|
-
|
|
1185
|
-
end
|
|
1186
|
-
end
|
|
1319
|
+
next unless path.start_with?(subject.root_path)
|
|
1187
1320
|
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
let(:error_message) do
|
|
1194
|
-
"unable to write file #{path} - file is a directory"
|
|
1321
|
+
path[(1 + subject.root_path.size)...]
|
|
1322
|
+
end # rubocop:disable Style/MultilineBlockChain
|
|
1323
|
+
.compact
|
|
1324
|
+
.grep(rxp)
|
|
1325
|
+
.map { |path| File.join(subject.root_path, path) }
|
|
1195
1326
|
end
|
|
1196
1327
|
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1328
|
+
include_deferred 'should return or yield the matching file names'
|
|
1329
|
+
|
|
1330
|
+
wrap_deferred 'when initialized with root_path: value' do
|
|
1331
|
+
include_deferred 'should return or yield the matching file names'
|
|
1200
1332
|
end
|
|
1201
1333
|
end
|
|
1202
1334
|
|
|
1203
|
-
context 'when
|
|
1204
|
-
let(:
|
|
1205
|
-
let(:
|
|
1206
|
-
|
|
1335
|
+
context 'when a matching file is added to the file system' do
|
|
1336
|
+
let(:pattern) { '*.txt' }
|
|
1337
|
+
let(:added_file_path) { 'added_file.txt' }
|
|
1338
|
+
let(:expanded_added_path) do
|
|
1339
|
+
File.expand_path(File.join(fixtures_path, 'added_file.txt'))
|
|
1207
1340
|
end
|
|
1208
|
-
let(:
|
|
1209
|
-
|
|
1341
|
+
let(:expected_files) do
|
|
1342
|
+
rxp = /\A\w+\.txt\z/
|
|
1343
|
+
|
|
1344
|
+
defined_files
|
|
1345
|
+
.grep(rxp)
|
|
1346
|
+
.push(added_file_path)
|
|
1347
|
+
.sort
|
|
1210
1348
|
end
|
|
1211
1349
|
|
|
1212
1350
|
before(:example) do
|
|
1213
|
-
subject.
|
|
1214
|
-
end
|
|
1351
|
+
subject.each_file(pattern) { nil }
|
|
1215
1352
|
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1353
|
+
subject.write_file(
|
|
1354
|
+
expanded_added_path,
|
|
1355
|
+
'This file was added in the test.'
|
|
1356
|
+
)
|
|
1219
1357
|
end
|
|
1220
|
-
end
|
|
1221
1358
|
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
File.join(super(), 'missing', 'directories')
|
|
1225
|
-
end
|
|
1226
|
-
let(:error_class) do
|
|
1227
|
-
Cuprum::Cli::Dependencies::FileSystem::DirectoryNotFoundError
|
|
1228
|
-
end
|
|
1229
|
-
let(:error_message) do
|
|
1230
|
-
"unable to write file #{path} - directory not found"
|
|
1231
|
-
end
|
|
1359
|
+
after(:example) do
|
|
1360
|
+
next unless subject.file?(expanded_added_path)
|
|
1232
1361
|
|
|
1233
|
-
|
|
1234
|
-
expect { subject.write_file(path, data) }
|
|
1235
|
-
.to raise_error(error_class, error_message)
|
|
1362
|
+
subject.delete_file(expanded_added_path)
|
|
1236
1363
|
end
|
|
1364
|
+
|
|
1365
|
+
include_deferred 'should return or yield the matching file names'
|
|
1237
1366
|
end
|
|
1238
1367
|
end
|
|
1368
|
+
end
|
|
1239
1369
|
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
File.join(directory, "#{SecureRandom.uuid}.txt")
|
|
1246
|
-
end
|
|
1370
|
+
describe '#file?' do
|
|
1371
|
+
define_method :check_file do
|
|
1372
|
+
subject.file?(path)
|
|
1373
|
+
end
|
|
1374
|
+
alias_method :call_method, :check_file
|
|
1247
1375
|
|
|
1248
|
-
|
|
1376
|
+
it 'should define the method' do
|
|
1377
|
+
expect(subject).to respond_to(:file?).with(1).argument
|
|
1378
|
+
end
|
|
1249
1379
|
|
|
1250
|
-
|
|
1251
|
-
|
|
1380
|
+
it 'should define the aliased method' do
|
|
1381
|
+
expect(subject)
|
|
1382
|
+
.to have_aliased_method(:file?)
|
|
1383
|
+
.as(:file_exists?)
|
|
1384
|
+
end
|
|
1252
1385
|
|
|
1253
|
-
|
|
1254
|
-
end
|
|
1386
|
+
include_deferred 'should validate the path'
|
|
1255
1387
|
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
let(:error_class) do
|
|
1259
|
-
Cuprum::Cli::Dependencies::FileSystem::DirectoryNotFoundError
|
|
1260
|
-
end
|
|
1261
|
-
let(:error_message) do
|
|
1262
|
-
"unable to write file #{path} - directory not found"
|
|
1263
|
-
end
|
|
1388
|
+
describe 'with an invalid absolute path' do
|
|
1389
|
+
let(:path) { invalid_absolute_path }
|
|
1264
1390
|
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1391
|
+
it { expect(subject.file?(path)).to be false }
|
|
1392
|
+
end
|
|
1393
|
+
|
|
1394
|
+
describe 'with an invalid qualified path' do
|
|
1395
|
+
let(:path) { invalid_qualified_path }
|
|
1396
|
+
|
|
1397
|
+
it { expect(subject.file?(path)).to be false }
|
|
1398
|
+
end
|
|
1399
|
+
|
|
1400
|
+
describe 'with an invalid relative path' do
|
|
1401
|
+
let(:path) { invalid_relative_path }
|
|
1402
|
+
|
|
1403
|
+
it { expect(subject.file?(path)).to be false }
|
|
1404
|
+
end
|
|
1405
|
+
|
|
1406
|
+
wrap_deferred 'with valid file paths' do
|
|
1407
|
+
describe 'with an absolute path to a directory' do
|
|
1408
|
+
let(:path) { absolute_directory_path }
|
|
1409
|
+
|
|
1410
|
+
it { expect(subject.file?(path)).to be false }
|
|
1269
1411
|
end
|
|
1270
1412
|
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
subject.write_file(path, "Existing contents...\n")
|
|
1274
|
-
end
|
|
1413
|
+
describe 'with an absolute path to a file' do
|
|
1414
|
+
let(:path) { absolute_file_path }
|
|
1275
1415
|
|
|
1276
|
-
it
|
|
1277
|
-
|
|
1416
|
+
it { expect(subject.file?(path)).to be true }
|
|
1417
|
+
end
|
|
1278
1418
|
|
|
1279
|
-
|
|
1280
|
-
|
|
1419
|
+
describe 'with a qualified path to a directory' do
|
|
1420
|
+
let(:path) { qualified_directory_path }
|
|
1421
|
+
|
|
1422
|
+
it { expect(subject.file?(path)).to be false }
|
|
1281
1423
|
end
|
|
1282
1424
|
|
|
1283
|
-
|
|
1284
|
-
let(:path) {
|
|
1285
|
-
let(:error_class) do
|
|
1286
|
-
Cuprum::Cli::Dependencies::FileSystem::FileIsADirectoryError
|
|
1287
|
-
end
|
|
1288
|
-
let(:error_message) do
|
|
1289
|
-
"unable to write file #{path} - file is a directory"
|
|
1290
|
-
end
|
|
1425
|
+
describe 'with a qualified path to a file' do
|
|
1426
|
+
let(:path) { qualified_file_path }
|
|
1291
1427
|
|
|
1292
|
-
it
|
|
1293
|
-
expect { subject.write_file(path, data) }
|
|
1294
|
-
.to raise_error(error_class, error_message)
|
|
1295
|
-
end
|
|
1428
|
+
it { expect(subject.file?(path)).to be true }
|
|
1296
1429
|
end
|
|
1297
1430
|
|
|
1298
|
-
|
|
1299
|
-
let(:
|
|
1300
|
-
let(:error_class) do
|
|
1301
|
-
Cuprum::Cli::Dependencies::FileSystem::DirectoryIsAFileError
|
|
1302
|
-
end
|
|
1303
|
-
let(:error_message) do
|
|
1304
|
-
"unable to write file #{path} - directory is a file"
|
|
1305
|
-
end
|
|
1431
|
+
describe 'with a relative path to a directory' do
|
|
1432
|
+
let(:path) { relative_directory_path }
|
|
1306
1433
|
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
end
|
|
1434
|
+
it { expect(subject.file?(path)).to be false }
|
|
1435
|
+
end
|
|
1310
1436
|
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1437
|
+
describe 'with a relative path to a file' do
|
|
1438
|
+
let(:path) { relative_file_path }
|
|
1439
|
+
|
|
1440
|
+
it { expect(subject.file?(path)).to be true }
|
|
1315
1441
|
end
|
|
1316
1442
|
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1443
|
+
wrap_deferred 'when initialized with root_path: value' do
|
|
1444
|
+
describe 'with a qualified path to a directory' do
|
|
1445
|
+
let(:path) { qualified_directory_path }
|
|
1446
|
+
|
|
1447
|
+
it { expect(subject.file?(path)).to be false }
|
|
1320
1448
|
end
|
|
1321
|
-
|
|
1322
|
-
|
|
1449
|
+
|
|
1450
|
+
describe 'with a qualified path to a file' do
|
|
1451
|
+
let(:path) { qualified_file_path }
|
|
1452
|
+
|
|
1453
|
+
it { expect(subject.file?(path)).to be true }
|
|
1323
1454
|
end
|
|
1324
|
-
|
|
1325
|
-
|
|
1455
|
+
|
|
1456
|
+
describe 'with a relative path to a directory' do
|
|
1457
|
+
let(:path) { relative_directory_path }
|
|
1458
|
+
|
|
1459
|
+
it { expect(subject.file?(path)).to be false }
|
|
1326
1460
|
end
|
|
1327
1461
|
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1462
|
+
describe 'with a relative path to a file' do
|
|
1463
|
+
let(:path) { relative_file_path }
|
|
1464
|
+
|
|
1465
|
+
it { expect(subject.file?(path)).to be true }
|
|
1331
1466
|
end
|
|
1332
1467
|
end
|
|
1333
1468
|
end
|
|
1469
|
+
end
|
|
1334
1470
|
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1471
|
+
describe '#read_file' do
|
|
1472
|
+
deferred_examples 'should read the file' do
|
|
1473
|
+
it { expect(subject.read_file(file)).to be == expected_contents }
|
|
1474
|
+
end
|
|
1475
|
+
|
|
1476
|
+
deferred_examples 'should read the file for a valid path' do
|
|
1477
|
+
include_deferred 'should read the file'
|
|
1478
|
+
|
|
1479
|
+
include_deferred 'should handle a directory when a file is expected',
|
|
1480
|
+
:file
|
|
1481
|
+
end
|
|
1482
|
+
|
|
1483
|
+
let(:expected_contents) do
|
|
1484
|
+
path = file
|
|
1485
|
+
|
|
1486
|
+
unless path.start_with?('/')
|
|
1487
|
+
path = File.expand_path(File.join(subject.root_path, path))
|
|
1338
1488
|
end
|
|
1339
|
-
|
|
1340
|
-
|
|
1489
|
+
|
|
1490
|
+
path = path.sub(%r{\A#{File.expand_path(fixtures_path)}/?}, '')
|
|
1491
|
+
|
|
1492
|
+
read_fixture(path)
|
|
1493
|
+
end
|
|
1494
|
+
let(:file) { nil }
|
|
1495
|
+
let(:error_reason) { "unable to read file #{file}" }
|
|
1496
|
+
|
|
1497
|
+
define_method :read_file do
|
|
1498
|
+
subject.read_file(file)
|
|
1499
|
+
end
|
|
1500
|
+
alias_method :call_method, :read_file
|
|
1501
|
+
|
|
1502
|
+
define_method :safe_read_file do
|
|
1503
|
+
read_file
|
|
1504
|
+
rescue StandardError
|
|
1505
|
+
nil
|
|
1506
|
+
end
|
|
1507
|
+
|
|
1508
|
+
it { expect(subject).to respond_to(:read_file).with(1).argument }
|
|
1509
|
+
|
|
1510
|
+
it 'should define the aliased method' do
|
|
1511
|
+
expect(subject).to have_aliased_method(:read_file).as(:read)
|
|
1512
|
+
end
|
|
1513
|
+
|
|
1514
|
+
include_deferred 'should validate the file or path', :file
|
|
1515
|
+
|
|
1516
|
+
describe 'with an IO stream' do
|
|
1517
|
+
let(:stream) { StringIO.new('Greetings, programs!') }
|
|
1518
|
+
|
|
1519
|
+
it { expect(subject.read_file(stream)).to be == stream.string }
|
|
1520
|
+
end
|
|
1521
|
+
|
|
1522
|
+
include_deferred 'should handle a path with missing file', :file
|
|
1523
|
+
|
|
1524
|
+
wrap_deferred 'with valid file paths' do
|
|
1525
|
+
describe 'with an absolute path' do
|
|
1526
|
+
let(:file) { absolute_file_path }
|
|
1527
|
+
|
|
1528
|
+
include_deferred 'should read the file for a valid path'
|
|
1341
1529
|
end
|
|
1342
1530
|
|
|
1343
|
-
|
|
1531
|
+
describe 'with a qualified path' do
|
|
1532
|
+
let(:file) { qualified_file_path }
|
|
1344
1533
|
|
|
1345
|
-
|
|
1346
|
-
|
|
1534
|
+
include_deferred 'should read the file for a valid path'
|
|
1535
|
+
end
|
|
1347
1536
|
|
|
1348
|
-
|
|
1537
|
+
describe 'with a relative path' do
|
|
1538
|
+
let(:file) { relative_file_path }
|
|
1539
|
+
|
|
1540
|
+
include_deferred 'should read the file for a valid path'
|
|
1349
1541
|
end
|
|
1350
1542
|
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
let(:error_message) do
|
|
1357
|
-
"unable to write file #{path} - directory not found"
|
|
1543
|
+
wrap_deferred 'when initialized with root_path: value' do
|
|
1544
|
+
describe 'with a qualified path' do
|
|
1545
|
+
let(:file) { qualified_file_path }
|
|
1546
|
+
|
|
1547
|
+
include_deferred 'should read the file for a valid path'
|
|
1358
1548
|
end
|
|
1359
1549
|
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1550
|
+
describe 'with a relative path' do
|
|
1551
|
+
let(:file) { relative_file_path }
|
|
1552
|
+
|
|
1553
|
+
include_deferred 'should read the file for a valid path'
|
|
1363
1554
|
end
|
|
1364
1555
|
end
|
|
1556
|
+
end
|
|
1557
|
+
end
|
|
1365
1558
|
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
subject.write_file(path, "Existing contents...\n")
|
|
1369
|
-
end
|
|
1559
|
+
describe '#root_path' do
|
|
1560
|
+
include_examples 'should define reader', :root_path, Dir.pwd
|
|
1370
1561
|
|
|
1371
|
-
|
|
1372
|
-
|
|
1562
|
+
wrap_deferred 'when initialized with root_path: value' do
|
|
1563
|
+
it { expect(subject.root_path).to be == root_path }
|
|
1564
|
+
end
|
|
1565
|
+
end
|
|
1373
1566
|
|
|
1374
|
-
|
|
1375
|
-
|
|
1567
|
+
describe '#with_tempfile' do
|
|
1568
|
+
let(:expected_tempfile) do
|
|
1569
|
+
respond_to(:read)
|
|
1570
|
+
.and(respond_to(:write)
|
|
1571
|
+
.and(respond_to(:path)))
|
|
1572
|
+
end
|
|
1573
|
+
|
|
1574
|
+
it 'should define the method' do
|
|
1575
|
+
expect(subject)
|
|
1576
|
+
.to respond_to(:with_tempfile)
|
|
1577
|
+
.with(0).arguments
|
|
1578
|
+
.and_a_block
|
|
1579
|
+
end
|
|
1580
|
+
|
|
1581
|
+
it 'should yield the file object' do
|
|
1582
|
+
expect { |block| subject.with_tempfile(&block) }
|
|
1583
|
+
.to yield_with_args(expected_tempfile)
|
|
1584
|
+
end
|
|
1585
|
+
end
|
|
1586
|
+
|
|
1587
|
+
describe '#write_file' do
|
|
1588
|
+
deferred_examples 'should not write the file' do
|
|
1589
|
+
it 'should not write the file', :aggregate_failures do
|
|
1590
|
+
existing_file = subject.file?(file)
|
|
1591
|
+
existing_contents = subject.read_file(file) if existing_file
|
|
1592
|
+
|
|
1593
|
+
expect { safe_write_file }.not_to(change { subject.file?(file) })
|
|
1594
|
+
|
|
1595
|
+
next unless existing_file
|
|
1596
|
+
|
|
1597
|
+
expect(subject.read_file(file)).to eq(existing_contents)
|
|
1376
1598
|
end
|
|
1599
|
+
end
|
|
1377
1600
|
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
end
|
|
1601
|
+
deferred_examples 'should create the file' do
|
|
1602
|
+
it 'should create the file' do
|
|
1603
|
+
expect { write_file }.to(
|
|
1604
|
+
change { subject.file?(file) }.to(be true)
|
|
1605
|
+
)
|
|
1606
|
+
end
|
|
1607
|
+
end
|
|
1386
1608
|
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1609
|
+
deferred_examples 'should write the data to the file' do
|
|
1610
|
+
it 'should write the data to the file' do
|
|
1611
|
+
write_file
|
|
1612
|
+
|
|
1613
|
+
expect(subject.read_file(file)).to be == data
|
|
1391
1614
|
end
|
|
1615
|
+
end
|
|
1392
1616
|
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
let(:error_class) do
|
|
1396
|
-
Cuprum::Cli::Dependencies::FileSystem::DirectoryIsAFileError
|
|
1397
|
-
end
|
|
1398
|
-
let(:error_message) do
|
|
1399
|
-
"unable to write file #{path} - directory is a file"
|
|
1400
|
-
end
|
|
1617
|
+
deferred_examples 'should write the file for a valid path' do
|
|
1618
|
+
include_deferred 'should create the file'
|
|
1401
1619
|
|
|
1402
|
-
|
|
1403
|
-
subject.write_file(directory, "Existing contents...\n")
|
|
1404
|
-
end
|
|
1620
|
+
include_deferred 'should write the data to the file'
|
|
1405
1621
|
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1622
|
+
include_deferred 'should handle a path with missing directory',
|
|
1623
|
+
:file \
|
|
1624
|
+
do
|
|
1625
|
+
include_deferred 'should not write the file'
|
|
1410
1626
|
end
|
|
1411
1627
|
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
Cuprum::Cli::Dependencies::FileSystem::DirectoryNotFoundError
|
|
1418
|
-
end
|
|
1419
|
-
let(:error_message) do
|
|
1420
|
-
"unable to write file #{path} - directory not found"
|
|
1421
|
-
end
|
|
1628
|
+
include_deferred 'should handle a directory when a file is expected',
|
|
1629
|
+
:file \
|
|
1630
|
+
do
|
|
1631
|
+
include_deferred 'should not write the file'
|
|
1632
|
+
end
|
|
1422
1633
|
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1634
|
+
context 'when the file already exists' do
|
|
1635
|
+
let(:file) do
|
|
1636
|
+
if absolute_path?(super())
|
|
1637
|
+
absolute_file_path
|
|
1638
|
+
elsif qualified_path?(super())
|
|
1639
|
+
qualified_file_path
|
|
1640
|
+
else
|
|
1641
|
+
relative_file_path
|
|
1642
|
+
end
|
|
1426
1643
|
end
|
|
1644
|
+
|
|
1645
|
+
include_deferred 'should write the data to the file'
|
|
1646
|
+
end
|
|
1647
|
+
|
|
1648
|
+
include_deferred 'should handle a path that includes a file',
|
|
1649
|
+
:file \
|
|
1650
|
+
do
|
|
1651
|
+
include_deferred 'should not write the file'
|
|
1652
|
+
end
|
|
1653
|
+
|
|
1654
|
+
include_deferred 'should handle a path with missing directory',
|
|
1655
|
+
:file \
|
|
1656
|
+
do
|
|
1657
|
+
include_deferred 'should not write the file'
|
|
1427
1658
|
end
|
|
1428
1659
|
end
|
|
1429
1660
|
|
|
1430
|
-
|
|
1431
|
-
|
|
1661
|
+
let(:file) { "#{SecureRandom.uuid}.txt" }
|
|
1662
|
+
let(:data) { "Greetings, programs!\n" }
|
|
1663
|
+
let(:error_reason) { "unable to write file #{file}" }
|
|
1432
1664
|
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1665
|
+
define_method :write_file do
|
|
1666
|
+
subject.write_file(file, data)
|
|
1667
|
+
end
|
|
1668
|
+
alias_method :call_method, :write_file
|
|
1669
|
+
|
|
1670
|
+
define_method :safe_write_file do
|
|
1671
|
+
write_file
|
|
1672
|
+
rescue StandardError
|
|
1673
|
+
nil
|
|
1674
|
+
end
|
|
1675
|
+
|
|
1676
|
+
it { expect(subject).to respond_to(:write_file).with(2).arguments }
|
|
1677
|
+
|
|
1678
|
+
it 'should define the aliased method' do
|
|
1679
|
+
expect(subject).to have_aliased_method(:write_file).as(:write)
|
|
1680
|
+
end
|
|
1681
|
+
|
|
1682
|
+
include_deferred 'should validate the file or path', :file
|
|
1683
|
+
|
|
1684
|
+
describe 'with data: nil' do
|
|
1685
|
+
let(:data) { nil }
|
|
1686
|
+
let(:stream) { StringIO.new }
|
|
1687
|
+
|
|
1688
|
+
it 'should not write to the stream' do
|
|
1689
|
+
expect { subject.write_file(stream, data) }
|
|
1690
|
+
.not_to change(stream, :string)
|
|
1691
|
+
end
|
|
1692
|
+
end
|
|
1693
|
+
|
|
1694
|
+
describe 'with data: an Object' do
|
|
1695
|
+
let(:data) { Object.new.freeze }
|
|
1696
|
+
let(:stream) { StringIO.new }
|
|
1697
|
+
|
|
1698
|
+
it 'should write the object to the stream' do
|
|
1699
|
+
expect { subject.write_file(stream, data) }
|
|
1700
|
+
.to change(stream, :string)
|
|
1701
|
+
.to be == data.inspect
|
|
1702
|
+
end
|
|
1703
|
+
end
|
|
1704
|
+
|
|
1705
|
+
describe 'with data: an empty String' do
|
|
1706
|
+
let(:data) { '' }
|
|
1707
|
+
let(:stream) { StringIO.new }
|
|
1708
|
+
|
|
1709
|
+
it 'should not write to the stream' do
|
|
1710
|
+
expect { subject.write_file(stream, data) }
|
|
1711
|
+
.not_to change(stream, :string)
|
|
1712
|
+
end
|
|
1713
|
+
end
|
|
1714
|
+
|
|
1715
|
+
describe 'with file: an IO stream' do
|
|
1716
|
+
let(:stream) { StringIO.new }
|
|
1717
|
+
|
|
1718
|
+
it 'should write the data to the stream' do
|
|
1719
|
+
expect { subject.write_file(stream, data) }
|
|
1720
|
+
.to change(stream, :string)
|
|
1721
|
+
.to be == data
|
|
1722
|
+
end
|
|
1723
|
+
end
|
|
1724
|
+
|
|
1725
|
+
wrap_deferred 'with valid file paths' do
|
|
1726
|
+
describe 'with an absolute path' do
|
|
1727
|
+
let(:file) do
|
|
1728
|
+
File.join(absolute_directory_path, "#{SecureRandom.uuid}.txt")
|
|
1442
1729
|
end
|
|
1443
1730
|
|
|
1444
|
-
|
|
1445
|
-
|
|
1731
|
+
include_deferred 'should write the file for a valid path'
|
|
1732
|
+
end
|
|
1446
1733
|
|
|
1447
|
-
|
|
1734
|
+
describe 'with a qualified path' do
|
|
1735
|
+
let(:file) do
|
|
1736
|
+
File.join(qualified_directory_path, "#{SecureRandom.uuid}.txt")
|
|
1448
1737
|
end
|
|
1738
|
+
|
|
1739
|
+
include_deferred 'should write the file for a valid path'
|
|
1449
1740
|
end
|
|
1450
1741
|
|
|
1451
1742
|
describe 'with a relative path' do
|
|
1452
|
-
let(:
|
|
1453
|
-
File.join(
|
|
1743
|
+
let(:file) do
|
|
1744
|
+
File.join(relative_directory_path, "#{SecureRandom.uuid}.txt")
|
|
1454
1745
|
end
|
|
1455
|
-
|
|
1456
|
-
|
|
1746
|
+
|
|
1747
|
+
include_deferred 'should write the file for a valid path'
|
|
1748
|
+
end
|
|
1749
|
+
|
|
1750
|
+
wrap_deferred 'when initialized with root_path: value' do
|
|
1751
|
+
describe 'with a qualified path' do
|
|
1752
|
+
let(:file) do
|
|
1753
|
+
File.join(qualified_directory_path, "#{SecureRandom.uuid}.txt")
|
|
1754
|
+
end
|
|
1755
|
+
|
|
1756
|
+
include_deferred 'should write the file for a valid path'
|
|
1457
1757
|
end
|
|
1458
1758
|
|
|
1459
|
-
|
|
1460
|
-
|
|
1759
|
+
describe 'with a relative path' do
|
|
1760
|
+
let(:file) do
|
|
1761
|
+
File.join(relative_directory_path, "#{SecureRandom.uuid}.txt")
|
|
1762
|
+
end
|
|
1461
1763
|
|
|
1462
|
-
|
|
1764
|
+
include_deferred 'should write the file for a valid path'
|
|
1463
1765
|
end
|
|
1464
1766
|
end
|
|
1465
1767
|
end
|