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.
- data/.gitignore +5 -0
- data/GENERATORS.md +2 -0
- data/LICENSE +18 -0
- data/OPTIONS.md +2 -0
- data/README.md +251 -0
- data/TASKS.md +21 -0
- data/bin/ing +5 -0
- data/examples/rspec_convert.rb +102 -0
- data/ing.gemspec +29 -0
- data/ing.rb +102 -0
- data/lib/ing.rb +78 -0
- data/lib/ing/actions/create_file.rb +105 -0
- data/lib/ing/actions/create_link.rb +57 -0
- data/lib/ing/actions/directory.rb +98 -0
- data/lib/ing/actions/empty_directory.rb +155 -0
- data/lib/ing/actions/file_manipulation.rb +308 -0
- data/lib/ing/actions/inject_into_file.rb +109 -0
- data/lib/ing/commands/boot.rb +76 -0
- data/lib/ing/commands/generate.rb +64 -0
- data/lib/ing/commands/help.rb +87 -0
- data/lib/ing/commands/implicit.rb +59 -0
- data/lib/ing/commands/list.rb +108 -0
- data/lib/ing/dispatcher.rb +132 -0
- data/lib/ing/files.rb +190 -0
- data/lib/ing/lib_trollop.rb +782 -0
- data/lib/ing/shell.rb +390 -0
- data/lib/ing/trollop/parser.rb +17 -0
- data/lib/ing/util.rb +61 -0
- data/lib/ing/version.rb +3 -0
- data/lib/thor/actions/file_manipulation.rb +30 -0
- data/lib/thor/shell/basic.rb +44 -0
- data/test/acceptance/ing_run_tests.rb +164 -0
- data/test/actions/create_file_spec.rb +209 -0
- data/test/actions/create_link_spec.rb +90 -0
- data/test/actions/directory_spec.rb +167 -0
- data/test/actions/empty_directory_spec.rb +146 -0
- data/test/actions/file_manipulation_spec.rb +433 -0
- data/test/actions/inject_into_file_spec.rb +147 -0
- data/test/fixtures/application.rb +2 -0
- data/test/fixtures/app{1}/README +3 -0
- data/test/fixtures/bundle/execute.rb +6 -0
- data/test/fixtures/bundle/main.thor +1 -0
- data/test/fixtures/doc/%file_name%.rb.tt +1 -0
- data/test/fixtures/doc/COMMENTER +10 -0
- data/test/fixtures/doc/README +3 -0
- data/test/fixtures/doc/block_helper.rb +3 -0
- data/test/fixtures/doc/components/.empty_directory +0 -0
- data/test/fixtures/doc/config.rb +1 -0
- data/test/fixtures/doc/config.yaml.tt +1 -0
- data/test/fixtures/group.ing.rb +76 -0
- data/test/fixtures/invok.ing.rb +50 -0
- data/test/fixtures/namespace.ing.rb +52 -0
- data/test/fixtures/require.ing.rb +7 -0
- data/test/fixtures/task.ing.rb +36 -0
- data/test/fixtures/task.thor +10 -0
- data/test/spec_helper.rb +2 -0
- data/test/test_helper.rb +41 -0
- data/todo.yml +7 -0
- 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
|