tap 0.7.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (146) hide show
  1. data/MIT-LICENSE +21 -0
  2. data/README +71 -0
  3. data/Rakefile +117 -0
  4. data/bin/tap +63 -0
  5. data/lib/tap.rb +15 -0
  6. data/lib/tap/app.rb +739 -0
  7. data/lib/tap/file_task.rb +354 -0
  8. data/lib/tap/generator.rb +29 -0
  9. data/lib/tap/generator/generators/config/USAGE +0 -0
  10. data/lib/tap/generator/generators/config/config_generator.rb +23 -0
  11. data/lib/tap/generator/generators/config/templates/config.erb +2 -0
  12. data/lib/tap/generator/generators/file_task/USAGE +0 -0
  13. data/lib/tap/generator/generators/file_task/file_task_generator.rb +21 -0
  14. data/lib/tap/generator/generators/file_task/templates/task.erb +27 -0
  15. data/lib/tap/generator/generators/file_task/templates/test.erb +12 -0
  16. data/lib/tap/generator/generators/root/USAGE +0 -0
  17. data/lib/tap/generator/generators/root/root_generator.rb +36 -0
  18. data/lib/tap/generator/generators/root/templates/Rakefile +48 -0
  19. data/lib/tap/generator/generators/root/templates/app.yml +19 -0
  20. data/lib/tap/generator/generators/root/templates/config/process_tap_request.yml +4 -0
  21. data/lib/tap/generator/generators/root/templates/lib/process_tap_request.rb +26 -0
  22. data/lib/tap/generator/generators/root/templates/public/images/nav.jpg +0 -0
  23. data/lib/tap/generator/generators/root/templates/public/stylesheets/color.css +57 -0
  24. data/lib/tap/generator/generators/root/templates/public/stylesheets/layout.css +108 -0
  25. data/lib/tap/generator/generators/root/templates/public/stylesheets/normalize.css +40 -0
  26. data/lib/tap/generator/generators/root/templates/public/stylesheets/typography.css +21 -0
  27. data/lib/tap/generator/generators/root/templates/server/config/environment.rb +60 -0
  28. data/lib/tap/generator/generators/root/templates/server/lib/tasks/clear_database_prerequisites.rake +5 -0
  29. data/lib/tap/generator/generators/root/templates/server/test/test_helper.rb +53 -0
  30. data/lib/tap/generator/generators/root/templates/test/tap_test_helper.rb +3 -0
  31. data/lib/tap/generator/generators/root/templates/test/tap_test_suite.rb +4 -0
  32. data/lib/tap/generator/generators/task/USAGE +0 -0
  33. data/lib/tap/generator/generators/task/task_generator.rb +21 -0
  34. data/lib/tap/generator/generators/task/templates/task.erb +21 -0
  35. data/lib/tap/generator/generators/task/templates/test.erb +29 -0
  36. data/lib/tap/generator/generators/workflow/USAGE +0 -0
  37. data/lib/tap/generator/generators/workflow/templates/task.erb +16 -0
  38. data/lib/tap/generator/generators/workflow/templates/test.erb +7 -0
  39. data/lib/tap/generator/generators/workflow/workflow_generator.rb +21 -0
  40. data/lib/tap/generator/options.rb +26 -0
  41. data/lib/tap/generator/usage.rb +26 -0
  42. data/lib/tap/root.rb +275 -0
  43. data/lib/tap/script/console.rb +7 -0
  44. data/lib/tap/script/destroy.rb +8 -0
  45. data/lib/tap/script/generate.rb +8 -0
  46. data/lib/tap/script/run.rb +111 -0
  47. data/lib/tap/script/server.rb +12 -0
  48. data/lib/tap/support/audit.rb +415 -0
  49. data/lib/tap/support/batch_queue.rb +165 -0
  50. data/lib/tap/support/combinator.rb +114 -0
  51. data/lib/tap/support/logger.rb +91 -0
  52. data/lib/tap/support/rap.rb +38 -0
  53. data/lib/tap/support/run_error.rb +20 -0
  54. data/lib/tap/support/template.rb +81 -0
  55. data/lib/tap/support/templater.rb +155 -0
  56. data/lib/tap/support/versions.rb +63 -0
  57. data/lib/tap/task.rb +448 -0
  58. data/lib/tap/test.rb +320 -0
  59. data/lib/tap/test/env_vars.rb +16 -0
  60. data/lib/tap/test/inference_methods.rb +298 -0
  61. data/lib/tap/test/subset_methods.rb +260 -0
  62. data/lib/tap/version.rb +3 -0
  63. data/lib/tap/workflow.rb +73 -0
  64. data/test/app/config/addition_template.yml +6 -0
  65. data/test/app/config/batch.yml +2 -0
  66. data/test/app/config/empty.yml +0 -0
  67. data/test/app/config/erb.yml +1 -0
  68. data/test/app/config/template.yml +6 -0
  69. data/test/app/config/version-0.1.yml +1 -0
  70. data/test/app/config/version.yml +1 -0
  71. data/test/app/lib/app_test_task.rb +2 -0
  72. data/test/app_class_test.rb +33 -0
  73. data/test/app_test.rb +1372 -0
  74. data/test/file_task/config/batch.yml +2 -0
  75. data/test/file_task/config/configured.yml +1 -0
  76. data/test/file_task/old_file_one.txt +0 -0
  77. data/test/file_task/old_file_two.txt +0 -0
  78. data/test/file_task_test.rb +1041 -0
  79. data/test/root/alt_lib/alt_module.rb +4 -0
  80. data/test/root/lib/absolute_alt_filepath.rb +2 -0
  81. data/test/root/lib/alternative_filepath.rb +2 -0
  82. data/test/root/lib/another_module.rb +2 -0
  83. data/test/root/lib/nested/some_module.rb +4 -0
  84. data/test/root/lib/no_module_included.rb +0 -0
  85. data/test/root/lib/some/module.rb +4 -0
  86. data/test/root/lib/some_class.rb +2 -0
  87. data/test/root/lib/some_module.rb +3 -0
  88. data/test/root/load_path/load_path_module.rb +2 -0
  89. data/test/root/load_path/skip_module.rb +2 -0
  90. data/test/root/mtime/older.txt +0 -0
  91. data/test/root/unload/full_path.rb +2 -0
  92. data/test/root/unload/loaded_by_nested.rb +2 -0
  93. data/test/root/unload/nested/nested_load.rb +6 -0
  94. data/test/root/unload/nested/nested_with_ext.rb +4 -0
  95. data/test/root/unload/nested/relative_path.rb +4 -0
  96. data/test/root/unload/older.rb +2 -0
  97. data/test/root/unload/unload_base.rb +9 -0
  98. data/test/root/versions/another.yml +0 -0
  99. data/test/root/versions/file-0.1.2.yml +0 -0
  100. data/test/root/versions/file-0.1.yml +0 -0
  101. data/test/root/versions/file.yml +0 -0
  102. data/test/root_test.rb +483 -0
  103. data/test/support/audit_test.rb +449 -0
  104. data/test/support/batch_queue_test.rb +320 -0
  105. data/test/support/combinator_test.rb +249 -0
  106. data/test/support/logger_test.rb +31 -0
  107. data/test/support/template_test.rb +122 -0
  108. data/test/support/templater/erb.txt +2 -0
  109. data/test/support/templater/erb.yml +2 -0
  110. data/test/support/templater/somefile.txt +2 -0
  111. data/test/support/templater_test.rb +192 -0
  112. data/test/support/versions_test.rb +71 -0
  113. data/test/tap_test_helper.rb +4 -0
  114. data/test/tap_test_suite.rb +4 -0
  115. data/test/task/config/batch.yml +2 -0
  116. data/test/task/config/batched.yml +2 -0
  117. data/test/task/config/configured.yml +1 -0
  118. data/test/task/config/example.yml +1 -0
  119. data/test/task/config/overriding.yml +2 -0
  120. data/test/task/config/task_with_config.yml +1 -0
  121. data/test/task/config/template.yml +4 -0
  122. data/test/task_class_test.rb +118 -0
  123. data/test/task_execute_test.rb +233 -0
  124. data/test/task_test.rb +424 -0
  125. data/test/test/inference_methods/test_assert_expected/expected/file.txt +1 -0
  126. data/test/test/inference_methods/test_assert_expected/expected/folder/file.txt +1 -0
  127. data/test/test/inference_methods/test_assert_expected/input/file.txt +1 -0
  128. data/test/test/inference_methods/test_assert_expected/input/folder/file.txt +1 -0
  129. data/test/test/inference_methods/test_assert_files_exist/input/input_1.txt +0 -0
  130. data/test/test/inference_methods/test_assert_files_exist/input/input_2.txt +0 -0
  131. data/test/test/inference_methods/test_file_compare/expected/output_1.txt +3 -0
  132. data/test/test/inference_methods/test_file_compare/expected/output_2.txt +1 -0
  133. data/test/test/inference_methods/test_file_compare/input/input_1.txt +3 -0
  134. data/test/test/inference_methods/test_file_compare/input/input_2.txt +3 -0
  135. data/test/test/inference_methods/test_infer_glob/expected/file.yml +0 -0
  136. data/test/test/inference_methods/test_infer_glob/expected/file_1.txt +0 -0
  137. data/test/test/inference_methods/test_infer_glob/expected/file_2.txt +0 -0
  138. data/test/test/inference_methods/test_yml_compare/expected/output_1.yml +6 -0
  139. data/test/test/inference_methods/test_yml_compare/expected/output_2.yml +6 -0
  140. data/test/test/inference_methods/test_yml_compare/input/input_1.yml +4 -0
  141. data/test/test/inference_methods/test_yml_compare/input/input_2.yml +4 -0
  142. data/test/test/inference_methods_test.rb +311 -0
  143. data/test/test/subset_methods_test.rb +115 -0
  144. data/test/test_test.rb +233 -0
  145. data/test/workflow_test.rb +108 -0
  146. metadata +274 -0
