ing 0.1.1

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 (59) hide show
  1. data/.gitignore +5 -0
  2. data/GENERATORS.md +2 -0
  3. data/LICENSE +18 -0
  4. data/OPTIONS.md +2 -0
  5. data/README.md +251 -0
  6. data/TASKS.md +21 -0
  7. data/bin/ing +5 -0
  8. data/examples/rspec_convert.rb +102 -0
  9. data/ing.gemspec +29 -0
  10. data/ing.rb +102 -0
  11. data/lib/ing.rb +78 -0
  12. data/lib/ing/actions/create_file.rb +105 -0
  13. data/lib/ing/actions/create_link.rb +57 -0
  14. data/lib/ing/actions/directory.rb +98 -0
  15. data/lib/ing/actions/empty_directory.rb +155 -0
  16. data/lib/ing/actions/file_manipulation.rb +308 -0
  17. data/lib/ing/actions/inject_into_file.rb +109 -0
  18. data/lib/ing/commands/boot.rb +76 -0
  19. data/lib/ing/commands/generate.rb +64 -0
  20. data/lib/ing/commands/help.rb +87 -0
  21. data/lib/ing/commands/implicit.rb +59 -0
  22. data/lib/ing/commands/list.rb +108 -0
  23. data/lib/ing/dispatcher.rb +132 -0
  24. data/lib/ing/files.rb +190 -0
  25. data/lib/ing/lib_trollop.rb +782 -0
  26. data/lib/ing/shell.rb +390 -0
  27. data/lib/ing/trollop/parser.rb +17 -0
  28. data/lib/ing/util.rb +61 -0
  29. data/lib/ing/version.rb +3 -0
  30. data/lib/thor/actions/file_manipulation.rb +30 -0
  31. data/lib/thor/shell/basic.rb +44 -0
  32. data/test/acceptance/ing_run_tests.rb +164 -0
  33. data/test/actions/create_file_spec.rb +209 -0
  34. data/test/actions/create_link_spec.rb +90 -0
  35. data/test/actions/directory_spec.rb +167 -0
  36. data/test/actions/empty_directory_spec.rb +146 -0
  37. data/test/actions/file_manipulation_spec.rb +433 -0
  38. data/test/actions/inject_into_file_spec.rb +147 -0
  39. data/test/fixtures/application.rb +2 -0
  40. data/test/fixtures/app{1}/README +3 -0
  41. data/test/fixtures/bundle/execute.rb +6 -0
  42. data/test/fixtures/bundle/main.thor +1 -0
  43. data/test/fixtures/doc/%file_name%.rb.tt +1 -0
  44. data/test/fixtures/doc/COMMENTER +10 -0
  45. data/test/fixtures/doc/README +3 -0
  46. data/test/fixtures/doc/block_helper.rb +3 -0
  47. data/test/fixtures/doc/components/.empty_directory +0 -0
  48. data/test/fixtures/doc/config.rb +1 -0
  49. data/test/fixtures/doc/config.yaml.tt +1 -0
  50. data/test/fixtures/group.ing.rb +76 -0
  51. data/test/fixtures/invok.ing.rb +50 -0
  52. data/test/fixtures/namespace.ing.rb +52 -0
  53. data/test/fixtures/require.ing.rb +7 -0
  54. data/test/fixtures/task.ing.rb +36 -0
  55. data/test/fixtures/task.thor +10 -0
  56. data/test/spec_helper.rb +2 -0
  57. data/test/test_helper.rb +41 -0
  58. data/todo.yml +7 -0
  59. metadata +147 -0
