puppet-module 0.3.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 (159) hide show
  1. data/CHANGES.markdown +91 -0
  2. data/LICENSE +17 -0
  3. data/README.markdown +221 -0
  4. data/Rakefile +87 -0
  5. data/VERSION +1 -0
  6. data/bin/puppet-module +7 -0
  7. data/lib/puppet/module/tool.rb +124 -0
  8. data/lib/puppet/module/tool/applications.rb +18 -0
  9. data/lib/puppet/module/tool/applications/application.rb +83 -0
  10. data/lib/puppet/module/tool/applications/builder.rb +88 -0
  11. data/lib/puppet/module/tool/applications/checksummer.rb +38 -0
  12. data/lib/puppet/module/tool/applications/cleaner.rb +14 -0
  13. data/lib/puppet/module/tool/applications/freezer.rb +20 -0
  14. data/lib/puppet/module/tool/applications/generator.rb +117 -0
  15. data/lib/puppet/module/tool/applications/installer.rb +83 -0
  16. data/lib/puppet/module/tool/applications/registrar.rb +34 -0
  17. data/lib/puppet/module/tool/applications/releaser.rb +48 -0
  18. data/lib/puppet/module/tool/applications/searcher.rb +34 -0
  19. data/lib/puppet/module/tool/applications/unpacker.rb +69 -0
  20. data/lib/puppet/module/tool/applications/unreleaser.rb +42 -0
  21. data/lib/puppet/module/tool/cache.rb +56 -0
  22. data/lib/puppet/module/tool/checksums.rb +52 -0
  23. data/lib/puppet/module/tool/cli.rb +127 -0
  24. data/lib/puppet/module/tool/contents_description.rb +84 -0
  25. data/lib/puppet/module/tool/dependency.rb +26 -0
  26. data/lib/puppet/module/tool/metadata.rb +80 -0
  27. data/lib/puppet/module/tool/modulefile.rb +47 -0
  28. data/lib/puppet/module/tool/repository.rb +74 -0
  29. data/lib/puppet/module/tool/skeleton.rb +39 -0
  30. data/lib/puppet/module/tool/utils.rb +9 -0
  31. data/lib/puppet/module/tool/utils/interrogation.rb +39 -0
  32. data/lib/puppet/module/tool/utils/settings.rb +36 -0
  33. data/lib/puppet/module/tool/utils/uri.rb +16 -0
  34. data/spec/fixtures/releases/jamtur01-apache/Modulefile +2 -0
  35. data/spec/fixtures/releases/jamtur01-apache/files/httpd +24 -0
  36. data/spec/fixtures/releases/jamtur01-apache/files/test.vhost +18 -0
  37. data/spec/fixtures/releases/jamtur01-apache/lib/puppet/provider/a2mod/debian.rb +21 -0
  38. data/spec/fixtures/releases/jamtur01-apache/lib/puppet/type/a2mod.rb +12 -0
  39. data/spec/fixtures/releases/jamtur01-apache/manifests/dev.pp +5 -0
  40. data/spec/fixtures/releases/jamtur01-apache/manifests/init.pp +34 -0
  41. data/spec/fixtures/releases/jamtur01-apache/manifests/params.pp +17 -0
  42. data/spec/fixtures/releases/jamtur01-apache/manifests/php.pp +5 -0
  43. data/spec/fixtures/releases/jamtur01-apache/manifests/ssl.pp +15 -0
  44. data/spec/fixtures/releases/jamtur01-apache/manifests/vhost.pp +15 -0
  45. data/spec/fixtures/releases/jamtur01-apache/metadata.json +1 -0
  46. data/spec/fixtures/releases/jamtur01-apache/templates/vhost-default.conf.erb +20 -0
  47. data/spec/fixtures/releases/jamtur01-apache/tests/apache.pp +1 -0
  48. data/spec/fixtures/releases/jamtur01-apache/tests/dev.pp +1 -0
  49. data/spec/fixtures/releases/jamtur01-apache/tests/init.pp +1 -0
  50. data/spec/fixtures/releases/jamtur01-apache/tests/php.pp +1 -0
  51. data/spec/fixtures/releases/jamtur01-apache/tests/ssl.pp +1 -0
  52. data/spec/fixtures/releases/jamtur01-apache/tests/vhost.pp +2 -0
  53. data/spec/integration/cli_spec.rb +373 -0
  54. data/spec/spec.opts +1 -0
  55. data/spec/spec_helper.rb +15 -0
  56. data/spec/support/output_support.rb +19 -0
  57. data/spec/support/stub_http_support.rb +14 -0
  58. data/spec/support/testdir_support.rb +26 -0
  59. data/spec/unit/application_spec.rb +25 -0
  60. data/spec/unit/repository_spec.rb +51 -0
  61. data/templates/generator/Modulefile.erb +5 -0
  62. data/templates/generator/README.erb +3 -0
  63. data/templates/generator/files/README.markdown +22 -0
  64. data/templates/generator/lib/puppet/facter/README.markdown +22 -0
  65. data/templates/generator/lib/puppet/parser/functions/README.markdown +17 -0
  66. data/templates/generator/lib/puppet/provider/README.markdown +14 -0
  67. data/templates/generator/lib/puppet/type/README.markdown +14 -0
  68. data/templates/generator/manifests/README.markdown +28 -0
  69. data/templates/generator/manifests/init.pp.erb +17 -0
  70. data/templates/generator/metadata.json +12 -0
  71. data/templates/generator/spec/README.markdown +7 -0
  72. data/templates/generator/spec/spec.opts +6 -0
  73. data/templates/generator/spec/spec_helper.rb +18 -0
  74. data/templates/generator/spec/unit/puppet/provider/README.markdown +4 -0
  75. data/templates/generator/spec/unit/puppet/type/README.markdown +4 -0
  76. data/templates/generator/templates/README.markdown +23 -0
  77. data/templates/generator/tests/init.pp.erb +1 -0
  78. data/vendor/facets-2.8.2-partial/lib/facets/kernel/returning.rb +23 -0
  79. data/vendor/facets-2.8.2-partial/lib/facets/kernel/tap.rb +39 -0
  80. data/vendor/multipart-post-1.0/Manifest.txt +9 -0
  81. data/vendor/multipart-post-1.0/README.txt +61 -0
  82. data/vendor/multipart-post-1.0/Rakefile +21 -0
  83. data/vendor/multipart-post-1.0/lib/composite_io.rb +89 -0
  84. data/vendor/multipart-post-1.0/lib/multipartable.rb +13 -0
  85. data/vendor/multipart-post-1.0/lib/net/http/post/multipart.rb +27 -0
  86. data/vendor/multipart-post-1.0/lib/parts.rb +66 -0
  87. data/vendor/multipart-post-1.0/test/net/http/post/test_multipart.rb +55 -0
  88. data/vendor/multipart-post-1.0/test/test_composite_io.rb +50 -0
  89. data/vendor/thor-852190ae/CHANGELOG.rdoc +89 -0
  90. data/vendor/thor-852190ae/LICENSE +20 -0
  91. data/vendor/thor-852190ae/README.rdoc +297 -0
  92. data/vendor/thor-852190ae/REVISION +1 -0
  93. data/vendor/thor-852190ae/Thorfile +69 -0
  94. data/vendor/thor-852190ae/bin/rake2thor +86 -0
  95. data/vendor/thor-852190ae/bin/thor +6 -0
  96. data/vendor/thor-852190ae/lib/thor.rb +244 -0
  97. data/vendor/thor-852190ae/lib/thor/actions.rb +275 -0
  98. data/vendor/thor-852190ae/lib/thor/actions/create_file.rb +103 -0
  99. data/vendor/thor-852190ae/lib/thor/actions/directory.rb +91 -0
  100. data/vendor/thor-852190ae/lib/thor/actions/empty_directory.rb +134 -0
  101. data/vendor/thor-852190ae/lib/thor/actions/file_manipulation.rb +223 -0
  102. data/vendor/thor-852190ae/lib/thor/actions/inject_into_file.rb +104 -0
  103. data/vendor/thor-852190ae/lib/thor/base.rb +540 -0
  104. data/vendor/thor-852190ae/lib/thor/core_ext/file_binary_read.rb +9 -0
  105. data/vendor/thor-852190ae/lib/thor/core_ext/hash_with_indifferent_access.rb +75 -0
  106. data/vendor/thor-852190ae/lib/thor/core_ext/ordered_hash.rb +100 -0
  107. data/vendor/thor-852190ae/lib/thor/error.rb +30 -0
  108. data/vendor/thor-852190ae/lib/thor/group.rb +271 -0
  109. data/vendor/thor-852190ae/lib/thor/invocation.rb +180 -0
  110. data/vendor/thor-852190ae/lib/thor/parser.rb +4 -0
  111. data/vendor/thor-852190ae/lib/thor/parser/argument.rb +67 -0
  112. data/vendor/thor-852190ae/lib/thor/parser/arguments.rb +150 -0
  113. data/vendor/thor-852190ae/lib/thor/parser/option.rb +128 -0
  114. data/vendor/thor-852190ae/lib/thor/parser/options.rb +169 -0
  115. data/vendor/thor-852190ae/lib/thor/rake_compat.rb +66 -0
  116. data/vendor/thor-852190ae/lib/thor/runner.rb +314 -0
  117. data/vendor/thor-852190ae/lib/thor/shell.rb +83 -0
  118. data/vendor/thor-852190ae/lib/thor/shell/basic.rb +239 -0
  119. data/vendor/thor-852190ae/lib/thor/shell/color.rb +108 -0
  120. data/vendor/thor-852190ae/lib/thor/task.rb +102 -0
  121. data/vendor/thor-852190ae/lib/thor/util.rb +230 -0
  122. data/vendor/thor-852190ae/lib/thor/version.rb +3 -0
  123. data/vendor/thor-852190ae/spec/actions/create_file_spec.rb +170 -0
  124. data/vendor/thor-852190ae/spec/actions/directory_spec.rb +131 -0
  125. data/vendor/thor-852190ae/spec/actions/empty_directory_spec.rb +91 -0
  126. data/vendor/thor-852190ae/spec/actions/file_manipulation_spec.rb +271 -0
  127. data/vendor/thor-852190ae/spec/actions/inject_into_file_spec.rb +135 -0
  128. data/vendor/thor-852190ae/spec/actions_spec.rb +292 -0
  129. data/vendor/thor-852190ae/spec/base_spec.rb +263 -0
  130. data/vendor/thor-852190ae/spec/core_ext/hash_with_indifferent_access_spec.rb +43 -0
  131. data/vendor/thor-852190ae/spec/core_ext/ordered_hash_spec.rb +115 -0
  132. data/vendor/thor-852190ae/spec/fixtures/application.rb +2 -0
  133. data/vendor/thor-852190ae/spec/fixtures/bundle/execute.rb +6 -0
  134. data/vendor/thor-852190ae/spec/fixtures/bundle/main.thor +1 -0
  135. data/vendor/thor-852190ae/spec/fixtures/doc/%file_name%.rb.tt +1 -0
  136. data/vendor/thor-852190ae/spec/fixtures/doc/README +3 -0
  137. data/vendor/thor-852190ae/spec/fixtures/doc/config.rb +1 -0
  138. data/vendor/thor-852190ae/spec/fixtures/group.thor +83 -0
  139. data/vendor/thor-852190ae/spec/fixtures/invoke.thor +112 -0
  140. data/vendor/thor-852190ae/spec/fixtures/script.thor +140 -0
  141. data/vendor/thor-852190ae/spec/fixtures/task.thor +10 -0
  142. data/vendor/thor-852190ae/spec/group_spec.rb +171 -0
  143. data/vendor/thor-852190ae/spec/invocation_spec.rb +107 -0
  144. data/vendor/thor-852190ae/spec/parser/argument_spec.rb +47 -0
  145. data/vendor/thor-852190ae/spec/parser/arguments_spec.rb +64 -0
  146. data/vendor/thor-852190ae/spec/parser/option_spec.rb +202 -0
  147. data/vendor/thor-852190ae/spec/parser/options_spec.rb +292 -0
  148. data/vendor/thor-852190ae/spec/rake_compat_spec.rb +68 -0
  149. data/vendor/thor-852190ae/spec/runner_spec.rb +202 -0
  150. data/vendor/thor-852190ae/spec/shell/basic_spec.rb +205 -0
  151. data/vendor/thor-852190ae/spec/shell/color_spec.rb +41 -0
  152. data/vendor/thor-852190ae/spec/shell_spec.rb +34 -0
  153. data/vendor/thor-852190ae/spec/spec.opts +1 -0
  154. data/vendor/thor-852190ae/spec/spec_helper.rb +54 -0
  155. data/vendor/thor-852190ae/spec/task_spec.rb +69 -0
  156. data/vendor/thor-852190ae/spec/thor_spec.rb +237 -0
  157. data/vendor/thor-852190ae/spec/util_spec.rb +167 -0
  158. data/vendor/thor-852190ae/thor.gemspec +120 -0
  159. metadata +229 -0
