thor-exclude_pattern 0.18.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.
Files changed (107) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/CHANGELOG.md +130 -0
  4. data/LICENSE.md +20 -0
  5. data/README.md +34 -0
  6. data/Thorfile +30 -0
  7. data/bin/rake2thor +86 -0
  8. data/bin/thor +6 -0
  9. data/lib/thor.rb +458 -0
  10. data/lib/thor/actions.rb +318 -0
  11. data/lib/thor/actions/create_file.rb +105 -0
  12. data/lib/thor/actions/create_link.rb +60 -0
  13. data/lib/thor/actions/directory.rb +119 -0
  14. data/lib/thor/actions/empty_directory.rb +153 -0
  15. data/lib/thor/actions/file_manipulation.rb +314 -0
  16. data/lib/thor/actions/inject_into_file.rb +109 -0
  17. data/lib/thor/base.rb +649 -0
  18. data/lib/thor/command.rb +136 -0
  19. data/lib/thor/core_ext/hash_with_indifferent_access.rb +80 -0
  20. data/lib/thor/core_ext/io_binary_read.rb +12 -0
  21. data/lib/thor/core_ext/ordered_hash.rb +100 -0
  22. data/lib/thor/error.rb +32 -0
  23. data/lib/thor/exclude_pattern/version.rb +5 -0
  24. data/lib/thor/group.rb +287 -0
  25. data/lib/thor/invocation.rb +172 -0
  26. data/lib/thor/parser.rb +4 -0
  27. data/lib/thor/parser/argument.rb +74 -0
  28. data/lib/thor/parser/arguments.rb +171 -0
  29. data/lib/thor/parser/option.rb +121 -0
  30. data/lib/thor/parser/options.rb +218 -0
  31. data/lib/thor/rake_compat.rb +72 -0
  32. data/lib/thor/runner.rb +322 -0
  33. data/lib/thor/shell.rb +88 -0
  34. data/lib/thor/shell/basic.rb +393 -0
  35. data/lib/thor/shell/color.rb +148 -0
  36. data/lib/thor/shell/html.rb +127 -0
  37. data/lib/thor/util.rb +270 -0
  38. data/lib/thor/version.rb +3 -0
  39. data/spec/actions/create_file_spec.rb +170 -0
  40. data/spec/actions/create_link_spec.rb +95 -0
  41. data/spec/actions/directory_spec.rb +169 -0
  42. data/spec/actions/empty_directory_spec.rb +130 -0
  43. data/spec/actions/file_manipulation_spec.rb +382 -0
  44. data/spec/actions/inject_into_file_spec.rb +135 -0
  45. data/spec/actions_spec.rb +331 -0
  46. data/spec/base_spec.rb +294 -0
  47. data/spec/command_spec.rb +80 -0
  48. data/spec/core_ext/hash_with_indifferent_access_spec.rb +48 -0
  49. data/spec/core_ext/ordered_hash_spec.rb +115 -0
  50. data/spec/exit_condition_spec.rb +19 -0
  51. data/spec/fixtures/application.rb +2 -0
  52. data/spec/fixtures/app{1}/README +3 -0
  53. data/spec/fixtures/bundle/execute.rb +6 -0
  54. data/spec/fixtures/bundle/main.thor +1 -0
  55. data/spec/fixtures/command.thor +10 -0
  56. data/spec/fixtures/doc/%file_name%.rb.tt +1 -0
  57. data/spec/fixtures/doc/COMMENTER +11 -0
  58. data/spec/fixtures/doc/README +3 -0
  59. data/spec/fixtures/doc/block_helper.rb +3 -0
  60. data/spec/fixtures/doc/config.rb +1 -0
  61. data/spec/fixtures/doc/config.yaml.tt +1 -0
  62. data/spec/fixtures/doc/excluding/%file_name%.rb.tt +1 -0
  63. data/spec/fixtures/enum.thor +10 -0
  64. data/spec/fixtures/group.thor +128 -0
  65. data/spec/fixtures/invoke.thor +112 -0
  66. data/spec/fixtures/path with spaces b/data/spec/fixtures/path with → spaces +0 -0
  67. data/spec/fixtures/preserve/script.sh +3 -0
  68. data/spec/fixtures/script.thor +199 -0
  69. data/spec/fixtures/subcommand.thor +17 -0
  70. data/spec/group_spec.rb +216 -0
  71. data/spec/helper.rb +67 -0
  72. data/spec/invocation_spec.rb +100 -0
  73. data/spec/parser/argument_spec.rb +53 -0
  74. data/spec/parser/arguments_spec.rb +66 -0
  75. data/spec/parser/option_spec.rb +202 -0
  76. data/spec/parser/options_spec.rb +400 -0
  77. data/spec/rake_compat_spec.rb +72 -0
  78. data/spec/register_spec.rb +197 -0
  79. data/spec/runner_spec.rb +241 -0
  80. data/spec/sandbox/application.rb +2 -0
  81. data/spec/sandbox/app{1}/README +3 -0
  82. data/spec/sandbox/bundle/execute.rb +6 -0
  83. data/spec/sandbox/bundle/main.thor +1 -0
  84. data/spec/sandbox/command.thor +10 -0
  85. data/spec/sandbox/doc/%file_name%.rb.tt +1 -0
  86. data/spec/sandbox/doc/COMMENTER +11 -0
  87. data/spec/sandbox/doc/README +4 -0
  88. data/spec/sandbox/doc/block_helper.rb +3 -0
  89. data/spec/sandbox/doc/config.rb +1 -0
  90. data/spec/sandbox/doc/config.yaml.tt +1 -0
  91. data/spec/sandbox/doc/excluding/%file_name%.rb.tt +1 -0
  92. data/spec/sandbox/enum.thor +10 -0
  93. data/spec/sandbox/group.thor +128 -0
  94. data/spec/sandbox/invoke.thor +112 -0
  95. data/spec/sandbox/path with spaces b/data/spec/sandbox/path with → spaces +0 -0
  96. data/spec/sandbox/preserve/script.sh +3 -0
  97. data/spec/sandbox/script.thor +199 -0
  98. data/spec/sandbox/subcommand.thor +17 -0
  99. data/spec/shell/basic_spec.rb +311 -0
  100. data/spec/shell/color_spec.rb +95 -0
  101. data/spec/shell/html_spec.rb +32 -0
  102. data/spec/shell_spec.rb +47 -0
  103. data/spec/subcommand_spec.rb +30 -0
  104. data/spec/thor_spec.rb +469 -0
  105. data/spec/util_spec.rb +196 -0
  106. data/thor.gemspec +24 -0
  107. metadata +232 -0
