buildr 1.3.5-x86-mswin32

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 (186) hide show
  1. data/CHANGELOG +998 -0
  2. data/LICENSE +176 -0
  3. data/NOTICE +26 -0
  4. data/README.rdoc +134 -0
  5. data/Rakefile +45 -0
  6. data/_buildr +29 -0
  7. data/_jbuildr +29 -0
  8. data/addon/buildr/antlr.rb +65 -0
  9. data/addon/buildr/cobertura.rb +22 -0
  10. data/addon/buildr/drb.rb +281 -0
  11. data/addon/buildr/emma.rb +22 -0
  12. data/addon/buildr/hibernate.rb +142 -0
  13. data/addon/buildr/javacc.rb +85 -0
  14. data/addon/buildr/jdepend.rb +60 -0
  15. data/addon/buildr/jetty.rb +248 -0
  16. data/addon/buildr/jibx.rb +86 -0
  17. data/addon/buildr/nailgun.rb +221 -0
  18. data/addon/buildr/openjpa.rb +90 -0
  19. data/addon/buildr/org/apache/buildr/BuildrNail$Main.class +0 -0
  20. data/addon/buildr/org/apache/buildr/BuildrNail.class +0 -0
  21. data/addon/buildr/org/apache/buildr/BuildrNail.java +41 -0
  22. data/addon/buildr/org/apache/buildr/JettyWrapper$1.class +0 -0
  23. data/addon/buildr/org/apache/buildr/JettyWrapper$BuildrHandler.class +0 -0
  24. data/addon/buildr/org/apache/buildr/JettyWrapper.class +0 -0
  25. data/addon/buildr/org/apache/buildr/JettyWrapper.java +144 -0
  26. data/addon/buildr/xmlbeans.rb +93 -0
  27. data/bin/buildr +19 -0
  28. data/buildr.buildfile +58 -0
  29. data/buildr.gemspec +65 -0
  30. data/doc/_config.yml +1 -0
  31. data/doc/_layouts/default.html +88 -0
  32. data/doc/_layouts/preface.html +22 -0
  33. data/doc/artifacts.textile +211 -0
  34. data/doc/building.textile +244 -0
  35. data/doc/contributing.textile +252 -0
  36. data/doc/css/default.css +236 -0
  37. data/doc/css/print.css +101 -0
  38. data/doc/css/syntax.css +23 -0
  39. data/doc/download.textile +79 -0
  40. data/doc/extending.textile +186 -0
  41. data/doc/images/1442160941-frontcover.jpg +0 -0
  42. data/doc/images/asf-logo.gif +0 -0
  43. data/doc/images/asf-logo.png +0 -0
  44. data/doc/images/buildr-hires.png +0 -0
  45. data/doc/images/buildr.png +0 -0
  46. data/doc/images/favicon.png +0 -0
  47. data/doc/images/growl-icon.tiff +0 -0
  48. data/doc/images/note.png +0 -0
  49. data/doc/images/project-structure.png +0 -0
  50. data/doc/images/tip.png +0 -0
  51. data/doc/images/zbuildr.png +0 -0
  52. data/doc/images/zbuildr.tif +0 -0
  53. data/doc/index.textile +69 -0
  54. data/doc/installing.textile +266 -0
  55. data/doc/languages.textile +459 -0
  56. data/doc/mailing_lists.textile +25 -0
  57. data/doc/more_stuff.textile +457 -0
  58. data/doc/packaging.textile +430 -0
  59. data/doc/preface.textile +54 -0
  60. data/doc/projects.textile +271 -0
  61. data/doc/quick_start.textile +210 -0
  62. data/doc/scripts/buildr-git.rb +512 -0
  63. data/doc/scripts/gitflow.rb +296 -0
  64. data/doc/scripts/install-jruby.sh +44 -0
  65. data/doc/scripts/install-linux.sh +72 -0
  66. data/doc/scripts/install-osx.sh +52 -0
  67. data/doc/settings_profiles.textile +280 -0
  68. data/doc/testing.textile +222 -0
  69. data/etc/KEYS +151 -0
  70. data/lib/buildr.rb +36 -0
  71. data/lib/buildr/core.rb +35 -0
  72. data/lib/buildr/core/application.rb +656 -0
  73. data/lib/buildr/core/build.rb +452 -0
  74. data/lib/buildr/core/checks.rb +254 -0
  75. data/lib/buildr/core/common.rb +150 -0
  76. data/lib/buildr/core/compile.rb +608 -0
  77. data/lib/buildr/core/environment.rb +129 -0
  78. data/lib/buildr/core/filter.rb +362 -0
  79. data/lib/buildr/core/generate.rb +195 -0
  80. data/lib/buildr/core/help.rb +119 -0
  81. data/lib/buildr/core/osx.rb +46 -0
  82. data/lib/buildr/core/progressbar.rb +156 -0
  83. data/lib/buildr/core/project.rb +866 -0
  84. data/lib/buildr/core/shell.rb +198 -0
  85. data/lib/buildr/core/test.rb +723 -0
  86. data/lib/buildr/core/transports.rb +559 -0
  87. data/lib/buildr/core/util.rb +449 -0
  88. data/lib/buildr/groovy.rb +19 -0
  89. data/lib/buildr/groovy/bdd.rb +106 -0
  90. data/lib/buildr/groovy/compiler.rb +138 -0
  91. data/lib/buildr/groovy/shell.rb +48 -0
  92. data/lib/buildr/ide.rb +19 -0
  93. data/lib/buildr/ide/eclipse.rb +334 -0
  94. data/lib/buildr/ide/eclipse/java.rb +53 -0
  95. data/lib/buildr/ide/eclipse/plugin.rb +68 -0
  96. data/lib/buildr/ide/eclipse/scala.rb +66 -0
  97. data/lib/buildr/ide/idea.ipr.template +300 -0
  98. data/lib/buildr/ide/idea.rb +190 -0
  99. data/lib/buildr/ide/idea7x.ipr.template +290 -0
  100. data/lib/buildr/ide/idea7x.rb +212 -0
  101. data/lib/buildr/java.rb +23 -0
  102. data/lib/buildr/java/ant.rb +94 -0
  103. data/lib/buildr/java/bdd.rb +459 -0
  104. data/lib/buildr/java/cobertura.rb +274 -0
  105. data/lib/buildr/java/commands.rb +213 -0
  106. data/lib/buildr/java/compiler.rb +349 -0
  107. data/lib/buildr/java/deprecated.rb +141 -0
  108. data/lib/buildr/java/emma.rb +244 -0
  109. data/lib/buildr/java/jruby.rb +117 -0
  110. data/lib/buildr/java/jtestr_runner.rb.erb +116 -0
  111. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.class +0 -0
  112. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.java +137 -0
  113. data/lib/buildr/java/packaging.rb +716 -0
  114. data/lib/buildr/java/pom.rb +174 -0
  115. data/lib/buildr/java/rjb.rb +155 -0
  116. data/lib/buildr/java/test_result.rb +353 -0
  117. data/lib/buildr/java/tests.rb +333 -0
  118. data/lib/buildr/java/version_requirement.rb +172 -0
  119. data/lib/buildr/packaging.rb +24 -0
  120. data/lib/buildr/packaging/archive.rb +488 -0
  121. data/lib/buildr/packaging/artifact.rb +749 -0
  122. data/lib/buildr/packaging/artifact_namespace.rb +972 -0
  123. data/lib/buildr/packaging/artifact_search.rb +140 -0
  124. data/lib/buildr/packaging/gems.rb +102 -0
  125. data/lib/buildr/packaging/package.rb +238 -0
  126. data/lib/buildr/packaging/tar.rb +186 -0
  127. data/lib/buildr/packaging/version_requirement.rb +172 -0
  128. data/lib/buildr/packaging/zip.rb +73 -0
  129. data/lib/buildr/packaging/ziptask.rb +316 -0
  130. data/lib/buildr/resources/buildr.icns +0 -0
  131. data/lib/buildr/scala.rb +25 -0
  132. data/lib/buildr/scala/bdd.rb +109 -0
  133. data/lib/buildr/scala/compiler.rb +195 -0
  134. data/lib/buildr/scala/org/apache/buildr/SpecsSingletonRunner$.class +0 -0
  135. data/lib/buildr/scala/org/apache/buildr/SpecsSingletonRunner.class +0 -0
  136. data/lib/buildr/scala/org/apache/buildr/SpecsSingletonRunner.scala +35 -0
  137. data/lib/buildr/scala/shell.rb +55 -0
  138. data/lib/buildr/scala/tests.rb +157 -0
  139. data/lib/buildr/shell.rb +180 -0
  140. data/rakelib/checks.rake +57 -0
  141. data/rakelib/doc.rake +92 -0
  142. data/rakelib/jekylltask.rb +120 -0
  143. data/rakelib/package.rake +73 -0
  144. data/rakelib/release.rake +149 -0
  145. data/rakelib/rspec.rake +73 -0
  146. data/rakelib/setup.rake +54 -0
  147. data/rakelib/stage.rake +213 -0
  148. data/rakelib/stage.rake~ +213 -0
  149. data/spec/addon/drb_spec.rb +328 -0
  150. data/spec/core/application_spec.rb +502 -0
  151. data/spec/core/build_spec.rb +677 -0
  152. data/spec/core/checks_spec.rb +519 -0
  153. data/spec/core/common_spec.rb +670 -0
  154. data/spec/core/compile_spec.rb +583 -0
  155. data/spec/core/extension_spec.rb +93 -0
  156. data/spec/core/generate_spec.rb +33 -0
  157. data/spec/core/project_spec.rb +762 -0
  158. data/spec/core/test_spec.rb +1098 -0
  159. data/spec/core/transport_spec.rb +537 -0
  160. data/spec/core/util_spec.rb +67 -0
  161. data/spec/groovy/bdd_spec.rb +80 -0
  162. data/spec/groovy/compiler_spec.rb +240 -0
  163. data/spec/ide/eclipse_spec.rb +501 -0
  164. data/spec/ide/idea7x_spec.rb +84 -0
  165. data/spec/java/ant_spec.rb +33 -0
  166. data/spec/java/bdd_spec.rb +382 -0
  167. data/spec/java/cobertura_spec.rb +85 -0
  168. data/spec/java/compiler_spec.rb +446 -0
  169. data/spec/java/emma_spec.rb +119 -0
  170. data/spec/java/java_spec.rb +124 -0
  171. data/spec/java/packaging_spec.rb +1134 -0
  172. data/spec/java/test_coverage_helper.rb +257 -0
  173. data/spec/java/tests_spec.rb +493 -0
  174. data/spec/packaging/archive_spec.rb +527 -0
  175. data/spec/packaging/artifact_namespace_spec.rb +654 -0
  176. data/spec/packaging/artifact_spec.rb +795 -0
  177. data/spec/packaging/packaging_helper.rb +63 -0
  178. data/spec/packaging/packaging_spec.rb +684 -0
  179. data/spec/sandbox.rb +142 -0
  180. data/spec/scala/bdd_spec.rb +119 -0
  181. data/spec/scala/compiler_spec.rb +284 -0
  182. data/spec/scala/scala.rb +38 -0
  183. data/spec/scala/tests_spec.rb +261 -0
  184. data/spec/spec_helpers.rb +340 -0
  185. data/spec/version_requirement_spec.rb +129 -0
  186. metadata +383 -0