@@ -0,0 +1,205 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Thor::Shell::Basic do
4
+ def shell
5
+ @shell ||= Thor::Shell::Basic.new
6
+ end
7
+
8
+ describe "#padding" do
9
+ it "cannot be set to below zero" do
10
+ shell.padding = 10
11
+ shell.padding.must == 10
12
+
13
+ shell.padding = -1
14
+ shell.padding.must == 0
15
+ end
16
+ end
17
+
18
+ describe "#ask" do
19
+ it "prints a message to the user and gets the response" do
20
+ $stdout.should_receive(:print).with("Should I overwrite it? ")
21
+ $stdin.should_receive(:gets).and_return('Sure')
22
+ shell.ask("Should I overwrite it?").must == "Sure"
23
+ end
24
+ end
25
+
26
+ describe "#yes?" do
27
+ it "asks the user and returns true if the user replies yes" do
28
+ $stdout.should_receive(:print).with("Should I overwrite it? ")
29
+ $stdin.should_receive(:gets).and_return('y')
30
+ shell.yes?("Should I overwrite it?").must be_true
31
+
32
+ $stdout.should_receive(:print).with("Should I overwrite it? ")
33
+ $stdin.should_receive(:gets).and_return('n')
34
+ shell.yes?("Should I overwrite it?").must_not be_true
35
+ end
36
+ end
37
+
38
+ describe "#no?" do
39
+ it "asks the user and returns true if the user replies no" do
40
+ $stdout.should_receive(:print).with("Should I overwrite it? ")
41
+ $stdin.should_receive(:gets).and_return('n')
42
+ shell.no?("Should I overwrite it?").must be_true
43
+
44
+ $stdout.should_receive(:print).with("Should I overwrite it? ")
45
+ $stdin.should_receive(:gets).and_return('Yes')
46
+ shell.no?("Should I overwrite it?").must be_false
47
+ end
48
+ end
49
+
50
+ describe "#say" do
51
+ it "prints a message to the user" do
52
+ $stdout.should_receive(:puts).with("Running...")
53
+ shell.say("Running...")
54
+ end
55
+
56
+ it "prints a message to the user without new line if it ends with a whitespace" do
57
+ $stdout.should_receive(:print).with("Running... ")
58
+ shell.say("Running... ")
59
+ end
60
+
61
+ it "prints a message to the user without new line" do
62
+ $stdout.should_receive(:print).with("Running...")
63
+ shell.say("Running...", nil, false)
64
+ end
65
+ end
66
+
67
+ describe "#say_status" do
68
+ it "prints a message to the user with status" do
69
+ $stdout.should_receive(:puts).with(" create ~/.thor/task.thor")
70
+ shell.say_status(:create, "~/.thor/task.thor")
71
+ end
72
+
73
+ it "always use new line" do
74
+ $stdout.should_receive(:puts).with(" create ")
75
+ shell.say_status(:create, "")
76
+ end
77
+
78
+ it "does not print a message if base is set to quiet" do
79
+ base = MyCounter.new [1,2]
80
+ base.should_receive(:options).and_return(:quiet => true)
81
+
82
+ $stdout.should_not_receive(:puts)
83
+ shell.base = base
84
+ shell.say_status(:created, "~/.thor/task.thor")
85
+ end
86
+
87
+ it "does not print a message if log status is set to false" do
88
+ $stdout.should_not_receive(:puts)
89
+ shell.say_status(:created, "~/.thor/task.thor", false)
90
+ end
91
+
92
+ it "uses padding to set messages left margin" do
93
+ shell.padding = 2
94
+ $stdout.should_receive(:puts).with(" create ~/.thor/task.thor")
95
+ shell.say_status(:create, "~/.thor/task.thor")
96
+ end
97
+ end
98
+
99
+ describe "#print_table" do
100
+ before(:each) do
101
+ @table = []
102
+ @table << ["abc", "#123", "first three"]
103
+ @table << ["", "#0", "empty"]
104
+ @table << ["xyz", "#786", "last three"]
105
+ end
106
+
107
+ it "prints a table" do
108
+ content = capture(:stdout){ shell.print_table(@table) }
109
+ content.must == <<-TABLE
110
+ abc #123 first three
111
+ #0 empty
112
+ xyz #786 last three
113
+ TABLE
114
+ end
115
+
116
+ it "prints a table with identation" do
117
+ content = capture(:stdout){ shell.print_table(@table, :ident => 2) }
118
+ content.must == <<-TABLE
119
+ abc #123 first three
120
+ #0 empty
121
+ xyz #786 last three
122
+ TABLE
123
+ end
124
+
125
+ it "uses maximum terminal width" do
126
+ shell.should_receive(:terminal_width).and_return(20)
127
+ content = capture(:stdout){ shell.print_table(@table, :ident => 2, :truncate => true) }
128
+ content.must == <<-TABLE
129
+ abc #123 firs...
130
+ #0 empty
131
+ xyz #786 last...
132
+ TABLE
133
+ end
134
+ end
135
+
136
+ describe "#file_collision" do
137
+ it "shows a menu with options" do
138
+ $stdout.should_receive(:print).with('Overwrite foo? (enter "h" for help) [Ynaqh] ')
139
+ $stdin.should_receive(:gets).and_return('n')
140
+ shell.file_collision('foo')
141
+ end
142
+
143
+ it "returns true if the user choose default option" do
144
+ $stdout.stub!(:print)
145
+ $stdin.should_receive(:gets).and_return('')
146
+ shell.file_collision('foo').must be_true
147
+ end
148
+
149
+ it "returns false if the user choose no" do
150
+ $stdout.stub!(:print)
151
+ $stdin.should_receive(:gets).and_return('n')
152
+ shell.file_collision('foo').must be_false
153
+ end
154
+
155
+ it "returns true if the user choose yes" do
156
+ $stdout.stub!(:print)
157
+ $stdin.should_receive(:gets).and_return('y')
158
+ shell.file_collision('foo').must be_true
159
+ end
160
+
161
+ it "shows help usage if the user choose help" do
162
+ $stdout.stub!(:print)
163
+ $stdin.should_receive(:gets).and_return('h')
164
+ $stdin.should_receive(:gets).and_return('n')
165
+ help = capture(:stdout){ shell.file_collision('foo') }
166
+ help.must =~ /h \- help, show this help/
167
+ end
168
+
169
+ it "quits if the user choose quit" do
170
+ $stdout.stub!(:print)
171
+ $stdout.should_receive(:puts).with('Aborting...')
172
+ $stdin.should_receive(:gets).and_return('q')
173
+
174
+ lambda {
175
+ shell.file_collision('foo')
176
+ }.must raise_error(SystemExit)
177
+ end
178
+
179
+ it "always returns true if the user choose always" do
180
+ $stdout.should_receive(:print).with('Overwrite foo? (enter "h" for help) [Ynaqh] ')
181
+ $stdin.should_receive(:gets).and_return('a')
182
+
183
+ shell.file_collision('foo').must be_true
184
+
185
+ $stdout.should_not_receive(:print)
186
+ shell.file_collision('foo').must be_true
187
+ end
188
+
189
+ describe "when a block is given" do
190
+ it "displays diff options to the user" do
191
+ $stdout.should_receive(:print).with('Overwrite foo? (enter "h" for help) [Ynaqdh] ')
192
+ $stdin.should_receive(:gets).and_return('s')
193
+ shell.file_collision('foo'){ }
194
+ end
195
+
196
+ it "invokes the diff command" do
197
+ $stdout.stub!(:print)
198
+ $stdin.should_receive(:gets).and_return('d')
199
+ $stdin.should_receive(:gets).and_return('n')
200
+ shell.should_receive(:system).with(/diff -u/)
201
+ capture(:stdout){ shell.file_collision('foo'){ } }
202
+ end
203
+ end
204
+ end
205
+ end
@@ -0,0 +1,41 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Thor::Shell::Color do
4
+ def shell
5
+ @shell ||= Thor::Shell::Color.new
6
+ end
7
+
8
+ describe "#say" do
9
+ it "set the color if specified" do
10
+ $stdout.should_receive(:puts).with("\e[32mWow! Now we have colors!\e[0m")
11
+ shell.say "Wow! Now we have colors!", :green
12
+ end
13
+
14
+ it "does not use a new line even with colors" do
15
+ $stdout.should_receive(:print).with("\e[32mWow! Now we have colors! \e[0m")
16
+ shell.say "Wow! Now we have colors! ", :green
17
+ end
18
+ end
19
+
20
+ describe "#say_status" do
21
+ it "uses color to say status" do
22
+ $stdout.should_receive(:puts).with("\e[1m\e[31m conflict\e[0m README")
23
+ shell.say_status :conflict, "README", :red
24
+ end
25
+ end
26
+
27
+ describe "#file_collision" do
28
+ describe "when a block is given" do
29
+ it "invokes the diff command" do
30
+ $stdout.stub!(:print)
31
+ $stdin.should_receive(:gets).and_return('d')
32
+ $stdin.should_receive(:gets).and_return('n')
33
+
34
+ output = capture(:stdout){ shell.file_collision('spec/fixtures/doc/README'){ "README\nEND\n" } }
35
+ output.must =~ /\e\[31m\- __start__\e\[0m/
36
+ output.must =~ /^ README/
37
+ output.must =~ /\e\[32m\+ END\e\[0m/
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,34 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Thor::Shell do
4
+ def shell
5
+ @shell ||= Thor::Base.shell.new
6
+ end
7
+
8
+ describe "#initialize" do
9
+ it "sets shell value" do
10
+ base = MyCounter.new [1, 2], { }, :shell => shell
11
+ base.shell.must == shell
12
+ end
13
+
14
+ it "sets the base value on the shell if an accessor is available" do
15
+ base = MyCounter.new [1, 2], { }, :shell => shell
16
+ shell.base.must == base
17
+ end
18
+ end
19
+
20
+ describe "#shell" do
21
+ it "returns the shell in use" do
22
+ MyCounter.new([1,2]).shell.must be_kind_of(Thor::Base.shell)
23
+ end
24
+ end
25
+
26
+ describe "with_padding" do
27
+ it "uses padding for inside block outputs" do
28
+ base = MyCounter.new([1,2])
29
+ base.with_padding do
30
+ capture(:stdout){ base.say_status :padding, "cool" }.strip.must == "padding cool"
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,54 @@
1
+ $TESTING=true
2
+
3
+ $:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
4
+ require 'thor'
5
+ require 'thor/group'
6
+ require 'stringio'
7
+
8
+ require 'rubygems'
9
+ require 'rdoc'
10
+ require 'diff/lcs' # You need diff/lcs installed to run specs (but not to run Thor).
11
+ require 'fakeweb' # You need fakeweb installed to run specs (but not to run Thor).
12
+
13
+ $thor_runner = true
14
+
15
+ # Load fixtures
16
+ load File.join(File.dirname(__FILE__), "fixtures", "task.thor")
17
+ load File.join(File.dirname(__FILE__), "fixtures", "group.thor")
18
+ load File.join(File.dirname(__FILE__), "fixtures", "script.thor")
19
+ load File.join(File.dirname(__FILE__), "fixtures", "invoke.thor")
20
+
21
+ # Set shell to basic
22
+ Thor::Base.shell = Thor::Shell::Basic
23
+
24
+ Kernel.module_eval do
25
+ alias_method :must, :should
26
+ alias_method :must_not, :should_not
27
+ undef_method :should
28
+ undef_method :should_not
29
+ end
30
+
31
+ Spec::Runner.configure do |config|
32
+ def capture(stream)
33
+ begin
34
+ stream = stream.to_s
35
+ eval "$#{stream} = StringIO.new"
36
+ yield
37
+ result = eval("$#{stream}").string
38
+ ensure
39
+ eval("$#{stream} = #{stream.upcase}")
40
+ end
41
+
42
+ result
43
+ end
44
+
45
+ def source_root
46
+ File.join(File.dirname(__FILE__), 'fixtures')
47
+ end
48
+
49
+ def destination_root
50
+ File.join(File.dirname(__FILE__), 'sandbox')
51
+ end
52
+
53
+ alias :silence :capture
54
+ end
@@ -0,0 +1,69 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Thor::Task do
4
+ def task(options={})
5
+ options.each do |key, value|
6
+ options[key] = Thor::Option.parse(key, value)
7
+ end
8
+
9
+ @task ||= Thor::Task.new(:can_has, "I can has cheezburger", "can_has", options)
10
+ end
11
+
12
+ describe "#formatted_usage" do
13
+ it "includes namespace within usage" do
14
+ Object.stub!(:namespace).and_return("foo")
15
+ Object.stub!(:arguments).and_return([])
16
+ task(:bar => :required).formatted_usage(Object).must == "foo:can_has --bar=BAR"
17
+ end
18
+
19
+ it "removes default from namespace" do
20
+ Object.stub!(:namespace).and_return("default:foo")
21
+ Object.stub!(:arguments).and_return([])
22
+ task(:bar => :required).formatted_usage(Object).must == ":foo:can_has --bar=BAR"
23
+ end
24
+
25
+ it "injects arguments into usage" do
26
+ Object.stub!(:namespace).and_return("foo")
27
+ Object.stub!(:arguments).and_return([ Thor::Argument.new(:bar, nil, true, :string) ])
28
+ task(:foo => :required).formatted_usage(Object).must == "foo:can_has BAR --foo=FOO"
29
+ end
30
+ end
31
+
32
+ describe "#dynamic" do
33
+ it "creates a dynamic task with the given name" do
34
+ Thor::Task::Dynamic.new('task').name.must == 'task'
35
+ Thor::Task::Dynamic.new('task').description.must == 'A dynamically-generated task'
36
+ Thor::Task::Dynamic.new('task').usage.must == 'task'
37
+ Thor::Task::Dynamic.new('task').options.must == {}
38
+ end
39
+
40
+ it "does not invoke an existing method" do
41
+ mock = mock()
42
+ mock.class.should_receive(:handle_no_task_error).with("to_s")
43
+ Thor::Task::Dynamic.new('to_s').run(mock)
44
+ end
45
+ end
46
+
47
+ describe "#dup" do
48
+ it "dup options hash" do
49
+ task = Thor::Task.new("can_has", nil, nil, :foo => true, :bar => :required)
50
+ task.dup.options.delete(:foo)
51
+ task.options[:foo].must_not be_nil
52
+ end
53
+ end
54
+
55
+ describe "#run" do
56
+ it "runs a task by calling a method in the given instance" do
57
+ mock = mock()
58
+ mock.should_receive(:send).with("can_has", 1, 2, 3)
59
+ task.run(mock, [1, 2, 3])
60
+ end
61
+
62
+ it "raises an error if the method to be invoked is private" do
63
+ mock = mock()
64
+ mock.should_receive(:private_methods).and_return(['can_has'])
65
+ mock.class.should_receive(:handle_no_task_error).with("can_has")
66
+ task.run(mock)
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,237 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Thor do
4
+ describe "#method_option" do
5
+ it "sets options to the next method to be invoked" do
6
+ args = ["foo", "bar", "--force"]
7
+ arg, options = MyScript.start(args)
8
+ options.must == { "force" => true }
9
+ end
10
+
11
+ describe "when :for is supplied" do
12
+ it "updates an already defined task" do
13
+ args, options = MyChildScript.start(["animal", "horse", "--other=fish"])
14
+ options[:other].must == "fish"
15
+ end
16
+
17
+ describe "and the target is on the parent class" do
18
+ it "updates an already defined task" do
19
+ args = ["example_default_task", "my_param", "--new-option=verified"]
20
+ options = Scripts::MyScript.start(args)
21
+ options[:new_option].must == "verified"
22
+ end
23
+
24
+ it "adds a task to the tasks list if the updated task is on the parent class" do
25
+ Scripts::MyScript.tasks["example_default_task"].must_not be_nil
26
+ end
27
+
28
+ it "clones the parent task" do
29
+ Scripts::MyScript.tasks["example_default_task"].must_not == MyChildScript.tasks["example_default_task"]
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ describe "#default_task" do
36
+ it "sets a default task" do
37
+ MyScript.default_task.must == "example_default_task"
38
+ end
39
+
40
+ it "invokes the default task if no command is specified" do
41
+ MyScript.start([]).must == "default task"
42
+ end
43
+
44
+ it "inherits the default task from parent" do
45
+ MyChildScript.default_task.must == "example_default_task"
46
+ end
47
+ end
48
+
49
+ describe "#map" do
50
+ it "calls the alias of a method if one is provided" do
51
+ MyScript.start(["-T", "fish"]).must == ["fish"]
52
+ end
53
+
54
+ it "calls the alias of a method if several are provided via .map" do
55
+ MyScript.start(["-f", "fish"]).must == ["fish", {}]
56
+ MyScript.start(["--foo", "fish"]).must == ["fish", {}]
57
+ end
58
+
59
+ it "inherits all mappings from parent" do
60
+ MyChildScript.default_task.must == "example_default_task"
61
+ end
62
+ end
63
+
64
+ describe "#desc" do
65
+ before(:all) do
66
+ @content = capture(:stdout) { MyScript.start(["help"]) }
67
+ end
68
+
69
+ it "provides description for a task" do
70
+ @content.must =~ /zoo\s+# zoo around/m
71
+ end
72
+
73
+ describe "when :for is supplied" do
74
+ it "overwrites a previous defined task" do
75
+ capture(:stdout) { MyChildScript.start(["help"]) }.must =~ /animal KIND \s+# fish around/m
76
+ end
77
+ end
78
+ end
79
+
80
+ describe "#method_options" do
81
+ it "sets default options if called before an initializer" do
82
+ options = MyChildScript.class_options
83
+ options[:force].type.must == :boolean
84
+ options[:param].type.must == :numeric
85
+ end
86
+
87
+ it "overwrites default options if called on the method scope" do
88
+ args = ["zoo", "--force", "--param", "feathers"]
89
+ options = MyChildScript.start(args)
90
+ options.must == { "force" => true, "param" => "feathers" }
91
+ end
92
+
93
+ it "allows default options to be merged with method options" do
94
+ args = ["animal", "bird", "--force", "--param", "1.0", "--other", "tweets"]
95
+ arg, options = MyChildScript.start(args)
96
+ arg.must == 'bird'
97
+ options.must == { "force"=>true, "param"=>1.0, "other"=>"tweets" }
98
+ end
99
+ end
100
+
101
+ describe "#start" do
102
+ it "calls a no-param method when no params are passed" do
103
+ MyScript.start(["zoo"]).must == true
104
+ end
105
+
106
+ it "calls a single-param method when a single param is passed" do
107
+ MyScript.start(["animal", "fish"]).must == ["fish"]
108
+ end
109
+
110
+ it "does not set options in attributes" do
111
+ MyScript.start(["with_optional", "--all"]).must == [nil, { "all" => true }]
112
+ end
113
+
114
+ it "raises an error if a required param is not provided" do
115
+ capture(:stderr) { MyScript.start(["animal"]) }.strip.must == '"animal" was called incorrectly. Call as "my_script:animal TYPE".'
116
+ end
117
+
118
+ it "raises an error if the invoked task does not exist" do
119
+ capture(:stderr) { Amazing.start(["animal"]) }.strip.must == 'Could not find task "animal" in "amazing" namespace.'
120
+ end
121
+
122
+ it "calls method_missing if an unknown method is passed in" do
123
+ MyScript.start(["unk", "hello"]).must == [:unk, ["hello"]]
124
+ end
125
+
126
+ it "does not call a private method no matter what" do
127
+ capture(:stderr) { MyScript.start(["what"]) }.strip.must == 'Could not find task "what" in "my_script" namespace.'
128
+ end
129
+
130
+ it "uses task default options" do
131
+ options = MyChildScript.start(["animal", "fish"]).last
132
+ options.must == { "other" => "method default" }
133
+ end
134
+
135
+ it "raises when an exception happens within the task call" do
136
+ lambda { MyScript.start(["call_myself_with_wrong_arity"]) }.must raise_error(ArgumentError)
137
+ end
138
+ end
139
+
140
+ describe "#help" do
141
+ def shell
142
+ @shell ||= Thor::Base.shell.new
143
+ end
144
+
145
+ describe "on general" do
146
+ before(:each) do
147
+ @content = capture(:stdout){ MyScript.help(shell) }
148
+ end
149
+
150
+ it "provides useful help info for the help method itself" do
151
+ @content.must =~ /help \[TASK\]\s+# Describe available tasks/
152
+ end
153
+
154
+ it "provides useful help info for a method with params" do
155
+ @content.must =~ /animal TYPE\s+# horse around/
156
+ end
157
+
158
+ it "uses the maximum terminal size to show tasks" do
159
+ @shell.should_receive(:terminal_width).and_return(80)
160
+ content = capture(:stdout){ MyScript.help(shell) }
161
+ content.must =~ /aaa\.\.\.$/
162
+ end
163
+
164
+ it "provides description for tasks from classes in the same namespace" do
165
+ @content.must =~ /baz\s+# do some bazing/
166
+ end
167
+
168
+ it "shows superclass tasks" do
169
+ content = capture(:stdout){ MyChildScript.help(shell) }
170
+ content.must =~ /foo BAR \s+# do some fooing/
171
+ end
172
+
173
+ it "shows class options information" do
174
+ content = capture(:stdout){ MyChildScript.help(shell) }
175
+ content.must =~ /Options\:/
176
+ content.must =~ /\[\-\-param=N\]/
177
+ end
178
+
179
+ it "injects class arguments into default usage" do
180
+ content = capture(:stdout){ Scripts::MyScript.help(shell) }
181
+ content.must =~ /zoo ACCESSOR \-\-param\=PARAM/
182
+ end
183
+ end
184
+
185
+ describe "for a specific task" do
186
+ it "provides full help info when talking about a specific task" do
187
+ capture(:stdout) { MyScript.task_help(shell, "foo") }.must == <<END
188
+ Usage:
189
+ thor my_script:foo BAR
190
+
191
+ Options:
192
+ [--force] # Force to do some fooing
193
+
194
+ do some fooing
195
+ This is more info!
196
+ Everyone likes more info!
197
+ END
198
+ end
199
+
200
+ it "raises an error if the task can't be found" do
201
+ lambda {
202
+ MyScript.task_help(shell, "unknown")
203
+ }.must raise_error(Thor::UndefinedTaskError, 'Could not find task "unknown" in "my_script" namespace.')
204
+ end
205
+
206
+ it "normalizes names before claiming they don't exist" do
207
+ capture(:stdout) { MyScript.task_help(shell, "name-with-dashes") }.must =~ /thor my_script:name-with-dashes/
208
+ end
209
+ end
210
+
211
+ describe "instance method" do
212
+ it "calls the class method" do
213
+ capture(:stdout){ MyScript.start(["help"]) }.must =~ /Tasks:/
214
+ end
215
+
216
+ it "calls the class method" do
217
+ capture(:stdout){ MyScript.start(["help", "foo"]) }.must =~ /Usage:/
218
+ end
219
+ end
220
+ end
221
+
222
+ describe "when creating tasks" do
223
+ it "prints a warning if a public method is created without description or usage" do
224
+ capture(:stdout) {
225
+ klass = Class.new(Thor)
226
+ klass.class_eval "def hello_from_thor; end"
227
+ }.must =~ /\[WARNING\] Attempted to create task "hello_from_thor" without usage or description/
228
+ end
229
+
230
+ it "does not print if overwriting a previous task" do
231
+ capture(:stdout) {
232
+ klass = Class.new(Thor)
233
+ klass.class_eval "def help; end"
234
+ }.must be_empty
235
+ end
236
+ end
237
+ end