@@ -0,0 +1,382 @@
1
+ require 'helper'
2
+
3
+ class Application; end
4
+
5
+ describe Thor::Actions do
6
+ def runner(options={})
7
+ @runner ||= MyCounter.new([1], options, { :destination_root => destination_root })
8
+ end
9
+
10
+ def action(*args, &block)
11
+ capture(:stdout) { runner.send(*args, &block) }
12
+ end
13
+
14
+ def exists_and_identical?(source, destination)
15
+ destination = File.join(destination_root, destination)
16
+ expect(File.exists?(destination)).to be_true
17
+
18
+ source = File.join(source_root, source)
19
+ expect(FileUtils).to be_identical(source, destination)
20
+ end
21
+
22
+ def file
23
+ File.join(destination_root, "foo")
24
+ end
25
+
26
+ before do
27
+ ::FileUtils.rm_rf(destination_root)
28
+ end
29
+
30
+ describe "#chmod" do
31
+ it "executes the command given" do
32
+ FileUtils.should_receive(:chmod_R).with(0755, file)
33
+ action :chmod, "foo", 0755
34
+ end
35
+
36
+ it "does not execute the command if pretending given" do
37
+ FileUtils.should_not_receive(:chmod_R)
38
+ runner(:pretend => true)
39
+ action :chmod, "foo", 0755
40
+ end
41
+
42
+ it "logs status" do
43
+ FileUtils.should_receive(:chmod_R).with(0755, file)
44
+ expect(action(:chmod, "foo", 0755)).to eq(" chmod foo\n")
45
+ end
46
+
47
+ it "does not log status if required" do
48
+ FileUtils.should_receive(:chmod_R).with(0755, file)
49
+ expect(action(:chmod, "foo", 0755, :verbose => false)).to be_empty
50
+ end
51
+ end
52
+
53
+ describe "#copy_file" do
54
+ it "copies file from source to default destination" do
55
+ action :copy_file, "command.thor"
56
+ exists_and_identical?("command.thor", "command.thor")
57
+ end
58
+
59
+ it "copies file from source to the specified destination" do
60
+ action :copy_file, "command.thor", "foo.thor"
61
+ exists_and_identical?("command.thor", "foo.thor")
62
+ end
63
+
64
+ it "copies file from the source relative to the current path" do
65
+ runner.inside("doc") do
66
+ action :copy_file, "README"
67
+ end
68
+ exists_and_identical?("doc/README", "doc/README")
69
+ end
70
+
71
+ it "copies file from source to default destination and preserves file mode" do
72
+ action :copy_file, "preserve/script.sh", :mode => :preserve
73
+ original = File.join(source_root, "preserve/script.sh")
74
+ copy = File.join(destination_root, "preserve/script.sh")
75
+ expect(File.stat(original).mode).to eq(File.stat(copy).mode)
76
+ end
77
+
78
+ it "logs status" do
79
+ expect(action(:copy_file, "command.thor")).to eq(" create command.thor\n")
80
+ end
81
+
82
+ it "accepts a block to change output" do
83
+ action :copy_file, "command.thor" do |content|
84
+ "OMG" + content
85
+ end
86
+ expect(File.read(File.join(destination_root, "command.thor"))).to match(/^OMG/)
87
+ end
88
+ end
89
+
90
+ describe "#link_file" do
91
+ it "links file from source to default destination" do
92
+ action :link_file, "command.thor"
93
+ exists_and_identical?("command.thor", "command.thor")
94
+ end
95
+
96
+ it "links file from source to the specified destination" do
97
+ action :link_file, "command.thor", "foo.thor"
98
+ exists_and_identical?("command.thor", "foo.thor")
99
+ end
100
+
101
+ it "links file from the source relative to the current path" do
102
+ runner.inside("doc") do
103
+ action :link_file, "README"
104
+ end
105
+ exists_and_identical?("doc/README", "doc/README")
106
+ end
107
+
108
+ it "logs status" do
109
+ expect(action(:link_file, "command.thor")).to eq(" create command.thor\n")
110
+ end
111
+ end
112
+
113
+ describe "#get" do
114
+ it "copies file from source to the specified destination" do
115
+ action :get, "doc/README", "docs/README"
116
+ exists_and_identical?("doc/README", "docs/README")
117
+ end
118
+
119
+ it "uses just the source basename as destination if none is specified" do
120
+ action :get, "doc/README"
121
+ exists_and_identical?("doc/README", "README")
122
+ end
123
+
124
+ it "allows the destination to be set as a block result" do
125
+ action(:get, "doc/README"){ |c| "docs/README" }
126
+ exists_and_identical?("doc/README", "docs/README")
127
+ end
128
+
129
+ it "yields file content to a block" do
130
+ action :get, "doc/README" do |content|
131
+ expect(content).to eq("__start__\nREADME\n__end__\n")
132
+ end
133
+ end
134
+
135
+ it "logs status" do
136
+ expect(action(:get, "doc/README", "docs/README")).to eq(" create docs/README\n")
137
+ end
138
+
139
+ it "accepts http remote sources" do
140
+ body = "__start__\nHTTPFILE\n__end__\n"
141
+ FakeWeb.register_uri(:get, 'http://example.com/file.txt', :body => body)
142
+ action :get, "http://example.com/file.txt" do |content|
143
+ expect(content).to eq(body)
144
+ end
145
+ FakeWeb.clean_registry
146
+ end
147
+
148
+ it "accepts https remote sources" do
149
+ body = "__start__\nHTTPSFILE\n__end__\n"
150
+ FakeWeb.register_uri(:get, 'https://example.com/file.txt', :body => body)
151
+ action :get, "https://example.com/file.txt" do |content|
152
+ expect(content).to eq(body)
153
+ end
154
+ FakeWeb.clean_registry
155
+ end
156
+ end
157
+
158
+ describe "#template" do
159
+ it "allows using block helpers in the template" do
160
+ action :template, "doc/block_helper.rb"
161
+
162
+ file = File.join(destination_root, "doc/block_helper.rb")
163
+ expect(File.read(file)).to eq("Hello world!")
164
+ end
165
+
166
+ it "evaluates the template given as source" do
167
+ runner.instance_variable_set("@klass", "Config")
168
+ action :template, "doc/config.rb"
169
+
170
+ file = File.join(destination_root, "doc/config.rb")
171
+ expect(File.read(file)).to eq("class Config; end\n")
172
+ end
173
+
174
+ it "copies the template to the specified destination" do
175
+ action :template, "doc/config.rb", "doc/configuration.rb"
176
+ file = File.join(destination_root, "doc/configuration.rb")
177
+ expect(File.exists?(file)).to be_true
178
+ end
179
+
180
+ it "converts enconded instructions" do
181
+ runner.should_receive(:file_name).and_return("rdoc")
182
+ action :template, "doc/%file_name%.rb.tt"
183
+ file = File.join(destination_root, "doc/rdoc.rb")
184
+ expect(File.exists?(file)).to be_true
185
+ end
186
+
187
+ it "logs status" do
188
+ expect(capture(:stdout) { runner.template("doc/config.rb") }).to eq(" create doc/config.rb\n")
189
+ end
190
+
191
+ it "accepts a block to change output" do
192
+ action :template, "doc/config.rb" do |content|
193
+ "OMG" + content
194
+ end
195
+ expect(File.read(File.join(destination_root, "doc/config.rb"))).to match(/^OMG/)
196
+ end
197
+
198
+ it "guesses the destination name when given only a source" do
199
+ action :template, "doc/config.yaml.tt"
200
+
201
+ file = File.join(destination_root, "doc/config.yaml")
202
+ expect(File.exists?(file)).to be_true
203
+ end
204
+ end
205
+
206
+ describe "when changing existent files" do
207
+ before do
208
+ ::FileUtils.cp_r(source_root, destination_root)
209
+ end
210
+
211
+ def file
212
+ File.join(destination_root, "doc", "README")
213
+ end
214
+
215
+ describe "#remove_file" do
216
+ it "removes the file given" do
217
+ action :remove_file, "doc/README"
218
+ expect(File.exists?(file)).to be_false
219
+ end
220
+
221
+ it "removes directories too" do
222
+ action :remove_dir, "doc"
223
+ expect(File.exists?(File.join(destination_root, "doc"))).to be_false
224
+ end
225
+
226
+ it "does not remove if pretending" do
227
+ runner(:pretend => true)
228
+ action :remove_file, "doc/README"
229
+ expect(File.exists?(file)).to be_true
230
+ end
231
+
232
+ it "logs status" do
233
+ expect(action(:remove_file, "doc/README")).to eq(" remove doc/README\n")
234
+ end
235
+
236
+ it "does not log status if required" do
237
+ expect(action(:remove_file, "doc/README", :verbose => false)).to be_empty
238
+ end
239
+ end
240
+
241
+ describe "#gsub_file" do
242
+ it "replaces the content in the file" do
243
+ action :gsub_file, "doc/README", "__start__", "START"
244
+ expect(File.binread(file)).to eq("START\nREADME\n__end__\n")
245
+ end
246
+
247
+ it "does not replace if pretending" do
248
+ runner(:pretend => true)
249
+ action :gsub_file, "doc/README", "__start__", "START"
250
+ expect(File.binread(file)).to eq("__start__\nREADME\n__end__\n")
251
+ end
252
+
253
+ it "accepts a block" do
254
+ action(:gsub_file, "doc/README", "__start__"){ |match| match.gsub('__', '').upcase }
255
+ expect(File.binread(file)).to eq("START\nREADME\n__end__\n")
256
+ end
257
+
258
+ it "logs status" do
259
+ expect(action(:gsub_file, "doc/README", "__start__", "START")).to eq(" gsub doc/README\n")
260
+ end
261
+
262
+ it "does not log status if required" do
263
+ expect(action(:gsub_file, file, "__", :verbose => false){ |match| match * 2 }).to be_empty
264
+ end
265
+ end
266
+
267
+ describe "#append_to_file" do
268
+ it "appends content to the file" do
269
+ action :append_to_file, "doc/README", "END\n"
270
+ expect(File.binread(file)).to eq("__start__\nREADME\n__end__\nEND\n")
271
+ end
272
+
273
+ it "accepts a block" do
274
+ action(:append_to_file, "doc/README"){ "END\n" }
275
+ expect(File.binread(file)).to eq("__start__\nREADME\n__end__\nEND\n")
276
+ end
277
+
278
+ it "logs status" do
279
+ expect(action(:append_to_file, "doc/README", "END")).to eq(" append doc/README\n")
280
+ end
281
+ end
282
+
283
+ describe "#prepend_to_file" do
284
+ it "prepends content to the file" do
285
+ action :prepend_to_file, "doc/README", "START\n"
286
+ expect(File.binread(file)).to eq("START\n__start__\nREADME\n__end__\n")
287
+ end
288
+
289
+ it "accepts a block" do
290
+ action(:prepend_to_file, "doc/README"){ "START\n" }
291
+ expect(File.binread(file)).to eq("START\n__start__\nREADME\n__end__\n")
292
+ end
293
+
294
+ it "logs status" do
295
+ expect(action(:prepend_to_file, "doc/README", "START")).to eq(" prepend doc/README\n")
296
+ end
297
+ end
298
+
299
+ describe "#inject_into_class" do
300
+ def file
301
+ File.join(destination_root, "application.rb")
302
+ end
303
+
304
+ it "appends content to a class" do
305
+ action :inject_into_class, "application.rb", Application, " filter_parameters :password\n"
306
+ expect(File.binread(file)).to eq("class Application < Base\n filter_parameters :password\nend\n")
307
+ end
308
+
309
+ it "accepts a block" do
310
+ action(:inject_into_class, "application.rb", Application){ " filter_parameters :password\n" }
311
+ expect(File.binread(file)).to eq("class Application < Base\n filter_parameters :password\nend\n")
312
+ end
313
+
314
+ it "logs status" do
315
+ expect(action(:inject_into_class, "application.rb", Application, " filter_parameters :password\n")).to eq(" insert application.rb\n")
316
+ end
317
+
318
+ it "does not append if class name does not match" do
319
+ action :inject_into_class, "application.rb", "App", " filter_parameters :password\n"
320
+ expect(File.binread(file)).to eq("class Application < Base\nend\n")
321
+ end
322
+ end
323
+ end
324
+
325
+ describe "when adjusting comments" do
326
+ before do
327
+ ::FileUtils.cp_r(source_root, destination_root)
328
+ end
329
+
330
+ def file
331
+ File.join(destination_root, "doc", "COMMENTER")
332
+ end
333
+
334
+ unmodified_comments_file = /__start__\n # greenblue\n#\n# yellowblue\n#yellowred\n #greenred\norange\n purple\n ind#igo\n # ind#igo\n__end__/
335
+
336
+ describe "#uncomment_lines" do
337
+ it "uncomments all matching lines in the file" do
338
+ action :uncomment_lines, "doc/COMMENTER", "green"
339
+ expect(File.binread(file)).to match(/__start__\n greenblue\n#\n# yellowblue\n#yellowred\n greenred\norange\n purple\n ind#igo\n # ind#igo\n__end__/)
340
+
341
+ action :uncomment_lines, "doc/COMMENTER", "red"
342
+ expect(File.binread(file)).to match(/__start__\n greenblue\n#\n# yellowblue\nyellowred\n greenred\norange\n purple\n ind#igo\n # ind#igo\n__end__/)
343
+ end
344
+
345
+ it "correctly uncomments lines with hashes in them" do
346
+ action :uncomment_lines, "doc/COMMENTER", "ind#igo"
347
+ expect(File.binread(file)).to match(/__start__\n # greenblue\n#\n# yellowblue\n#yellowred\n #greenred\norange\n purple\n ind#igo\n ind#igo\n__end__/)
348
+ end
349
+
350
+ it "does not modify already uncommented lines in the file" do
351
+ action :uncomment_lines, "doc/COMMENTER", "orange"
352
+ action :uncomment_lines, "doc/COMMENTER", "purple"
353
+ expect(File.binread(file)).to match(unmodified_comments_file)
354
+ end
355
+
356
+ it "does not uncomment the wrong line when uncommenting lines preceded by blank commented line" do
357
+ action :uncomment_lines, "doc/COMMENTER", "yellow"
358
+ expect(File.binread(file)).to match(/__start__\n # greenblue\n#\nyellowblue\nyellowred\n #greenred\norange\n purple\n ind#igo\n # ind#igo\n__end__/)
359
+ end
360
+ end
361
+
362
+ describe "#comment_lines" do
363
+ it "comments lines which are not commented" do
364
+ action :comment_lines, "doc/COMMENTER", "orange"
365
+ expect(File.binread(file)).to match(/__start__\n # greenblue\n#\n# yellowblue\n#yellowred\n #greenred\n# orange\n purple\n ind#igo\n # ind#igo\n__end__/)
366
+
367
+ action :comment_lines, "doc/COMMENTER", "purple"
368
+ expect(File.binread(file)).to match(/__start__\n # greenblue\n#\n# yellowblue\n#yellowred\n #greenred\n# orange\n # purple\n ind#igo\n # ind#igo\n__end__/)
369
+ end
370
+
371
+ it "correctly comments lines with hashes in them" do
372
+ action :comment_lines, "doc/COMMENTER", "ind#igo"
373
+ expect(File.binread(file)).to match(/__start__\n # greenblue\n#\n# yellowblue\n#yellowred\n #greenred\norange\n purple\n # ind#igo\n # ind#igo\n__end__/)
374
+ end
375
+
376
+ it "does not modify already commented lines" do
377
+ action :comment_lines, "doc/COMMENTER", "green"
378
+ expect(File.binread(file)).to match(unmodified_comments_file)
379
+ end
380
+ end
381
+ end
382
+ end
@@ -0,0 +1,135 @@
1
+ require 'helper'
2
+ require 'thor/actions'
3
+
4
+ describe Thor::Actions::InjectIntoFile do
5
+ before do
6
+ ::FileUtils.rm_rf(destination_root)
7
+ ::FileUtils.cp_r(source_root, destination_root)
8
+ end
9
+
10
+ def invoker(options={})
11
+ @invoker ||= MyCounter.new([1,2], options, { :destination_root => destination_root })
12
+ end
13
+
14
+ def revoker
15
+ @revoker ||= MyCounter.new([1,2], {}, { :destination_root => destination_root, :behavior => :revoke })
16
+ end
17
+
18
+ def invoke!(*args, &block)
19
+ capture(:stdout) { invoker.insert_into_file(*args, &block) }
20
+ end
21
+
22
+ def revoke!(*args, &block)
23
+ capture(:stdout) { revoker.insert_into_file(*args, &block) }
24
+ end
25
+
26
+ def file
27
+ File.join(destination_root, "doc/README")
28
+ end
29
+
30
+ describe "#invoke!" do
31
+ it "changes the file adding content after the flag" do
32
+ invoke! "doc/README", "\nmore content", :after => "__start__"
33
+ expect(File.read(file)).to eq("__start__\nmore content\nREADME\n__end__\n")
34
+ end
35
+
36
+ it "changes the file adding content before the flag" do
37
+ invoke! "doc/README", "more content\n", :before => "__end__"
38
+ expect(File.read(file)).to eq("__start__\nREADME\nmore content\n__end__\n")
39
+ end
40
+
41
+ it "accepts data as a block" do
42
+ invoke! "doc/README", :before => "__end__" do
43
+ "more content\n"
44
+ end
45
+
46
+ expect(File.read(file)).to eq("__start__\nREADME\nmore content\n__end__\n")
47
+ end
48
+
49
+ it "logs status" do
50
+ expect(invoke!("doc/README", "\nmore content", :after => "__start__")).to eq(" insert doc/README\n")
51
+ end
52
+
53
+ it "does not change the file if pretending" do
54
+ invoker :pretend => true
55
+ invoke! "doc/README", "\nmore content", :after => "__start__"
56
+ expect(File.read(file)).to eq("__start__\nREADME\n__end__\n")
57
+ end
58
+
59
+ it "does not change the file if already include content" do
60
+ invoke! "doc/README", :before => "__end__" do
61
+ "more content\n"
62
+ end
63
+
64
+ expect(File.read(file)).to eq("__start__\nREADME\nmore content\n__end__\n")
65
+
66
+ invoke! "doc/README", :before => "__end__" do
67
+ "more content\n"
68
+ end
69
+
70
+ expect(File.read(file)).to eq("__start__\nREADME\nmore content\n__end__\n")
71
+ end
72
+
73
+ it "does change the file if already include content and :force == true" do
74
+ invoke! "doc/README", :before => "__end__" do
75
+ "more content\n"
76
+ end
77
+
78
+ expect(File.read(file)).to eq("__start__\nREADME\nmore content\n__end__\n")
79
+
80
+ invoke! "doc/README", :before => "__end__", :force => true do
81
+ "more content\n"
82
+ end
83
+
84
+ expect(File.read(file)).to eq("__start__\nREADME\nmore content\nmore content\n__end__\n")
85
+ end
86
+
87
+ end
88
+
89
+ describe "#revoke!" do
90
+ it "substracts the destination file after injection" do
91
+ invoke! "doc/README", "\nmore content", :after => "__start__"
92
+ revoke! "doc/README", "\nmore content", :after => "__start__"
93
+ expect(File.read(file)).to eq("__start__\nREADME\n__end__\n")
94
+ end
95
+
96
+ it "substracts the destination file before injection" do
97
+ invoke! "doc/README", "more content\n", :before => "__start__"
98
+ revoke! "doc/README", "more content\n", :before => "__start__"
99
+ expect(File.read(file)).to eq("__start__\nREADME\n__end__\n")
100
+ end
101
+
102
+ it "substracts even with double after injection" do
103
+ invoke! "doc/README", "\nmore content", :after => "__start__"
104
+ invoke! "doc/README", "\nanother stuff", :after => "__start__"
105
+ revoke! "doc/README", "\nmore content", :after => "__start__"
106
+ expect(File.read(file)).to eq("__start__\nanother stuff\nREADME\n__end__\n")
107
+ end
108
+
109
+ it "substracts even with double before injection" do
110
+ invoke! "doc/README", "more content\n", :before => "__start__"
111
+ invoke! "doc/README", "another stuff\n", :before => "__start__"
112
+ revoke! "doc/README", "more content\n", :before => "__start__"
113
+ expect(File.read(file)).to eq("another stuff\n__start__\nREADME\n__end__\n")
114
+ end
115
+
116
+ it "substracts when prepending" do
117
+ invoke! "doc/README", "more content\n", :after => /\A/
118
+ invoke! "doc/README", "another stuff\n", :after => /\A/
119
+ revoke! "doc/README", "more content\n", :after => /\A/
120
+ expect(File.read(file)).to eq("another stuff\n__start__\nREADME\n__end__\n")
121
+ end
122
+
123
+ it "substracts when appending" do
124
+ invoke! "doc/README", "more content\n", :before => /\z/
125
+ invoke! "doc/README", "another stuff\n", :before => /\z/
126
+ revoke! "doc/README", "more content\n", :before => /\z/
127
+ expect(File.read(file)).to eq("__start__\nREADME\n__end__\nanother stuff\n")
128
+ end
129
+
130
+ it "shows progress information to the user" do
131
+ invoke!("doc/README", "\nmore content", :after => "__start__")
132
+ expect(revoke!("doc/README", "\nmore content", :after => "__start__")).to eq(" subtract doc/README\n")
133
+ end
134
+ end
135
+ end