@@ -0,0 +1,537 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with this
3
+ # work for additional information regarding copyright ownership. The ASF
4
+ # licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations under
14
+ # the License.
15
+
16
+
17
+ require File.join(File.dirname(__FILE__), '../spec_helpers')
18
+
19
+
20
+ describe URI, '#download' do
21
+ before do
22
+ write @source = 'source', @content = 'Just a file'
23
+ @uri = URI("file://#{File.expand_path(@source)}")
24
+ @target = 'target'
25
+ end
26
+
27
+ it 'should download file if found' do
28
+ @uri.download @target
29
+ file(@target).should contain(@content)
30
+ end
31
+
32
+ it 'should fail if file not found' do
33
+ lambda { (@uri + 'missing').download @target }.should raise_error(URI::NotFoundError)
34
+ file(@target).should_not exist
35
+ end
36
+
37
+ it 'should work the same way from static method with URI' do
38
+ URI.download @uri, @target
39
+ file(@target).should contain(@content)
40
+ end
41
+
42
+ it 'should work the same way from static method with String' do
43
+ URI.download @uri.to_s, @target
44
+ file(@target).should contain(@content)
45
+ end
46
+
47
+ it 'should download to a task' do
48
+ @uri.download file(@target)
49
+ file(@target).should contain(@content)
50
+ end
51
+
52
+ it 'should download to a file' do
53
+ File.open(@target, 'w') { |file| @uri.download file }
54
+ file(@target).should contain(@content)
55
+ end
56
+ end
57
+
58
+
59
+ describe URI, '#upload' do
60
+ before do
61
+ write @source = 'source', @content = 'Just a file'
62
+ @target = 'target'
63
+ @uri = URI("file://#{File.expand_path(@target)}")
64
+ end
65
+
66
+ it 'should upload file if found' do
67
+ @uri.upload @source
68
+ file(@target).should contain(@content)
69
+ end
70
+
71
+ it 'should fail if file not found' do
72
+ lambda { @uri.upload @source.ext('missing') }.should raise_error(URI::NotFoundError)
73
+ file(@target).should_not exist
74
+ end
75
+
76
+ it 'should work the same way from static method with URI' do
77
+ URI.upload @uri, @source
78
+ file(@target).should contain(@content)
79
+ end
80
+
81
+ it 'should work the same way from static method with String' do
82
+ URI.upload @uri.to_s, @source
83
+ file(@target).should contain(@content)
84
+ end
85
+
86
+ it 'should upload from a task' do
87
+ @uri.upload file(@source)
88
+ file(@target).should contain(@content)
89
+ end
90
+
91
+ it 'should create MD5 hash' do
92
+ @uri.upload file(@source)
93
+ file(@target.ext('.md5')).should contain(Digest::MD5.hexdigest(@content))
94
+ end
95
+
96
+ it 'should create SHA1 hash' do
97
+ @uri.upload file(@source)
98
+ file(@target.ext('.sha1')).should contain(Digest::SHA1.hexdigest(@content))
99
+ end
100
+
101
+ it 'should upload an entire directory' do
102
+ mkpath 'dir' ; write 'dir/test', 'in directory'
103
+ mkpath 'dir/nested' ; write 'dir/nested/test', 'in nested directory'
104
+ @uri.upload 'dir'
105
+ file(@target).should contain('test', 'nested/test')
106
+ file(@target + '/test').should contain('in directory')
107
+ file(@target + '/nested/test').should contain('in nested directory')
108
+ end
109
+ end
110
+
111
+
112
+ describe URI::FILE do
113
+ it 'should complain about file:' do
114
+ lambda { URI('file:') }.should raise_error(URI::InvalidURIError)
115
+ end
116
+
117
+ it 'should accept file:something as file:///something' do
118
+ URI('file:something').should eql(URI('file:///something'))
119
+ end
120
+
121
+ it 'should accept file:/ as file:///' do
122
+ URI('file:/').should eql(URI('file:///'))
123
+ end
124
+
125
+ it 'should accept file:/something as file:///something' do
126
+ URI('file:/something').should eql(URI('file:///something'))
127
+ end
128
+
129
+ it 'should complain about file://' do
130
+ lambda { URI('file://').should eql(URI('file:///')) }.should raise_error(URI::InvalidURIError)
131
+ end
132
+
133
+ it 'should accept file://something as file://something/' do
134
+ URI('file://something').should eql(URI('file://something/'))
135
+ end
136
+
137
+ it 'should accept file:///something' do
138
+ URI('file:///something').should be_kind_of(URI::FILE)
139
+ URI('file:///something').to_s.should eql('file:///something')
140
+ URI('file:///something').path.should eql('/something')
141
+ end
142
+
143
+ it 'should treat host as path when host name is a Windows drive' do
144
+ URI('file://c:/something').should eql(URI('file:///c:/something'))
145
+ end
146
+ end
147
+
148
+
149
+ describe URI::FILE, '#read' do
150
+ before do
151
+ @filename = 'readme'
152
+ @uri = URI("file:///#{File.expand_path(@filename)}")
153
+ @content = 'Readme. Please!'
154
+ write 'readme', @content
155
+ end
156
+
157
+ it 'should not complain about excessive options' do
158
+ @uri.read :proxy=>[], :lovely=>true
159
+ end
160
+
161
+ it 'should read the file' do
162
+ @uri.read.should eql(@content)
163
+ end
164
+
165
+ it 'should read the file and yield to block' do
166
+ @uri.read { |content| content.should eql(@content) }
167
+ end
168
+
169
+ it 'should raise NotFoundError if file doesn\'t exist' do
170
+ lambda { (@uri + 'notme').read }.should raise_error(URI::NotFoundError)
171
+ end
172
+
173
+ it 'should raise NotFoundError if file is actually a directory' do
174
+ mkpath 'dir'
175
+ lambda { (@uri + 'dir').read }.should raise_error(URI::NotFoundError)
176
+ end
177
+ end
178
+
179
+
180
+ describe URI::FILE, '#write' do
181
+ before do
182
+ @filename = 'readme'
183
+ @uri = URI("file:///#{File.expand_path(@filename)}")
184
+ @content = 'Readme. Please!'
185
+ end
186
+
187
+ it 'should not complain about excessive options' do
188
+ @uri.write @content, :proxy=>[], :lovely=>true
189
+ end
190
+
191
+ it 'should write the file from a string' do
192
+ @uri.write @content
193
+ read(@filename).should eql(@content)
194
+ end
195
+
196
+ it 'should write the file from a reader' do
197
+ reader = Object.new
198
+ class << reader
199
+ def read(bytes) ; @array.pop ; end
200
+ end
201
+ reader.instance_variable_set :@array, [@content]
202
+ @uri.write reader
203
+ read(@filename).should eql(@content)
204
+ end
205
+
206
+ it 'should write the file from a block' do
207
+ array = [@content]
208
+ @uri.write { array.pop }
209
+ read(@filename).should eql(@content)
210
+ end
211
+
212
+ it 'should not create file if read fails' do
213
+ @uri.write { fail } rescue nil
214
+ file(@filename).should_not exist
215
+ end
216
+ end
217
+
218
+
219
+ describe URI::HTTP, '#read' do
220
+ before do
221
+ @proxy = 'http://john:smith@myproxy:8080'
222
+ @domain = 'domain'
223
+ @host_domain = "host.#{@domain}"
224
+ @path = "/foo/bar/baz"
225
+ @query = "?query"
226
+ @uri = URI("http://#{@host_domain}#{@path}#{@query}")
227
+ @no_proxy_args = [@host_domain, 80]
228
+ @proxy_args = @no_proxy_args + ['myproxy', 8080, 'john', 'smith']
229
+ @http = mock('http')
230
+ @http.stub!(:request).and_yield(Net::HTTPNotModified.new(nil, nil, nil))
231
+ end
232
+
233
+ it 'should not use proxy unless proxy is set' do
234
+ Net::HTTP.should_receive(:new).with(*@no_proxy_args).and_return(@http)
235
+ @uri.read
236
+ end
237
+
238
+ it 'should use HTTPS if applicable' do
239
+ Net::HTTP.should_receive(:new).with(@host_domain, 443).and_return(@http)
240
+ @http.should_receive(:use_ssl=).with(true)
241
+ URI(@uri.to_s.sub(/http/, 'https')).read
242
+ end
243
+
244
+ it 'should use proxy from environment variable HTTP_PROXY when using http' do
245
+ ENV['HTTP_PROXY'] = @proxy
246
+ Net::HTTP.should_receive(:new).with(*@proxy_args).and_return(@http)
247
+ @uri.read
248
+ end
249
+
250
+ it 'should use proxy from environment variable HTTPS_PROXY when using https' do
251
+ ENV['HTTPS_PROXY'] = @proxy
252
+ Net::HTTP.should_receive(:new).with(@host_domain, 443, 'myproxy', 8080, 'john', 'smith').and_return(@http)
253
+ @http.should_receive(:use_ssl=).with(true)
254
+ URI(@uri.to_s.sub(/http/, 'https')).read
255
+ end
256
+
257
+ it 'should not use proxy for hosts from environment variable NO_PROXY' do
258
+ ENV['HTTP_PROXY'] = @proxy
259
+ ENV['NO_PROXY'] = @host_domain
260
+ Net::HTTP.should_receive(:new).with(*@no_proxy_args).and_return(@http)
261
+ @uri.read
262
+ end
263
+
264
+ it 'should use proxy for hosts other than those specified by NO_PROXY' do
265
+ ENV['HTTP_PROXY'] = @proxy
266
+ ENV['NO_PROXY'] = 'whatever'
267
+ Net::HTTP.should_receive(:new).with(*@proxy_args).and_return(@http)
268
+ @uri.read
269
+ end
270
+
271
+ it 'should support comma separated list in environment variable NO_PROXY' do
272
+ ENV['HTTP_PROXY'] = @proxy
273
+ ENV['NO_PROXY'] = 'optimus,prime'
274
+ Net::HTTP.should_receive(:new).with('optimus', 80).and_return(@http)
275
+ URI('http://optimus').read
276
+ Net::HTTP.should_receive(:new).with('prime', 80).and_return(@http)
277
+ URI('http://prime').read
278
+ Net::HTTP.should_receive(:new).with('bumblebee', *@proxy_args[1..-1]).and_return(@http)
279
+ URI('http://bumblebee').read
280
+ end
281
+
282
+ it 'should support glob pattern in NO_PROXY' do
283
+ ENV['HTTP_PROXY'] = @proxy
284
+ ENV['NO_PROXY'] = "*.#{@domain}"
285
+ Net::HTTP.should_receive(:new).once.with(*@no_proxy_args).and_return(@http)
286
+ @uri.read
287
+ end
288
+
289
+ it 'should support specific port in NO_PROXY' do
290
+ ENV['HTTP_PROXY'] = @proxy
291
+ ENV['NO_PROXY'] = "#{@host_domain}:80"
292
+ Net::HTTP.should_receive(:new).with(*@no_proxy_args).and_return(@http)
293
+ @uri.read
294
+ ENV['NO_PROXY'] = "#{@host_domain}:800"
295
+ Net::HTTP.should_receive(:new).with(*@proxy_args).and_return(@http)
296
+ @uri.read
297
+ end
298
+
299
+ it 'should not die if content size is zero' do
300
+ ok = Net::HTTPOK.new(nil, nil, nil)
301
+ ok.stub!(:read_body)
302
+ @http.stub!(:request).and_yield(ok)
303
+ Net::HTTP.should_receive(:new).and_return(@http)
304
+ $stdout.should_receive(:isatty).and_return(false)
305
+ @uri.read :progress=>true
306
+ end
307
+
308
+ it 'should use HTTP Basic authentication' do
309
+ Net::HTTP.should_receive(:new).and_return(@http)
310
+ request = mock('request')
311
+ Net::HTTP::Get.should_receive(:new).and_return(request)
312
+ request.should_receive(:basic_auth).with('john', 'secret')
313
+ URI("http://john:secret@#{@host_domain}").read
314
+ end
315
+
316
+ it 'should preseve authentication information during a redirect' do
317
+ Net::HTTP.should_receive(:new).twice.and_return(@http)
318
+
319
+ # The first request will produce a redirect
320
+ redirect = Net::HTTPRedirection.new(nil, nil, nil)
321
+ redirect['Location'] = "http://#{@host_domain}/asdf"
322
+
323
+ request1 = mock('request1')
324
+ Net::HTTP::Get.should_receive(:new).once.with('/', nil).and_return(request1)
325
+ request1.should_receive(:basic_auth).with('john', 'secret')
326
+ @http.should_receive(:request).with(request1).and_yield(redirect)
327
+
328
+ # The second request will be ok
329
+ ok = Net::HTTPOK.new(nil, nil, nil)
330
+ ok.stub!(:read_body)
331
+
332
+ request2 = mock('request2')
333
+ Net::HTTP::Get.should_receive(:new).once.with("/asdf", nil).and_return(request2)
334
+ request2.should_receive(:basic_auth).with('john', 'secret')
335
+ @http.should_receive(:request).with(request2).and_yield(ok)
336
+
337
+ URI("http://john:secret@#{@host_domain}").read
338
+ end
339
+
340
+ it 'should include the query part when performing HTTP GET' do
341
+ # should this test be generalized or shared with any other URI subtypes?
342
+ Net::HTTP.stub!(:new).and_return(@http)
343
+ Net::HTTP::Get.should_receive(:new).with(/#{Regexp.escape(@query)}$/, nil)
344
+ @uri.read
345
+ end
346
+
347
+ end
348
+
349
+
350
+ describe URI::HTTP, '#write' do
351
+ before do
352
+ @content = 'Readme. Please!'
353
+ @uri = URI('http://john:secret@host.domain/foo/bar/baz.jar')
354
+ @http = mock('Net::HTTP')
355
+ @http.stub!(:request).and_return(Net::HTTPOK.new(nil, nil, nil))
356
+ Net::HTTP.stub!(:new).and_return(@http)
357
+ end
358
+
359
+ it 'should open connection to HTTP server' do
360
+ Net::HTTP.should_receive(:new).with('host.domain', 80).and_return(@http)
361
+ @uri.write @content
362
+ end
363
+
364
+ it 'should use HTTP basic authentication' do
365
+ @http.should_receive(:request) do |request|
366
+ request['authorization'].should == ('Basic ' + ['john:secret'].pack('m').delete("\r\n"))
367
+ Net::HTTPOK.new(nil, nil, nil)
368
+ end
369
+ @uri.write @content
370
+ end
371
+
372
+ it 'should use HTTPS if applicable' do
373
+ Net::HTTP.should_receive(:new).with('host.domain', 443).and_return(@http)
374
+ @http.should_receive(:use_ssl=).with(true)
375
+ URI(@uri.to_s.sub(/http/, 'https')).write @content
376
+ end
377
+
378
+ it 'should upload file with PUT request' do
379
+ @http.should_receive(:request) do |request|
380
+ request.should be_kind_of(Net::HTTP::Put)
381
+ Net::HTTPOK.new(nil, nil, nil)
382
+ end
383
+ @uri.write @content
384
+ end
385
+
386
+ it 'should set Content-Length header' do
387
+ @http.should_receive(:request) do |request|
388
+ request.content_length.should == @content.size
389
+ Net::HTTPOK.new(nil, nil, nil)
390
+ end
391
+ @uri.write @content
392
+ end
393
+
394
+ it 'should set Content-MD5 header' do
395
+ @http.should_receive(:request) do |request|
396
+ request['Content-MD5'].should == Digest::MD5.hexdigest(@content)
397
+ Net::HTTPOK.new(nil, nil, nil)
398
+ end
399
+ @uri.write @content
400
+ end
401
+
402
+ it 'should send entire content' do
403
+ @http.should_receive(:request) do |request|
404
+ body_stream = request.body_stream
405
+ body_stream.read(1024).should == @content
406
+ body_stream.read(1024).should be_nil
407
+ Net::HTTPOK.new(nil, nil, nil)
408
+ end
409
+ @uri.write @content
410
+ end
411
+
412
+ it 'should fail on 4xx response' do
413
+ @http.should_receive(:request).and_return(Net::HTTPBadRequest.new(nil, nil, nil))
414
+ lambda { @uri.write @content }.should raise_error(RuntimeError, /failed to upload/i)
415
+ end
416
+
417
+ it 'should fail on 5xx response' do
418
+ @http.should_receive(:request).and_return(Net::HTTPServiceUnavailable.new(nil, nil, nil))
419
+ lambda { @uri.write @content }.should raise_error(RuntimeError, /failed to upload/i)
420
+ end
421
+
422
+ end
423
+
424
+
425
+ describe URI::SFTP, '#read' do
426
+ before do
427
+ @uri = URI('sftp://john:secret@localhost/root/path/readme')
428
+ @content = 'Readme. Please!'
429
+
430
+ @ssh_session = mock('Net::SSH::Session')
431
+ @sftp_session = mock('Net::SFTP::Session')
432
+ @file_factory = mock('Net::SFTP::Operations::FileFactory')
433
+ Net::SSH.stub!(:start).with('localhost', 'john', :password=>'secret', :port=>22).and_return(@ssh_session) do
434
+ Net::SFTP::Session.should_receive(:new).with(@ssh_session).and_yield(@sftp_session).and_return(@sftp_session)
435
+ @sftp_session.should_receive(:connect!).and_return(@sftp_session)
436
+ @sftp_session.should_receive(:loop)
437
+ @sftp_session.should_receive(:file).with.and_return(@file_factory)
438
+ @file_factory.stub!(:open)
439
+ @ssh_session.should_receive(:close)
440
+ @ssh_session
441
+ end
442
+ end
443
+
444
+ it 'should open connection to SFTP server' do
445
+ @uri.read
446
+ end
447
+
448
+ it 'should open file for reading' do
449
+ @file_factory.should_receive(:open).with('/root/path/readme', 'r')
450
+ @uri.read
451
+ end
452
+
453
+ it 'should read contents of file and return it' do
454
+ file = mock('Net::SFTP::Operations::File')
455
+ file.should_receive(:read).with(URI::RW_CHUNK_SIZE).once.and_return(@content, nil)
456
+ @file_factory.should_receive(:open).with('/root/path/readme', 'r').and_yield(file)
457
+ @uri.read.should eql(@content)
458
+ end
459
+
460
+ it 'should read contents of file and pass it to block' do
461
+ file = mock('Net::SFTP::Operations::File')
462
+ file.should_receive(:read).with(URI::RW_CHUNK_SIZE).once.and_return(@content, nil)
463
+ @file_factory.should_receive(:open).with('/root/path/readme', 'r').and_yield(file)
464
+ content = ''
465
+ @uri.read do |chunk|
466
+ content << chunk
467
+ end
468
+ content.should eql(@content)
469
+ end
470
+ end
471
+
472
+
473
+ describe URI::SFTP, '#write' do
474
+ before do
475
+ @uri = URI('sftp://john:secret@localhost/root/path/readme')
476
+ @content = 'Readme. Please!'
477
+
478
+ @ssh_session = mock('Net::SSH::Session')
479
+ @sftp_session = mock('Net::SFTP::Session')
480
+ @file_factory = mock('Net::SFTP::Operations::FileFactory')
481
+ Net::SSH.stub!(:start).with('localhost', 'john', :password=>'secret', :port=>22).and_return(@ssh_session) do
482
+ Net::SFTP::Session.should_receive(:new).with(@ssh_session).and_yield(@sftp_session).and_return(@sftp_session)
483
+ @sftp_session.should_receive(:connect!).and_return(@sftp_session)
484
+ @sftp_session.should_receive(:loop)
485
+ @sftp_session.stub!(:opendir!).and_return { fail }
486
+ @sftp_session.stub!(:close)
487
+ @sftp_session.stub!(:mkdir!)
488
+ @sftp_session.should_receive(:file).with.and_return(@file_factory)
489
+ @file_factory.stub!(:open)
490
+ @ssh_session.should_receive(:close)
491
+ @ssh_session
492
+ end
493
+ end
494
+
495
+ it 'should open connection to SFTP server' do
496
+ @uri.write @content
497
+ end
498
+
499
+ it 'should check that path exists on server' do
500
+ paths = ['/root', '/root/path']
501
+ @sftp_session.should_receive(:opendir!).with(anything()).twice { |path| paths.shift.should == path }
502
+ @uri.write @content
503
+ end
504
+
505
+ it 'should close all opened directories' do
506
+ @sftp_session.should_receive(:opendir!).with(anything()).twice do |path|
507
+ @sftp_session.should_receive(:close).with(handle = Object.new)
508
+ handle
509
+ end
510
+ @uri.write @content
511
+ end
512
+
513
+ it 'should create missing paths on server' do
514
+ @sftp_session.should_receive(:opendir!) { |path| fail unless path == '/root' }
515
+ @sftp_session.should_receive(:mkdir!).once.with('/root/path', {})
516
+ @uri.write @content
517
+ end
518
+
519
+ it 'should create missing directories recursively' do
520
+ paths = ['/root', '/root/path']
521
+ @sftp_session.should_receive(:mkdir!).with(anything(), {}).twice { |path, options| paths.shift.should == path }
522
+ @uri.write @content
523
+ end
524
+
525
+ it 'should open file for writing' do
526
+ @file_factory.should_receive(:open).with('/root/path/readme', 'w')
527
+ @uri.write @content
528
+ end
529
+
530
+ it 'should write contents to file' do
531
+ file = mock('Net::SFTP::Operations::File')
532
+ file.should_receive(:write).with(@content)
533
+ @file_factory.should_receive(:open).with('/root/path/readme', 'w').and_yield(file)
534
+ @uri.write @content
535
+ end
536
+
537
+ end