@@ -0,0 +1,2 @@
1
+ - one: one
2
+ - two: two
@@ -0,0 +1 @@
1
+ config: value
File without changes
File without changes
@@ -0,0 +1,1041 @@
1
+ require File.join(File.dirname(__FILE__), 'tap_test_helper')
2
+ require 'tap/file_task'
3
+
4
+ class FileTaskTest < Test::Unit::TestCase
5
+ acts_as_tap_test
6
+
7
+ attr_reader :t
8
+
9
+ def setup
10
+ super
11
+ @t = Tap::FileTask.new
12
+ end
13
+
14
+ def touch_file(path, content=nil)
15
+ FileUtils.mkdir_p(File.dirname(path))
16
+ if content
17
+ File.open(path, "w") {|f| f << content}
18
+ else
19
+ FileUtils.touch(path)
20
+ end
21
+ end
22
+
23
+ def test_touch_file
24
+ non_existant_file = infer_filepath(:output, "non_existant_file.txt")
25
+ assert !File.exists?(non_existant_file)
26
+ touch_file(non_existant_file)
27
+ assert File.exists?(non_existant_file)
28
+ assert File.file?(non_existant_file)
29
+ assert_equal "", File.read(non_existant_file)
30
+
31
+ non_existant_file = infer_filepath(:output, "non_existant_file2.txt")
32
+ assert !File.exists?(non_existant_file)
33
+ touch_file(non_existant_file, "content")
34
+ assert File.exists?(non_existant_file)
35
+ assert File.file?(non_existant_file)
36
+ assert_equal "content", File.read(non_existant_file)
37
+ end
38
+
39
+ #
40
+ # dirname tests
41
+ #
42
+
43
+ def test_dirname_returns_default_dirname_by_default
44
+ assert_equal "tap/file_task", t.dirname
45
+
46
+ t = Tap::FileTask.new "batch"
47
+ assert_equal 2, t.batch.size
48
+ t1, t2 = t.batch
49
+ assert_equal "batch_0", t1.dirname
50
+ assert_equal "batch_1", t2.dirname
51
+ end
52
+
53
+ def test_dirname_returns_dirname_if_set
54
+ t.dirname = "name"
55
+ assert_equal "name", t.dirname
56
+ end
57
+
58
+ #
59
+ # inference tests
60
+ #
61
+
62
+ def test_inference_sets_inference_block
63
+ block = lambda {}
64
+ t.inference(&block)
65
+ assert_equal block, t.inference_block
66
+ end
67
+
68
+ def test_inference_can_only_be_set_once
69
+ t.inference {}
70
+ assert_raise(RuntimeError) { t.inference {} }
71
+ assert_raise(RuntimeError) { t.inference }
72
+ end
73
+
74
+ #
75
+ # infer_filepath tests
76
+ #
77
+
78
+ def test_infer_filepath_passes_app_dir_dirname_and_path_to_block
79
+ t.inference do |root, dir, path|
80
+ [root, dir, path]
81
+ end
82
+
83
+ assert_equal "tap/file_task", t.dirname
84
+ assert_equal [app[:dir], "tap/file_task", "path"], t.infer_filepath(:dir, "path")
85
+ end
86
+
87
+ def test_infer_filepath_with_multiple_paths
88
+ t.inference do |root, dir, *paths|
89
+ [root, dir, paths]
90
+ end
91
+ assert_equal [app[:dir], "tap/file_task", ["path", "to", "file"]], t.infer_filepath(:dir, "path", "to", "file")
92
+ end
93
+
94
+ def test_infer_filepath_with_multiple_paths_but_single_path_given
95
+ t.inference do |root, dir, *paths|
96
+ [root, dir, paths]
97
+ end
98
+ assert_equal [app[:dir], "tap/file_task", ["path"]], t.infer_filepath(:dir, "path")
99
+
100
+ t.inference(true) do |root, dir, path_a, path_b|
101
+ [root, dir, path_a, path_b]
102
+ end
103
+ assert_equal [app[:dir], "tap/file_task", "path", nil], t.infer_filepath(:dir, "path")
104
+ end
105
+
106
+ def test_infer_filepath_with_single_path_but_multiple_paths_given
107
+ t.inference do |root, dir, path|
108
+ [root, dir, path]
109
+ end
110
+ assert_equal [app[:dir], "tap/file_task", "path"], t.infer_filepath(:dir, "path", "to", "file")
111
+ end
112
+
113
+ def test_infer_filepath_constructs_path_using_app_filepath_when_inference_block_is_not_set
114
+ assert_nil t.inference_block
115
+ assert_equal(
116
+ app.filepath(:dir, "tap/file_task", "path", "to", "file"),
117
+ t.infer_filepath(:dir, "path", "to", "file"))
118
+ end
119
+
120
+ #
121
+ # backup_filepath test
122
+ #
123
+
124
+ def prepare_backup_filepath_with_output_and_timestamp
125
+ timestamp_format = "%Y%m%d"
126
+ timestamp = Time.now.strftime(timestamp_format)
127
+
128
+ t.backup_dir = :output
129
+ t.backup_timestamp = timestamp_format
130
+
131
+ timestamp
132
+ end
133
+
134
+ def test_backup_filepath_infers_filepath_using_backup_dir_and_timestamp
135
+ timestamp = prepare_backup_filepath_with_output_and_timestamp
136
+
137
+ assert_equal(
138
+ app.filepath(:output, t.name, "file_#{timestamp}.txt"),
139
+ t.backup_filepath("file.txt"))
140
+ end
141
+
142
+ def test_backup_filepath_uses_inference_block
143
+ timestamp = prepare_backup_filepath_with_output_and_timestamp
144
+
145
+ t.inference do |root, dir, path|
146
+ [root, dir, path]
147
+ end
148
+
149
+ assert_equal(
150
+ [app[:output], "tap/file_task", "file_#{timestamp}.txt"],
151
+ t.backup_filepath("file.txt"))
152
+ end
153
+
154
+ def test_backup_filepath_uses_path_relative_to_dirname_if_input_is_relative_to_dirname
155
+ timestamp = prepare_backup_filepath_with_output_and_timestamp
156
+
157
+ t.inference do |root, dir, path|
158
+ [root, dir, path]
159
+ end
160
+
161
+ assert_equal("tap/file_task", t.dirname)
162
+ assert_equal(
163
+ [app[:output], t.name, "path/to/file_#{timestamp}.txt"],
164
+ t.backup_filepath("folder/tap/file_task/path/to/file.txt"))
165
+ end
166
+
167
+ def test_backup_filepath_uses_the_input_basename_if_input_is_not_relative_to_dirname
168
+ timestamp = prepare_backup_filepath_with_output_and_timestamp
169
+
170
+ t.inference do |root, dir, path|
171
+ [root, dir, path]
172
+ end
173
+
174
+ assert_equal(
175
+ [app[:output], t.name, "file_#{timestamp}.txt"],
176
+ t.backup_filepath("path/to/file.txt"))
177
+ end
178
+
179
+ def test_backup_filepath_does_not_mistake_files_as_folders_when_checking_if_input_is_relative_to_dirname
180
+ timestamp = prepare_backup_filepath_with_output_and_timestamp
181
+
182
+ t.inference do |root, dir, path|
183
+ [root, dir, path]
184
+ end
185
+
186
+ assert_equal(
187
+ [app[:output], t.name, "file_task_#{timestamp}.txt"],
188
+ t.backup_filepath("folder/tap/file_task.txt"))
189
+ end
190
+
191
+ #
192
+ # open tests
193
+ #
194
+
195
+ def test_open_opens_each_file
196
+ FileUtils.mkdir_p(infer_filepath(:output))
197
+
198
+ list = [0, 1].collect do |n|
199
+ path = infer_filepath(:output, "#{n}.txt")
200
+ File.open(path, "w") {|f| f << n.to_s}
201
+ path
202
+ end
203
+
204
+ t.open(list) do |files|
205
+ files.each_with_index do |file, n|
206
+ assert_equal File, file.class
207
+ assert_equal n.to_s, file.read
208
+ end
209
+ end
210
+ end
211
+
212
+ def test_open_opens_with_input_mode
213
+ FileUtils.mkdir_p(infer_filepath(:output))
214
+
215
+ list = [0, 1].collect do |n|
216
+ path = infer_filepath(:output, "#{n}.txt")
217
+ path
218
+ end
219
+
220
+ t.open(list, "w") do |files|
221
+ files.each_with_index do |file, n|
222
+ assert_equal File, file.class
223
+ file << n.to_s
224
+ end
225
+ end
226
+
227
+ list.each_with_index do |file, n|
228
+ assert_equal n.to_s, File.read(file)
229
+ end
230
+ end
231
+
232
+ def test_open_returns_open_files_if_no_block_is_given
233
+ FileUtils.mkdir_p(infer_filepath(:output))
234
+
235
+ list = [0, 1].collect do |n|
236
+ path = infer_filepath(:output, "#{n}.txt")
237
+ File.open(path, "w") {|f| f << n.to_s}
238
+ path
239
+ end
240
+
241
+ open_files = t.open(list)
242
+ open_files.each_with_index do |file, n|
243
+ assert_equal File, file.class
244
+ assert_equal n.to_s, file.read
245
+ file.close
246
+ end
247
+ end
248
+
249
+ #
250
+ # uptodate tests
251
+ #
252
+
253
+ def uptodate_test_setup(output_str='')
254
+ of1 = ifs.filepath(:root, 'old_file_one.txt')
255
+ of2 = ifs.filepath(:root, 'old_file_two.txt')
256
+
257
+ nf1 = tempfile('new_file_one.txt')
258
+ File.open(nf1, "w") {|file| file << output_str}
259
+
260
+ nf2 = tempfile('new_file_two.txt')
261
+ File.open(nf2, "w") {|file| file << output_str}
262
+
263
+ [of1, of2, nf1, nf2]
264
+ end
265
+
266
+ def test_uptodate_test_setup
267
+ files = uptodate_test_setup
268
+ files.each { |file| assert File.exists?(file), file }
269
+
270
+ of1, of2, nf1, nf2 = files
271
+ assert FileUtils.uptodate?(nf1, of1)
272
+ assert FileUtils.uptodate?(nf2, of1)
273
+ assert FileUtils.uptodate?(nf1, of2)
274
+ assert FileUtils.uptodate?(nf2, of2)
275
+ end
276
+
277
+ def test_uptodate
278
+ of1, of2, nf1, nf2 = uptodate_test_setup
279
+
280
+ non = ifs.filepath(:output, "non_existant_file.txt")
281
+ assert !File.exists?(non)
282
+
283
+ assert t.uptodate?(nf1)
284
+ assert t.uptodate?(nf1, of1)
285
+ assert t.uptodate?(nf1, [of1, of2])
286
+ assert t.uptodate?(nf1, [of1, of2, non])
287
+ assert t.uptodate?([nf1, nf2], of1)
288
+ assert t.uptodate?([nf1, nf2], [of1, of2])
289
+
290
+ assert !t.uptodate?(of1, nf1)
291
+ assert !t.uptodate?(of1, [nf1, nf2])
292
+ assert !t.uptodate?(non, nf1)
293
+ assert !t.uptodate?(non, of1)
294
+ assert !t.uptodate?([nf1, non], of1)
295
+ assert !t.uptodate?([nf1, non], [of1, of2])
296
+ end
297
+
298
+ def test_uptodate_with_up_to_date_config_file
299
+ t = Tap::FileTask.new "configured"
300
+
301
+ of1, of2, nf1, nf2 = uptodate_test_setup
302
+
303
+ non = ifs.filepath(:output, "non_existant_file.txt")
304
+ assert !File.exists?(non)
305
+
306
+ assert t.uptodate?(nf1)
307
+ assert t.uptodate?(nf1, of1)
308
+ assert t.uptodate?(nf1, [of1, of2])
309
+ assert t.uptodate?(nf1, [of1, of2, non])
310
+ assert t.uptodate?([nf1, nf2], of1)
311
+ assert t.uptodate?([nf1, nf2], [of1, of2])
312
+
313
+ assert !t.uptodate?(of1, nf1)
314
+ assert !t.uptodate?(of1, [nf1, nf2])
315
+ assert !t.uptodate?(non, nf1)
316
+ assert !t.uptodate?(non, of1)
317
+ assert !t.uptodate?([nf1, non], of1)
318
+ assert !t.uptodate?([nf1, non], [of1, of2])
319
+ end
320
+
321
+ def test_uptodate_with_out_of_date_config_file
322
+ filepath = ifs.filepath(:config, "configured-0.1.yml")
323
+ assert !File.exists?(filepath)
324
+ begin
325
+ of1, of2, nf1, nf2 = uptodate_test_setup
326
+ FileUtils.touch(filepath)
327
+ t = Tap::FileTask.new "configured-0.1"
328
+
329
+ assert !t.uptodate?(nf1)
330
+ assert !t.uptodate?(nf1, of1)
331
+ assert !t.uptodate?([nf1, nf2], [of1, of2])
332
+ rescue
333
+ raise $!
334
+ ensure
335
+ FileUtils.rm(filepath) if File.exists?(filepath)
336
+ end
337
+ end
338
+
339
+ def test_uptodate_returns_false_when_force
340
+ of1, of2, nf1, nf2 = uptodate_test_setup
341
+
342
+ assert t.uptodate?(nf1, of1)
343
+ with_options :force => true, :quiet => true do
344
+ assert app.options.force
345
+ assert !t.uptodate?(nf1, of1)
346
+ end
347
+ end
348
+
349
+ #
350
+ # backup tests
351
+ #
352
+
353
+ def backup_test_setup
354
+ existing_file = infer_filepath(:output, "file.txt")
355
+ backup_file = infer_filepath(:output, "backup.txt")
356
+
357
+ touch_file(existing_file, "existing content")
358
+ # assure backup_filepath will return backup_file
359
+ t.inference {|root, dir, path| backup_file}
360
+
361
+ [existing_file, backup_file]
362
+ end
363
+
364
+ def test_backup_test_setup
365
+ existing_file, backup_file = backup_test_setup
366
+
367
+ assert File.exists?(existing_file)
368
+ assert !File.exists?(backup_file)
369
+
370
+ assert_equal "existing content", File.read(existing_file)
371
+ assert_equal backup_file, t.backup_filepath(existing_file)
372
+ end
373
+
374
+ def test_backup_copies_filepath_to_backup_filepath
375
+ existing_file, backup_file = backup_test_setup
376
+
377
+ t.backup(existing_file)
378
+
379
+ assert File.exists?(existing_file)
380
+ assert File.exists?(backup_file)
381
+ assert FileUtils.compare_file(existing_file, backup_file)
382
+ end
383
+
384
+ def test_backup_moves_filepath_to_backup_filepath_unless_copy_is_true
385
+ existing_file, backup_file = backup_test_setup
386
+
387
+ t.backup(existing_file, false)
388
+
389
+ assert !File.exists?(existing_file)
390
+ assert File.exists?(backup_file)
391
+ assert_equal "existing content", File.read(backup_file)
392
+ end
393
+
394
+ def test_backup_registers_expanded_filepath_and_backup_filepath_in_backed_up_files
395
+ existing_file, backup_file = backup_test_setup
396
+
397
+ assert_not_equal existing_file, File.expand_path(existing_file)
398
+
399
+ assert_equal({}, t.backed_up_files)
400
+ t.backup(existing_file)
401
+ assert_equal({File.expand_path(existing_file) => File.expand_path(backup_file)}, t.backed_up_files)
402
+ end
403
+
404
+ def test_backup_does_nothing_if_filepath_does_not_exist
405
+ existing_file, backup_file = backup_test_setup
406
+ FileUtils.rm(existing_file)
407
+
408
+ assert !File.exists?(existing_file)
409
+ assert !File.exists?(backup_file)
410
+ assert_equal({}, t.backed_up_files)
411
+
412
+ t.backup(existing_file)
413
+
414
+ assert !File.exists?(existing_file)
415
+ assert !File.exists?(backup_file)
416
+ assert_equal({}, t.backed_up_files)
417
+ end
418
+
419
+ def test_backup_acts_on_list_and_returns_backup_files
420
+ existing_file0 = infer_filepath(:output, "file0.txt")
421
+ existing_file1 = infer_filepath(:output, "file1.txt")
422
+ backup_file0 = infer_filepath(:output, "backup0.txt")
423
+ backup_file1 = infer_filepath(:output, "backup1.txt")
424
+
425
+ touch_file(existing_file0)
426
+ touch_file(existing_file1)
427
+ t.inference do |root, dir, path|
428
+ path =~ /file0/ ? backup_file0 : backup_file1
429
+ end
430
+
431
+ assert !File.exists?(backup_file0)
432
+ assert !File.exists?(backup_file1)
433
+
434
+ assert_equal [File.expand_path(backup_file0), File.expand_path(backup_file1)], t.backup([existing_file0, existing_file1])
435
+
436
+ assert File.exists?(backup_file0)
437
+ assert File.exists?(backup_file1)
438
+ end
439
+
440
+ def test_backup_raises_error_if_backup_for_file_already_exists
441
+ existing_file, backup_file = backup_test_setup
442
+ t.backup(existing_file)
443
+
444
+ assert_raise(RuntimeError) { t.backup(existing_file) }
445
+ end
446
+
447
+ #
448
+ # restore tests
449
+ #
450
+
451
+ def test_restore_restores_backed_up_file_to_original_location_as_listed_in_backed_up_files
452
+ original_file = File.expand_path(infer_filepath(:output, 'original/file.txt'))
453
+ backup_file = File.expand_path(infer_filepath(:output, 'backup/file.txt'))
454
+
455
+ FileUtils.mkdir_p( File.dirname(original_file) )
456
+ touch_file(backup_file)
457
+
458
+ assert File.exists?(File.dirname(original_file))
459
+ assert !File.exists?(original_file)
460
+ assert File.exists?(backup_file)
461
+
462
+ t.backed_up_files[original_file] = backup_file
463
+ t.restore(original_file)
464
+
465
+ assert File.exists?(original_file)
466
+ assert !File.exists?(backup_file)
467
+ end
468
+
469
+ def test_restore_creates_dirs_as_needed_to_restore_file
470
+ original_file = File.expand_path(infer_filepath(:output, 'original/file.txt'))
471
+ backup_file = File.expand_path(infer_filepath(:output, 'backup/file.txt'))
472
+
473
+ touch_file(backup_file)
474
+
475
+ assert !File.exists?(File.dirname(original_file))
476
+ assert !File.exists?(original_file)
477
+ assert File.exists?(backup_file)
478
+
479
+ t.backed_up_files[original_file] = backup_file
480
+ t.restore(original_file)
481
+
482
+ assert File.exists?(original_file)
483
+ assert !File.exists?(backup_file)
484
+ end
485
+
486
+ def test_restore_raises_error_if_the_input_file_is_not_backed_up
487
+ assert t.backed_up_files.empty?
488
+ assert_raise(RuntimeError) { t.restore("original_file") }
489
+ end
490
+
491
+ def test_restore_removes_backup_dir_using_rmdir
492
+ original_file = File.expand_path(infer_filepath(:output, 'original/file.txt'))
493
+ backup_file = File.expand_path(infer_filepath(:output, 'backup/file.txt'))
494
+ backup_dir = File.dirname(backup_file)
495
+
496
+ t.mkdir(backup_file)
497
+ assert File.exists?(backup_dir)
498
+
499
+ touch_file(backup_file)
500
+
501
+ t.backed_up_files[original_file] = backup_file
502
+ t.restore(original_file)
503
+
504
+ assert !File.exists?(backup_dir)
505
+ end
506
+
507
+ def test_restore_acts_on_list_and_returns_restored_files
508
+ existing_file0 = File.expand_path(infer_filepath(:output, "file0.txt"))
509
+ existing_file1 = File.expand_path(infer_filepath(:output, "file1.txt"))
510
+ backup_file0 = File.expand_path(infer_filepath(:output, "backup0.txt"))
511
+ backup_file1 = File.expand_path(infer_filepath(:output, "backup1.txt"))
512
+
513
+ touch_file(backup_file0)
514
+ touch_file(backup_file1)
515
+
516
+ t.backed_up_files[existing_file0] = backup_file0
517
+ t.backed_up_files[existing_file1] = backup_file1
518
+
519
+ assert !File.exists?(existing_file0)
520
+ assert !File.exists?(existing_file1)
521
+
522
+ assert_equal [existing_file0, existing_file1], t.restore([existing_file0, existing_file1])
523
+
524
+ assert File.exists?(existing_file0)
525
+ assert File.exists?(existing_file1)
526
+ end
527
+
528
+ #
529
+ # mkdir tests
530
+ #
531
+
532
+ def test_mkdir_creates_dir_if_it_does_not_exist
533
+ dir = infer_filepath(:output, 'path/to/non_existant_folder')
534
+ FileUtils.mkdir_p(File.dirname(dir))
535
+ assert !File.exists?(dir)
536
+
537
+ t.mkdir(dir)
538
+ assert File.exists?(dir)
539
+ end
540
+
541
+ def test_mkdir_creates_parent_dirs_if_they_do_not_exist
542
+ dir = infer_filepath(:output, 'path/to/non_existant_folder')
543
+ assert !File.exists?(infer_filepath(:output))
544
+
545
+ t.mkdir(dir)
546
+ assert File.exists?(dir)
547
+ end
548
+
549
+ def test_mkdir_registers_expanded_dir_and_all_non_existing_parent_dirs_in_made_files
550
+ dir = infer_filepath(:output, 'path/to/non_existant_folder')
551
+ assert_equal [], t.made_files
552
+ assert_not_equal dir, File.expand_path(dir)
553
+
554
+ t.mkdir(dir)
555
+
556
+ expected = [
557
+ infer_root,
558
+ infer_filepath(:output),
559
+ infer_filepath(:output, 'path'),
560
+ infer_filepath(:output, 'path/to'),
561
+ infer_filepath(:output, 'path/to/non_existant_folder')
562
+ ].collect do |dir|
563
+ File.expand_path(dir)
564
+ end
565
+
566
+ assert_equal expected, t.made_files
567
+ end
568
+
569
+ def test_mkdir_acts_on_and_returns_list
570
+ dir = infer_filepath(:output, 'path')
571
+ another = infer_filepath(:output, 'another')
572
+
573
+ assert !File.exists?(dir)
574
+ assert !File.exists?(another)
575
+
576
+ assert_equal [dir, another], t.mkdir([dir, another])
577
+
578
+ assert File.exists?(dir)
579
+ assert File.exists?(another)
580
+ end
581
+
582
+ #
583
+ # rmdir tests
584
+ #
585
+
586
+ def test_rmdir_removes_dir_if_made_by_the_task
587
+ dir = infer_filepath(:output, 'path/to/non_existant_folder')
588
+ existing_dir = infer_filepath(:output, 'path/to')
589
+
590
+ FileUtils.mkdir_p(existing_dir)
591
+ assert File.exists?(existing_dir)
592
+ assert !File.exists?(dir)
593
+
594
+ t.mkdir(dir)
595
+ assert File.exists?(dir)
596
+
597
+ t.rmdir(dir)
598
+ assert File.exists?(existing_dir)
599
+ assert !File.exists?(dir)
600
+ end
601
+
602
+ def test_rmdir_removes_parent_dirs_if_made_by_the_task
603
+ dir = infer_filepath(:output, 'path/to/non/existant/folder')
604
+ root_parent_dir = infer_filepath(:output, 'path/to')
605
+ existing_dir = infer_filepath(:output, 'path')
606
+
607
+ FileUtils.mkdir_p(existing_dir)
608
+ assert File.exists?(existing_dir)
609
+ assert !File.exists?(root_parent_dir)
610
+
611
+ t.mkdir(dir)
612
+ assert File.exists?(dir)
613
+
614
+ t.rmdir(dir)
615
+ assert File.exists?(existing_dir)
616
+ assert !File.exists?(root_parent_dir)
617
+ end
618
+
619
+ def test_rmdir_does_not_remove_if_dir_was_not_made_by_task
620
+ dir = infer_filepath(:output, 'path/to/non_existant_folder')
621
+
622
+ FileUtils.mkdir_p(dir)
623
+ assert File.exists?(dir)
624
+
625
+ t.rmdir(dir)
626
+ assert File.exists?(dir)
627
+ end
628
+
629
+ def test_rmdir_does_not_remove_if_folder_is_not_empty
630
+ dir = infer_filepath(:output, 'path/to/folder')
631
+ not_empty_dir = infer_filepath(:output, 'path/to')
632
+
633
+ t.mkdir(dir)
634
+ assert File.exists?(dir)
635
+
636
+ touch_file File.join(not_empty_dir, "file.txt")
637
+
638
+ t.rmdir(dir)
639
+ assert File.exists?(not_empty_dir)
640
+ assert !File.exists?(dir)
641
+ end
642
+
643
+ def test_rmdir_checks_for_hidden_files_as_well_as_regular_files
644
+ dir = infer_filepath(:output, 'path/to/folder')
645
+ not_empty_dir = infer_filepath(:output, 'path/to')
646
+
647
+ t.mkdir(dir)
648
+ assert File.exists?(dir)
649
+
650
+ touch_file File.join(not_empty_dir, ".hidden_file")
651
+
652
+ t.rmdir(dir)
653
+ assert File.exists?(not_empty_dir)
654
+ assert !File.exists?(dir)
655
+ end
656
+
657
+ def test_rmdir_clears_made_files_of_removed_dirs
658
+ dir = infer_filepath(:output, 'path/to/folder')
659
+
660
+ FileUtils.mkdir_p(infer_filepath(:output))
661
+ assert_equal [], t.made_files
662
+
663
+ t.mkdir(dir)
664
+ assert_equal [
665
+ File.expand_path(infer_filepath(:output, 'path')),
666
+ File.expand_path(infer_filepath(:output, 'path/to')),
667
+ File.expand_path(infer_filepath(:output, 'path/to/folder'))], t.made_files
668
+
669
+ # touch a file so the 'path' folder isn't removed
670
+ touch_file infer_filepath(:output, 'path/file.txt')
671
+
672
+ t.rmdir(dir)
673
+ assert_equal [
674
+ File.expand_path(infer_filepath(:output, 'path'))], t.made_files
675
+ end
676
+
677
+ def test_rmdir_acts_on_and_returns_expanded_list_of_removed_dirs
678
+ dir = infer_filepath(:output, 'path')
679
+ another = infer_filepath(:output, 'another')
680
+ not_removed = infer_filepath(:output, 'not')
681
+ removed = infer_filepath(:output, 'not/removed')
682
+
683
+ t.mkdir([dir, another, not_removed, removed])
684
+ # touch a file so the not_removed folder isn't removed
685
+ touch_file infer_filepath(:output, 'not/file.txt')
686
+
687
+ expected = [dir, another, removed].collect {|d| File.expand_path(d)}
688
+ assert_equal expected, t.rmdir([dir, another, not_removed, removed])
689
+ end
690
+
691
+ #
692
+ # make tests
693
+ #
694
+
695
+ def test_make_acts_on_and_returns_list
696
+ filepath = "file.txt"
697
+ another = "another.txt"
698
+ assert_equal [filepath, another], t.make([filepath, another])
699
+ end
700
+
701
+ def test_make_yields_list_if_block_given
702
+ was_in_make = false
703
+ t.make("file.txt") do |list|
704
+ was_in_make = true
705
+ assert_equal ["file.txt"], list
706
+ end
707
+ assert was_in_make
708
+ end
709
+
710
+ def test_make_backs_up_existing_files_and_creates_non_existant_dirs
711
+ existing_file = infer_filepath(:output, "path/to/existing/file.txt")
712
+ non_existant_file = infer_filepath(:output, "path/to/non/existant/file.txt")
713
+ touch_file(existing_file, "existing content")
714
+
715
+ # be sure inference leads files to an output dir, for cleanup
716
+ removal_path = infer_filepath(:output, 'removal')
717
+ t.inference {|root, dir, path| removal_path}
718
+
719
+ assert File.exists?(existing_file)
720
+ assert !File.exists?(non_existant_file)
721
+
722
+ files = [existing_file, non_existant_file]
723
+ t.make(files)
724
+
725
+ # check neither of the files exist at this point
726
+ # and the parent dirs all exist
727
+ files.each do |file|
728
+ assert !File.exists?(file)
729
+ assert File.exists?(File.dirname(file))
730
+ end
731
+
732
+ # check the existing file was backed up
733
+ assert_equal({File.expand_path(existing_file) => File.expand_path(removal_path)}, t.backed_up_files)
734
+ assert_equal "existing content", File.read(removal_path)
735
+ end
736
+
737
+ def test_make_adds_list_to_made_files
738
+ existing_file = infer_filepath(:output, "path/to/existing/file.txt")
739
+ non_existant_file = infer_filepath(:output, "path/to/non/existant/file.txt")
740
+ touch_file(existing_file)
741
+
742
+ # be sure inference leads files to an output dir, for cleanup
743
+ removal_path = infer_filepath(:output, 'removal')
744
+ t.inference {|root, dir, path| File.join(removal_path, path) }
745
+
746
+ assert_equal([], t.made_files)
747
+ assert File.exists?(existing_file)
748
+ assert !File.exists?(non_existant_file)
749
+ assert !File.exists?(removal_path)
750
+
751
+ files = [existing_file, non_existant_file]
752
+ t.make(files)
753
+
754
+ expected = [
755
+ removal_path, # added by backup of existing_file
756
+ existing_file, # added by make
757
+ infer_filepath(:output, 'path/to/non'), # added by mkdir
758
+ infer_filepath(:output, 'path/to/non/existant'), # added by mkdir
759
+ non_existant_file # added by make
760
+ ].collect do |dir|
761
+ File.expand_path(dir)
762
+ end
763
+
764
+ assert_equal expected, t.made_files
765
+ end
766
+
767
+ #
768
+ # rm tests
769
+ #
770
+
771
+ def test_rm_removes_file_and_parent_dirs_if_made_by_the_task
772
+ file = infer_filepath(:output, 'path/to/file.txt')
773
+ parent_dir = infer_filepath(:output, 'path/to')
774
+ existing_dir = infer_filepath(:output, 'path')
775
+ FileUtils.mkdir_p existing_dir
776
+
777
+ assert File.exists?(existing_dir)
778
+ assert !File.exists?(file)
779
+
780
+ t.make file
781
+ touch_file(file)
782
+ assert File.exists?(file)
783
+
784
+ t.rm(file)
785
+ assert File.exists?(existing_dir)
786
+ assert !File.exists?(parent_dir)
787
+ assert !File.exists?(file)
788
+ end
789
+
790
+ def test_rm_removes_parent_dirs_even_if_file_does_not_exist
791
+ file = infer_filepath(:output, 'path/to/file.txt')
792
+ parent_dir = infer_filepath(:output, 'path/to')
793
+ existing_dir = infer_filepath(:output, 'path')
794
+ FileUtils.mkdir_p existing_dir
795
+
796
+ assert File.exists?(existing_dir)
797
+ assert !File.exists?(file)
798
+
799
+ t.make file
800
+ assert !File.exists?(file)
801
+
802
+ t.rm(file)
803
+ assert File.exists?(existing_dir)
804
+ assert !File.exists?(parent_dir)
805
+ end
806
+
807
+ def test_rm_does_not_remove_file_if_not_made_by_the_task
808
+ file = infer_filepath(:output, 'path/to/file.txt')
809
+
810
+ touch_file(file)
811
+ assert File.exists?(file)
812
+
813
+ t.rm(file)
814
+ assert File.exists?(file)
815
+ end
816
+
817
+ def test_rm_clears_made_files_of_removed_files
818
+ file0 = infer_filepath(:output, 'file0.txt')
819
+ file1 = infer_filepath(:output, 'file1.txt')
820
+
821
+ FileUtils.mkdir_p(infer_filepath(:output))
822
+ assert_equal [], t.made_files
823
+
824
+ t.make([file0,file1])
825
+ assert_equal [
826
+ File.expand_path(infer_filepath(:output, 'file0.txt')),
827
+ File.expand_path(infer_filepath(:output, 'file1.txt'))], t.made_files
828
+
829
+ t.rm(file0)
830
+ assert_equal [
831
+ File.expand_path(infer_filepath(:output, 'file1.txt'))], t.made_files
832
+ end
833
+
834
+ def test_rm_acts_on_and_returns_expanded_list_of_removed_files_and_dirs
835
+ file = infer_filepath(:output, 'file.txt')
836
+ another = infer_filepath(:output, 'another.txt')
837
+ not_removed = infer_filepath(:output, 'not')
838
+ removed = infer_filepath(:output, 'not/removed.txt')
839
+
840
+ t.make([file, another, removed])
841
+ # touch a file so the not_removed folder isn't removed
842
+ touch_file infer_filepath(:output, 'not/file.txt')
843
+
844
+ expected = [file, another, removed].collect {|f| File.expand_path(f)}
845
+ assert_equal expected, t.rm([file, another, removed])
846
+ end
847
+
848
+ #
849
+ # process tests
850
+ #
851
+
852
+ def setup_process_test(&block)
853
+ existing_file = infer_filepath(:output, "path/to/existing/file.txt")
854
+ non_existant_dir = infer_filepath(:output, "path/to/non/existing")
855
+ non_existant_file = File.join(non_existant_dir, "file.txt")
856
+ backup_file = infer_filepath(:output, "backup/file.txt")
857
+
858
+ touch_file(existing_file, "original content")
859
+ @t = Tap::FileTask.new do |task, input|
860
+ task.make([existing_file, non_existant_file])
861
+
862
+ block.call if block_given?
863
+ end
864
+ # inference leads to the backup_file
865
+ @t.inference do |root, dir, path|
866
+ backup_file
867
+ end
868
+
869
+ [existing_file, backup_file, non_existant_dir, non_existant_file]
870
+ end
871
+
872
+ def test_setup_process_test
873
+ existing_file, backup_file, non_existant_dir, non_existant_file = setup_process_test do
874
+ assert !File.exists?(non_existant_file)
875
+ assert File.exists?(non_existant_dir)
876
+ assert File.exists?(backup_file)
877
+ assert_equal "original content", File.read(backup_file)
878
+ end
879
+ t.execute(nil)
880
+ end
881
+
882
+ def test_process_restores_backups_and_removes_made_files_on_error
883
+ was_in_process = false
884
+ existing_file, backup_file, non_existant_dir, non_existant_file = setup_process_test do
885
+ was_in_process = true
886
+ raise "error"
887
+ end
888
+
889
+ assert_raise(RuntimeError) { t.execute(nil) }
890
+
891
+ # check the existing file was restored
892
+ assert was_in_process
893
+ assert File.exists?(existing_file)
894
+ assert !File.exists?(non_existant_dir)
895
+ assert !File.exists?(backup_file)
896
+ assert_equal "original content", File.read(existing_file)
897
+ end
898
+
899
+ def test_process_does_not_restores_backups_if_restore_on_error_is_false
900
+ was_in_process = false
901
+ existing_file, backup_file, non_existant_dir, non_existant_file = setup_process_test do
902
+ was_in_process = true
903
+ raise "error"
904
+ end
905
+
906
+ t.restore_on_error = false
907
+ assert_raise(RuntimeError) { t.execute(nil) }
908
+
909
+ # check the existing file was NOT restored
910
+ assert was_in_process
911
+ assert !File.exists?(existing_file)
912
+ assert File.exists?(non_existant_dir)
913
+ assert File.exists?(backup_file)
914
+ assert_equal "original content", File.read(backup_file)
915
+ end
916
+
917
+ def test_process_removes_backed_up_files_if_remove_backed_up_files_is_true
918
+ was_in_process = false
919
+ existing_file, backup_file, non_existant_dir, non_existant_file = setup_process_test do
920
+ was_in_process = true
921
+ touch_file(existing_file, "new content")
922
+ end
923
+
924
+ t.remove_backed_up_files = true
925
+ t.execute(nil)
926
+
927
+ # check the backup file was removed and that
928
+ # there was no restore (no error was raised)
929
+ assert was_in_process
930
+ assert File.exists?(existing_file)
931
+ assert_equal "new content", File.read(existing_file)
932
+ assert !File.exists?(backup_file)
933
+ assert !File.exists?(File.dirname(backup_file))
934
+ end
935
+
936
+ def test_process_restores_backups_on_error_even_if_remove_backed_up_files_is_true
937
+ was_in_process = false
938
+ existing_file, backup_file, non_existant_dir, non_existant_file = setup_process_test do
939
+ was_in_process = true
940
+ touch_file(existing_file, "new content")
941
+ raise "error"
942
+ end
943
+
944
+ t.remove_backed_up_files = true
945
+ assert_raise(RuntimeError) { t.execute(nil) }
946
+
947
+ # check the existing file was restored and
948
+ # backup file was removed
949
+ assert was_in_process
950
+ assert File.exists?(existing_file)
951
+ assert_equal "original content", File.read(existing_file)
952
+ assert !File.exists?(backup_file)
953
+ assert !File.exists?(File.dirname(backup_file))
954
+ end
955
+
956
+ #
957
+ # test process with multiple files
958
+ #
959
+
960
+ def setup_multiple_file_process_test(&block)
961
+ existing_files = [0,1].collect do |n|
962
+ path = infer_filepath(:output, "path/to/existing/file#{n}.txt")
963
+ touch_file path, n.to_s
964
+ path
965
+ end
966
+
967
+ non_existant_files = [0,1].collect do |n|
968
+ infer_filepath(:output, "path/to/non/existing/file#{n}.txt")
969
+ end
970
+
971
+ @t = Tap::FileTask.new do |task, input|
972
+ task.make(existing_files + non_existant_files)
973
+ block.call if block_given?
974
+ end
975
+ # inference leads to an output_dir
976
+ @t.inference do |root, dir, path|
977
+ infer_filepath(:output, 'backup', path)
978
+ end
979
+
980
+ [existing_files, non_existant_files]
981
+ end
982
+
983
+ def test_setup_multiple_file_process_test
984
+ existing_files, non_existant_files = setup_multiple_file_process_test do
985
+ (existing_files + existing_files).each do |file|
986
+ assert !File.exists?(file)
987
+ assert File.exists?(File.dirname(file))
988
+ end
989
+ end
990
+ t.execute(nil)
991
+ end
992
+
993
+ def test_process_restore_and_removal_with_multiple_files
994
+ was_in_process = false
995
+ existing_files, non_existant_files = setup_multiple_file_process_test do
996
+ was_in_process = true
997
+ (existing_files + non_existant_files) .each do |file|
998
+ touch_file file, "new content"
999
+ end
1000
+ raise "error"
1001
+ end
1002
+
1003
+ assert !File.exists?(infer_filepath(:output, 'backup'))
1004
+ assert_raise(RuntimeError) { t.execute(nil) }
1005
+
1006
+ # check existing files were restored, made files and backups removed.
1007
+ assert was_in_process
1008
+ existing_files.each_with_index do |existing_file, n|
1009
+ assert File.exists?(existing_file)
1010
+ assert_equal n.to_s, File.read(existing_file)
1011
+ end
1012
+ non_existant_files.each do |non_existing_file|
1013
+ assert !File.exists?(non_existing_file)
1014
+ end
1015
+ assert !File.exists?(infer_filepath(:output, 'backup'))
1016
+ end
1017
+
1018
+ def test_process_remove_backed_up_files_with_multiple_files
1019
+ was_in_process = false
1020
+ existing_files, non_existant_files = setup_multiple_file_process_test do
1021
+ was_in_process = true
1022
+ (existing_files + non_existant_files) .each do |file|
1023
+ touch_file file, "new content"
1024
+ end
1025
+ end
1026
+
1027
+ assert !File.exists?(infer_filepath(:output, 'backup'))
1028
+
1029
+ t.remove_backed_up_files = true
1030
+ t.execute(nil)
1031
+
1032
+ # check existing files were restored, made files and backups removed.
1033
+ assert was_in_process
1034
+ (existing_files + non_existant_files).each do |file|
1035
+ assert File.exists?(file)
1036
+ assert_equal "new content", File.read(file)
1037
+ end
1038
+ assert !File.exists?(infer_filepath(:output, 'backup'))
1039
+ end
1040
+
1041
+ end