@@ -0,0 +1,90 @@
1
+ require File.expand_path('../spec_helper', File.dirname(__FILE__))
2
+ require File.expand_path("../../lib/ing/files", File.dirname(__FILE__))
3
+
4
+ require 'tempfile'
5
+
6
+ describe Ing::Files::CreateLink do
7
+ include SpecHelpers
8
+
9
+ def reset
10
+ @hardlink_to = File.join(Dir.tmpdir, 'linkdest.rb')
11
+ ::FileUtils.rm_rf(destination_root)
12
+ ::FileUtils.rm_rf(@hardlink_to)
13
+ end
14
+
15
+ def create_link(destination=nil, config={}, options={})
16
+ @base = MyCounter.new(options)
17
+ @base.destination_root = destination_root
18
+ @base.call 1, 2
19
+ MyCounter.send(:define_method, :file_name, Proc.new {'rdoc'} )
20
+
21
+ @tempfile = Tempfile.new("config.rb")
22
+
23
+ @action = Ing::Files::CreateLink.new(@base, destination, @tempfile.path,
24
+ { :verbose => !@silence }.merge(config))
25
+ end
26
+
27
+ def invoke!
28
+ capture(:stdout){ @action.invoke! }
29
+ end
30
+
31
+ def silence!
32
+ @silence = true
33
+ end
34
+
35
+ describe "#invoke!" do
36
+ before { reset }
37
+
38
+ it "creates a symbolic link for :symbolic => true" do
39
+ create_link("doc/config.rb", :symbolic => true)
40
+ invoke!
41
+ destination_path = File.join(destination_root, "doc/config.rb")
42
+ assert File.exists?(destination_path)
43
+ assert File.symlink?(destination_path)
44
+ end
45
+
46
+ it "creates a hard link for :symbolic => false" do
47
+ create_link(@hardlink_to, :symbolic => false)
48
+ invoke!
49
+ destination_path = @hardlink_to
50
+ assert File.exists?(destination_path)
51
+ refute File.symlink?(destination_path)
52
+ end
53
+
54
+ it "creates a symbolic link by default" do
55
+ create_link("doc/config.rb")
56
+ invoke!
57
+ destination_path = File.join(destination_root, "doc/config.rb")
58
+ assert File.exists?(destination_path)
59
+ assert File.symlink?(destination_path)
60
+ end
61
+
62
+ it "does not create a link if pretending" do
63
+ create_link("doc/config.rb", {}, :pretend => true)
64
+ invoke!
65
+ refute File.exists?(File.join(destination_root, "doc/config.rb"))
66
+ end
67
+
68
+ it "shows created status to the user" do
69
+ create_link("doc/config.rb")
70
+ assert_equal " create doc/config.rb\n", invoke!
71
+ end
72
+
73
+ it "does not show any information if log status is false" do
74
+ silence!
75
+ create_link("doc/config.rb")
76
+ assert invoke!.empty?
77
+ end
78
+ end
79
+
80
+ describe "#identical?" do
81
+ before { reset }
82
+
83
+ it "returns true if the destination link exists and is identical" do
84
+ create_link("doc/config.rb")
85
+ refute @action.identical?
86
+ invoke!
87
+ assert @action.identical?
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,167 @@
1
+ require File.expand_path('../spec_helper', File.dirname(__FILE__))
2
+ require File.expand_path("../../lib/ing/files", File.dirname(__FILE__))
3
+
4
+ describe Ing::Files::Directory do
5
+ include TestHelpers
6
+
7
+ def reset
8
+ ::FileUtils.rm_rf(destination_root)
9
+ invoker.class.send(:define_method, :file_name, Proc.new{ "rdoc" })
10
+ end
11
+
12
+ def invoker
13
+ @invoker ||= begin
14
+ wg=WhinyGenerator.new({})
15
+ wg.destination_root = destination_root
16
+ wg.call 1,2
17
+ wg
18
+ end
19
+ end
20
+
21
+ def revoker
22
+ @revoker ||= begin
23
+ wg=WhinyGenerator.new({:revoke => true})
24
+ wg.destination_root = destination_root
25
+ wg.call 1,2
26
+ wg
27
+ end
28
+ end
29
+
30
+ def invoke!(*args, &block)
31
+ capture(:stdout){ invoker.directory(*args, &block) }
32
+ end
33
+
34
+ def revoke!(*args, &block)
35
+ capture(:stdout){ revoker.directory(*args, &block) }
36
+ end
37
+
38
+ def exists_and_identical?(source_path, destination_path)
39
+ %w(config.rb README).each do |file|
40
+ source = File.join(source_root, source_path, file)
41
+ destination = File.join(destination_root, destination_path, file)
42
+
43
+ assert File.exists?(destination)
44
+ assert FileUtils.identical?(source, destination)
45
+ end
46
+ end
47
+
48
+ describe "#invoke!" do
49
+
50
+ before { reset }
51
+
52
+ it "raises an error if the source does not exist" do
53
+ assert_match(
54
+ /Could not find "unknown" in any of your source paths/,
55
+ assert_raises(Ing::FileNotFoundError) { invoke! "unknown" }.message
56
+ )
57
+ end
58
+
59
+ it "should not create a directory in pretend mode" do
60
+ invoke! "doc", "ghost", :pretend => true
61
+ refute File.exists?("ghost")
62
+ end
63
+
64
+ it "copies the whole directory recursively to the default destination" do
65
+ invoke! "doc"
66
+ exists_and_identical?("doc", "doc")
67
+ end
68
+
69
+ it "copies the whole directory recursively to the specified destination" do
70
+ invoke! "doc", "docs"
71
+ exists_and_identical?("doc", "docs")
72
+ end
73
+
74
+ it "copies only the first level files if not recursive" do
75
+ invoke! ".", "tasks", :recursive => false
76
+
77
+ file = File.join(destination_root, "tasks", "group.ing.rb")
78
+ assert File.exists?(file)
79
+
80
+ file = File.join(destination_root, "tasks", "doc")
81
+ refute File.exists?(file)
82
+
83
+ file = File.join(destination_root, "tasks", "doc", "README")
84
+ refute File.exists?(file)
85
+ end
86
+
87
+ it "copies files from the source relative to the current path" do
88
+ invoker.inside "doc" do
89
+ invoke! "."
90
+ end
91
+ exists_and_identical?("doc", "doc")
92
+ end
93
+
94
+ it "copies and evaluates templates" do
95
+ invoke! "doc", "docs"
96
+ file = File.join(destination_root, "docs", "rdoc.rb")
97
+ assert File.exists?(file)
98
+ assert_equal "FOO = FOO\n", File.read(file)
99
+ end
100
+
101
+ it "copies directories" do
102
+ invoke! "doc", "docs"
103
+ file = File.join(destination_root, "docs", "components")
104
+ assert File.exists?(file)
105
+ assert File.directory?(file)
106
+ end
107
+
108
+ it "does not copy .empty_directory files" do
109
+ invoke! "doc", "docs"
110
+ file = File.join(destination_root, "docs", "components", ".empty_directory")
111
+ refute File.exists?(file)
112
+ end
113
+
114
+ it "copies directories even if they are empty" do
115
+ invoke! "doc/components", "docs/components"
116
+ file = File.join(destination_root, "docs", "components")
117
+ assert File.exists?(file)
118
+ end
119
+
120
+ it "does not copy empty directories twice" do
121
+ content = invoke!("doc/components", "docs/components")
122
+ refute_match(/exist/, content)
123
+ end
124
+
125
+ it "logs status" do
126
+ content = invoke!("doc")
127
+ assert_match(/create doc\/README/, content)
128
+ assert_match(/create doc\/config\.rb/, content)
129
+ assert_match(/create doc\/rdoc\.rb/, content)
130
+ assert_match(/create doc\/components/, content)
131
+ end
132
+
133
+ it "yields a block" do
134
+ checked = false
135
+ invoke!("doc") do |content|
136
+ checked ||= !!(content =~ /FOO/)
137
+ end
138
+ assert checked
139
+ end
140
+
141
+ it "works with glob characters in the path" do
142
+ content = invoke!("app{1}")
143
+ assert_match(/create app\{1\}\/README/, content)
144
+ end
145
+ end
146
+
147
+ describe "#revoke!" do
148
+ before { reset }
149
+
150
+ it "removes the destination file" do
151
+ invoke! "doc"
152
+ revoke! "doc"
153
+
154
+ refute File.exists?(File.join(destination_root, "doc", "README"))
155
+ refute File.exists?(File.join(destination_root, "doc", "config.rb"))
156
+ refute File.exists?(File.join(destination_root, "doc", "components"))
157
+ end
158
+
159
+ it "works with glob characters in the path" do
160
+ invoke! "app{1}"
161
+ assert File.exists?(File.join(destination_root, "app{1}", "README"))
162
+
163
+ revoke! "app{1}"
164
+ refute File.exists?(File.join(destination_root, "app{1}", "README"))
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,146 @@
1
+ require File.expand_path('../spec_helper', File.dirname(__FILE__))
2
+ require File.expand_path("../../lib/ing/files", File.dirname(__FILE__))
3
+
4
+ describe Ing::Files::EmptyDirectory do
5
+ include SpecHelpers
6
+
7
+ def reset
8
+ ::FileUtils.rm_rf(destination_root)
9
+ end
10
+
11
+ def empty_directory(destination, options={})
12
+ @action = Ing::Files::EmptyDirectory.new(base, destination)
13
+ end
14
+
15
+ def invoke!
16
+ capture(:stdout){ @action.invoke! }
17
+ end
18
+
19
+ def revoke!
20
+ capture(:stdout){ @action.revoke! }
21
+ end
22
+
23
+ def base
24
+ @base ||= begin
25
+ x = MyCounter.new({})
26
+ x.destination_root = destination_root
27
+ x.call 1,2
28
+ x
29
+ end
30
+
31
+ end
32
+
33
+ describe "#destination" do
34
+ before { reset }
35
+ it "returns the full destination with the destination_root" do
36
+ assert_equal File.join(destination_root, 'doc'), empty_directory('doc').destination
37
+ end
38
+
39
+ it "takes relative root into account" do
40
+ base.inside('doc') do
41
+ assert_equal File.join(destination_root, 'doc', 'contents'), empty_directory('contents').destination
42
+ end
43
+ end
44
+ end
45
+
46
+ describe "#relative_destination" do
47
+ before { reset }
48
+ it "returns the relative destination to the original destination root" do
49
+ base.inside('doc') do
50
+ assert_equal 'doc/contents', empty_directory('contents').relative_destination
51
+ end
52
+ end
53
+ end
54
+
55
+ describe "#given_destination" do
56
+ before { reset }
57
+ it "returns the destination supplied by the user" do
58
+ base.inside('doc') do
59
+ assert_equal 'contents', empty_directory('contents').given_destination
60
+ end
61
+ end
62
+ end
63
+
64
+ describe "#invoke!" do
65
+ before { reset }
66
+ it "copies the file to the specified destination" do
67
+ empty_directory("doc")
68
+ invoke!
69
+ assert File.exists?(File.join(destination_root, "doc"))
70
+ end
71
+
72
+ it "shows created status to the user" do
73
+ empty_directory("doc")
74
+ assert_equal " create doc\n", invoke!
75
+ end
76
+
77
+ it "does not create a directory if pretending" do
78
+ base.inside("foo", :pretend => true) do
79
+ empty_directory("ghost")
80
+ end
81
+ refute File.exists?(File.join(base.destination_root, "ghost"))
82
+ end
83
+
84
+ describe "when directory exists" do
85
+ it "shows exist status" do
86
+ empty_directory("doc")
87
+ invoke!
88
+ assert_equal " exist doc\n", invoke!
89
+ end
90
+ end
91
+ end
92
+
93
+ describe "#revoke!" do
94
+ before { reset }
95
+ it "removes the destination file" do
96
+ empty_directory("doc")
97
+ invoke!
98
+ revoke!
99
+ refute File.exists?(@action.destination)
100
+ end
101
+ end
102
+
103
+ describe "#exists?" do
104
+ before { reset }
105
+ it "returns true if the destination file exists" do
106
+ empty_directory("doc")
107
+ refute @action.exists?
108
+ invoke!
109
+ assert @action.exists?
110
+ end
111
+ end
112
+
113
+ describe "protected methods" do
114
+ describe "#convert_encoded_instructions" do
115
+ before do
116
+ reset
117
+ empty_directory("test_dir")
118
+ @action.base.class.send :define_method, :file_name, Proc.new{"expected"}
119
+ end
120
+
121
+ it "accepts and executes a 'legal' %\w+% encoded instruction" do
122
+ assert_equal "expected.txt",
123
+ @action.send(:convert_encoded_instructions, "%file_name%.txt")
124
+ end
125
+
126
+ it "ignores an 'illegal' %\w+% encoded instruction" do
127
+ assert_equal "%some_name%.txt", @action.send(:convert_encoded_instructions, "%some_name%.txt")
128
+ end
129
+
130
+ it "ignores incorrectly encoded instruction" do
131
+ assert_equal "%some.name%.txt", @action.send(:convert_encoded_instructions, "%some.name%.txt")
132
+ end
133
+
134
+ it "raises an error if the instruction refers to a private method" do
135
+ module PrivExt
136
+ private
137
+ def private_file_name
138
+ "something_hidden"
139
+ end
140
+ end
141
+ @action.base.extend(PrivExt)
142
+ assert_raises(NoMethodError) { @action.send(:convert_encoded_instructions, "%private_file_name%.txt") }
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,433 @@
1
+ require File.expand_path('../spec_helper', File.dirname(__FILE__))
2
+ require File.expand_path("../../lib/ing/files", File.dirname(__FILE__))
3
+
4
+ class Application; end
5
+
6
+ describe Ing::Files do
7
+ include SpecHelpers
8
+
9
+ def reset
10
+ ::FileUtils.rm_rf(destination_root)
11
+ end
12
+
13
+ def runner(options={})
14
+ @runner ||= begin
15
+ r = MyCounter.new(options)
16
+ r.destination_root = destination_root
17
+ r.call 1
18
+ r
19
+ end
20
+ end
21
+
22
+ def action(*args, &block)
23
+ capture(:stdout){ runner.send(*args, &block) }
24
+ end
25
+
26
+ def exists_and_identical?(source, destination)
27
+ destination = File.join(destination_root, destination)
28
+ assert File.exists?(destination)
29
+
30
+ source = File.join(source_root, source)
31
+ assert FileUtils.identical?(source, destination)
32
+ end
33
+
34
+ def file
35
+ File.join(destination_root, "foo")
36
+ end
37
+
38
+ describe "#chmod" do
39
+ before { reset }
40
+
41
+ # A bit hacky. But really FileUtils method should not be mocked.
42
+ def expecting_chmod(*expected_args)
43
+ saved = FileUtils
44
+ m = MiniTest::Mock.new; m.expect(:chmod_R, nil, expected_args)
45
+ Object.const_set("FileUtils", m)
46
+ yield m
47
+ ensure
48
+ Object.const_set("FileUtils", saved)
49
+ end
50
+
51
+ it "executes the command given" do
52
+ expecting_chmod(0755, file) do
53
+ action :chmod, "foo", 0755
54
+ end
55
+ end
56
+
57
+ ### Stupid test of implementation not behavior, I'm taking it out
58
+ # it "does not execute the command if pretending given" do
59
+ # FileUtils.should_not_receive(:chmod_R)
60
+ # runner(:pretend => true)
61
+ # action :chmod, "foo", 0755
62
+ # end
63
+
64
+ it "logs status" do
65
+ expecting_chmod(0755, file) do
66
+ log = action(:chmod, "foo", 0755)
67
+ assert_equal " chmod foo\n", log
68
+ end
69
+ end
70
+
71
+ it "does not log status if required" do
72
+ expecting_chmod(0755, file) do
73
+ log = action(:chmod, "foo", 0755, :verbose => false)
74
+ assert log.empty?
75
+ end
76
+ end
77
+ end
78
+
79
+ describe "#copy_file" do
80
+ before { reset }
81
+
82
+ it "copies file from source to default destination" do
83
+ action :copy_file, "task.thor"
84
+ exists_and_identical?("task.thor", "task.thor")
85
+ end
86
+
87
+ it "copies file from source to the specified destination" do
88
+ action :copy_file, "task.thor", "foo.thor"
89
+ exists_and_identical?("task.thor", "foo.thor")
90
+ end
91
+
92
+ it "copies file from the source relative to the current path" do
93
+ runner.inside("doc") do
94
+ action :copy_file, "README"
95
+ end
96
+ exists_and_identical?("doc/README", "doc/README")
97
+ end
98
+
99
+ it "logs status" do
100
+ assert_equal " create task.thor\n", action(:copy_file, "task.thor")
101
+ end
102
+
103
+ it "accepts a block to change output" do
104
+ action :copy_file, "task.thor" do |content|
105
+ "OMG" + content
106
+ end
107
+ assert_match(/^OMG/, File.read(File.join(destination_root, "task.thor")))
108
+ end
109
+ end
110
+
111
+ describe "#link_file" do
112
+ before { reset }
113
+
114
+ it "links file from source to default destination" do
115
+ action :link_file, "task.thor"
116
+ exists_and_identical?("task.thor", "task.thor")
117
+ end
118
+
119
+ it "links file from source to the specified destination" do
120
+ action :link_file, "task.thor", "foo.thor"
121
+ exists_and_identical?("task.thor", "foo.thor")
122
+ end
123
+
124
+ it "links file from the source relative to the current path" do
125
+ runner.inside("doc") do
126
+ action :link_file, "README"
127
+ end
128
+ exists_and_identical?("doc/README", "doc/README")
129
+ end
130
+
131
+ it "logs status" do
132
+ assert_equal " create task.thor\n", action(:link_file, "task.thor")
133
+ end
134
+ end
135
+
136
+ describe "#get" do
137
+ before { reset }
138
+
139
+ it "copies file from source to the specified destination" do
140
+ action :get, "doc/README", "docs/README"
141
+ exists_and_identical?("doc/README", "docs/README")
142
+ end
143
+
144
+ it "uses just the source basename as destination if none is specified" do
145
+ action :get, "doc/README"
146
+ exists_and_identical?("doc/README", "README")
147
+ end
148
+
149
+ it "allows the destination to be set as a block result" do
150
+ action(:get, "doc/README"){ |c| "docs/README" }
151
+ exists_and_identical?("doc/README", "docs/README")
152
+ end
153
+
154
+ it "yields file content to a block" do
155
+ action :get, "doc/README" do |content|
156
+ assert_equal "__start__\nREADME\n__end__\n", content
157
+ end
158
+ end
159
+
160
+ it "logs status" do
161
+ assert_equal " create docs/README\n", action(:get, "doc/README", "docs/README")
162
+ end
163
+
164
+ it "accepts http remote sources" do
165
+ body = "__start__\nHTTPFILE\n__end__\n"
166
+ FakeWeb.register_uri(:get, 'http://example.com/file.txt', :body => body)
167
+ action :get, 'http://example.com/file.txt' do |content|
168
+ assert_equal body, content
169
+ end
170
+ FakeWeb.clean_registry
171
+ end
172
+
173
+ it "accepts https remote sources" do
174
+ body = "__start__\nHTTPSFILE\n__end__\n"
175
+ FakeWeb.register_uri(:get, 'https://example.com/file.txt', :body => body)
176
+ action :get, 'https://example.com/file.txt' do |content|
177
+ assert_equal body, content
178
+ end
179
+ FakeWeb.clean_registry
180
+ end
181
+ end
182
+
183
+ describe "#template" do
184
+ before { reset }
185
+
186
+ it "allows using block helpers in the template" do
187
+ action :template, "doc/block_helper.rb"
188
+
189
+ file = File.join(destination_root, "doc/block_helper.rb")
190
+ assert_equal "Hello world!", File.read(file)
191
+ end
192
+
193
+ it "evaluates the template given as source" do
194
+ runner.instance_variable_set("@klass", "Config")
195
+ action :template, "doc/config.rb"
196
+
197
+ file = File.join(destination_root, "doc/config.rb")
198
+ assert_equal "class Config; end\n", File.read(file)
199
+ end
200
+
201
+ it "copies the template to the specified destination" do
202
+ action :template, "doc/config.rb", "doc/configuration.rb"
203
+ file = File.join(destination_root, "doc/configuration.rb")
204
+ assert File.exists?(file)
205
+ end
206
+
207
+ it "converts enconded instructions" do
208
+ runner.class.send(:define_method, :file_name, Proc.new {"rdoc"})
209
+ action :template, "doc/%file_name%.rb.tt"
210
+ file = File.join(destination_root, "doc/rdoc.rb")
211
+ assert File.exists?(file)
212
+ end
213
+
214
+ it "logs status" do
215
+ assert_equal " create doc/config.rb\n", capture(:stdout){ runner.template("doc/config.rb") }
216
+ end
217
+
218
+ it "accepts a block to change output" do
219
+ action :template, "doc/config.rb" do |content|
220
+ "OMG" + content
221
+ end
222
+ assert_match(/^OMG/, File.read(File.join(destination_root, "doc/config.rb")))
223
+ end
224
+
225
+ it "guesses the destination name when given only a source" do
226
+ action :template, "doc/config.yaml.tt"
227
+
228
+ file = File.join(destination_root, "doc/config.yaml")
229
+ assert File.exists?(file)
230
+ end
231
+ end
232
+
233
+ describe "when changing existent files" do
234
+
235
+ def file
236
+ File.join(destination_root, "doc", "README")
237
+ end
238
+
239
+ describe "#remove_file" do
240
+ before do
241
+ reset
242
+ ::FileUtils.cp_r(source_root, destination_root)
243
+ end
244
+
245
+ it "removes the file given" do
246
+ action :remove_file, "doc/README"
247
+ refute File.exists?(file)
248
+ end
249
+
250
+ it "removes directories too" do
251
+ action :remove_dir, "doc"
252
+ refute File.exists?(File.join(destination_root, "doc"))
253
+ end
254
+
255
+ it "does not remove if pretending" do
256
+ runner(:pretend => true)
257
+ action :remove_file, "doc/README"
258
+ assert File.exists?(file)
259
+ end
260
+
261
+ it "logs status" do
262
+ assert_equal " remove doc/README\n", action(:remove_file, "doc/README")
263
+ end
264
+
265
+ it "does not log status if required" do
266
+ assert action(:remove_file, "doc/README", :verbose => false).empty?
267
+ end
268
+ end
269
+
270
+ describe "#gsub_file" do
271
+ before do
272
+ reset
273
+ ::FileUtils.cp_r(source_root, destination_root)
274
+ end
275
+
276
+ it "replaces the content in the file" do
277
+ action :gsub_file, "doc/README", "__start__", "START"
278
+ assert_equal "START\nREADME\n__end__\n", File.binread(file)
279
+ end
280
+
281
+ it "does not replace if pretending" do
282
+ runner(:pretend => true)
283
+ action :gsub_file, "doc/README", "__start__", "START"
284
+ assert_equal "__start__\nREADME\n__end__\n", File.binread(file)
285
+ end
286
+
287
+ it "accepts a block" do
288
+ action(:gsub_file, "doc/README", "__start__"){ |match| match.gsub('__', '').upcase }
289
+ assert_equal "START\nREADME\n__end__\n", File.binread(file)
290
+ end
291
+
292
+ it "logs status" do
293
+ assert_equal " gsub doc/README\n", action(:gsub_file, "doc/README", "__start__", "START")
294
+ end
295
+
296
+ it "does not log status if required" do
297
+ assert action(:gsub_file, file, "__", :verbose => false){ |match| match * 2 }.empty?
298
+ end
299
+ end
300
+
301
+ describe "#append_to_file" do
302
+ before do
303
+ reset
304
+ ::FileUtils.cp_r(source_root, destination_root)
305
+ end
306
+
307
+ it "appends content to the file" do
308
+ action :append_to_file, "doc/README", "END\n"
309
+ assert_equal "__start__\nREADME\n__end__\nEND\n", File.binread(file)
310
+ end
311
+
312
+ it "accepts a block" do
313
+ action(:append_to_file, "doc/README"){ "END\n" }
314
+ assert_equal "__start__\nREADME\n__end__\nEND\n", File.binread(file)
315
+ end
316
+
317
+ it "logs status" do
318
+ assert_equal " append doc/README\n", action(:append_to_file, "doc/README", "END")
319
+ end
320
+ end
321
+
322
+ describe "#prepend_to_file" do
323
+ before do
324
+ reset
325
+ ::FileUtils.cp_r(source_root, destination_root)
326
+ end
327
+
328
+ it "prepends content to the file" do
329
+ action :prepend_to_file, "doc/README", "START\n"
330
+ assert_equal "START\n__start__\nREADME\n__end__\n", File.binread(file)
331
+ end
332
+
333
+ it "accepts a block" do
334
+ action(:prepend_to_file, "doc/README"){ "START\n" }
335
+ assert_equal "START\n__start__\nREADME\n__end__\n", File.binread(file)
336
+ end
337
+
338
+ it "logs status" do
339
+ assert_equal " prepend doc/README\n", action(:prepend_to_file, "doc/README", "START")
340
+ end
341
+ end
342
+
343
+ describe "#inject_into_class" do
344
+ before do
345
+ reset
346
+ ::FileUtils.cp_r(source_root, destination_root)
347
+ end
348
+
349
+ def file
350
+ File.join(destination_root, "application.rb")
351
+ end
352
+
353
+ it "appends content to a class" do
354
+ action :inject_into_class, "application.rb", Application, " filter_parameters :password\n"
355
+ assert_equal "class Application < Base\n filter_parameters :password\nend\n", File.binread(file)
356
+ end
357
+
358
+ it "accepts a block" do
359
+ action(:inject_into_class, "application.rb", Application){ " filter_parameters :password\n" }
360
+ assert_equal "class Application < Base\n filter_parameters :password\nend\n", File.binread(file)
361
+ end
362
+
363
+ it "logs status" do
364
+ assert_equal " insert application.rb\n", action(:inject_into_class, "application.rb", Application, " filter_parameters :password\n")
365
+ end
366
+
367
+ it "does not append if class name does not match" do
368
+ action :inject_into_class, "application.rb", "App", " filter_parameters :password\n"
369
+ assert_equal "class Application < Base\nend\n", File.binread(file)
370
+ end
371
+ end
372
+ end
373
+
374
+ describe "when adjusting comments" do
375
+
376
+ def file
377
+ File.join(destination_root, "doc", "COMMENTER")
378
+ end
379
+
380
+ unmodified_comments_file = /__start__\n # greenblue\n# yellowblue\n#yellowred\n #greenred\norange\n purple\n ind#igo\n # ind#igo\n__end__/
381
+
382
+ describe "#uncomment_lines" do
383
+ before do
384
+ reset
385
+ ::FileUtils.cp_r(source_root, destination_root)
386
+ end
387
+
388
+ it "uncomments all matching lines in the file" do
389
+ action :uncomment_lines, "doc/COMMENTER", "green"
390
+ assert_match(/__start__\n greenblue\n# yellowblue\n#yellowred\n greenred\norange\n purple\n ind#igo\n # ind#igo\n__end__/, File.binread(file))
391
+
392
+ action :uncomment_lines, "doc/COMMENTER", "red"
393
+ assert_match(/__start__\n greenblue\n# yellowblue\nyellowred\n greenred\norange\n purple\n ind#igo\n # ind#igo\n__end__/, File.binread(file))
394
+ end
395
+
396
+ it "correctly uncomments lines with hashes in them" do
397
+ action :uncomment_lines, "doc/COMMENTER", "ind#igo"
398
+ assert_match(/__start__\n # greenblue\n# yellowblue\n#yellowred\n #greenred\norange\n purple\n ind#igo\n ind#igo\n__end__/, File.binread(file))
399
+ end
400
+
401
+ it "does not modify already uncommented lines in the file" do
402
+ action :uncomment_lines, "doc/COMMENTER", "orange"
403
+ action :uncomment_lines, "doc/COMMENTER", "purple"
404
+ assert_match(unmodified_comments_file, File.binread(file))
405
+ end
406
+ end
407
+
408
+ describe "#comment_lines" do
409
+ before do
410
+ reset
411
+ ::FileUtils.cp_r(source_root, destination_root)
412
+ end
413
+
414
+ it "comments lines which are not commented" do
415
+ action :comment_lines, "doc/COMMENTER", "orange"
416
+ assert_match(/__start__\n # greenblue\n# yellowblue\n#yellowred\n #greenred\n# orange\n purple\n ind#igo\n # ind#igo\n__end__/, File.binread(file))
417
+
418
+ action :comment_lines, "doc/COMMENTER", "purple"
419
+ assert_match(/__start__\n # greenblue\n# yellowblue\n#yellowred\n #greenred\n# orange\n # purple\n ind#igo\n # ind#igo\n__end__/, File.binread(file))
420
+ end
421
+
422
+ it "correctly comments lines with hashes in them" do
423
+ action :comment_lines, "doc/COMMENTER", "ind#igo"
424
+ assert_match(/__start__\n # greenblue\n# yellowblue\n#yellowred\n #greenred\norange\n purple\n # ind#igo\n # ind#igo\n__end__/, File.binread(file))
425
+ end
426
+
427
+ it "does not modify already commented lines" do
428
+ action :comment_lines, "doc/COMMENTER", "green"
429
+ assert_match(unmodified_comments_file, File.binread(file))
430
+ end
431
+ end
432
+ end
433
+ end