assaf-buildr 1.3.3

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 (163) hide show
  1. data/CHANGELOG +887 -0
  2. data/DISCLAIMER +7 -0
  3. data/LICENSE +176 -0
  4. data/NOTICE +26 -0
  5. data/README.rdoc +146 -0
  6. data/Rakefile +62 -0
  7. data/_buildr +38 -0
  8. data/addon/buildr/antlr.rb +65 -0
  9. data/addon/buildr/cobertura.rb +236 -0
  10. data/addon/buildr/emma.rb +238 -0
  11. data/addon/buildr/hibernate.rb +142 -0
  12. data/addon/buildr/javacc.rb +85 -0
  13. data/addon/buildr/jdepend.rb +60 -0
  14. data/addon/buildr/jetty.rb +248 -0
  15. data/addon/buildr/jibx.rb +86 -0
  16. data/addon/buildr/nailgun.rb +817 -0
  17. data/addon/buildr/openjpa.rb +90 -0
  18. data/addon/buildr/org/apache/buildr/BuildrNail$Main.class +0 -0
  19. data/addon/buildr/org/apache/buildr/BuildrNail.class +0 -0
  20. data/addon/buildr/org/apache/buildr/BuildrNail.java +41 -0
  21. data/addon/buildr/org/apache/buildr/JettyWrapper$1.class +0 -0
  22. data/addon/buildr/org/apache/buildr/JettyWrapper$BuildrHandler.class +0 -0
  23. data/addon/buildr/org/apache/buildr/JettyWrapper.class +0 -0
  24. data/addon/buildr/org/apache/buildr/JettyWrapper.java +144 -0
  25. data/addon/buildr/xmlbeans.rb +93 -0
  26. data/bin/buildr +28 -0
  27. data/buildr.buildfile +53 -0
  28. data/buildr.gemspec +58 -0
  29. data/doc/css/default.css +228 -0
  30. data/doc/css/print.css +100 -0
  31. data/doc/css/syntax.css +52 -0
  32. data/doc/images/apache-incubator-logo.png +0 -0
  33. data/doc/images/buildr-hires.png +0 -0
  34. data/doc/images/buildr.png +0 -0
  35. data/doc/images/favicon.png +0 -0
  36. data/doc/images/growl-icon.tiff +0 -0
  37. data/doc/images/note.png +0 -0
  38. data/doc/images/project-structure.png +0 -0
  39. data/doc/images/tip.png +0 -0
  40. data/doc/images/zbuildr.tif +0 -0
  41. data/doc/pages/artifacts.textile +207 -0
  42. data/doc/pages/building.textile +240 -0
  43. data/doc/pages/contributing.textile +208 -0
  44. data/doc/pages/download.textile +62 -0
  45. data/doc/pages/extending.textile +175 -0
  46. data/doc/pages/getting_started.textile +273 -0
  47. data/doc/pages/index.textile +42 -0
  48. data/doc/pages/languages.textile +407 -0
  49. data/doc/pages/mailing_lists.textile +17 -0
  50. data/doc/pages/more_stuff.textile +286 -0
  51. data/doc/pages/packaging.textile +427 -0
  52. data/doc/pages/projects.textile +274 -0
  53. data/doc/pages/recipes.textile +103 -0
  54. data/doc/pages/settings_profiles.textile +274 -0
  55. data/doc/pages/testing.textile +212 -0
  56. data/doc/pages/troubleshooting.textile +103 -0
  57. data/doc/pages/whats_new.textile +323 -0
  58. data/doc/print.haml +51 -0
  59. data/doc/print.toc.yaml +29 -0
  60. data/doc/scripts/buildr-git.rb +412 -0
  61. data/doc/scripts/install-jruby.sh +44 -0
  62. data/doc/scripts/install-linux.sh +64 -0
  63. data/doc/scripts/install-osx.sh +52 -0
  64. data/doc/site.haml +56 -0
  65. data/doc/site.toc.yaml +47 -0
  66. data/etc/KEYS +151 -0
  67. data/etc/git-svn-authors +16 -0
  68. data/lib/buildr.rb +35 -0
  69. data/lib/buildr/core.rb +27 -0
  70. data/lib/buildr/core/application.rb +489 -0
  71. data/lib/buildr/core/application_cli.rb +139 -0
  72. data/lib/buildr/core/build.rb +311 -0
  73. data/lib/buildr/core/checks.rb +382 -0
  74. data/lib/buildr/core/common.rb +154 -0
  75. data/lib/buildr/core/compile.rb +596 -0
  76. data/lib/buildr/core/environment.rb +120 -0
  77. data/lib/buildr/core/filter.rb +362 -0
  78. data/lib/buildr/core/generate.rb +195 -0
  79. data/lib/buildr/core/help.rb +118 -0
  80. data/lib/buildr/core/progressbar.rb +156 -0
  81. data/lib/buildr/core/project.rb +892 -0
  82. data/lib/buildr/core/test.rb +715 -0
  83. data/lib/buildr/core/transports.rb +558 -0
  84. data/lib/buildr/core/util.rb +289 -0
  85. data/lib/buildr/groovy.rb +18 -0
  86. data/lib/buildr/groovy/bdd.rb +105 -0
  87. data/lib/buildr/groovy/compiler.rb +138 -0
  88. data/lib/buildr/ide.rb +19 -0
  89. data/lib/buildr/ide/eclipse.rb +212 -0
  90. data/lib/buildr/ide/idea.ipr.template +300 -0
  91. data/lib/buildr/ide/idea.rb +189 -0
  92. data/lib/buildr/ide/idea7x.ipr.template +290 -0
  93. data/lib/buildr/ide/idea7x.rb +210 -0
  94. data/lib/buildr/java.rb +23 -0
  95. data/lib/buildr/java/ant.rb +92 -0
  96. data/lib/buildr/java/bdd.rb +449 -0
  97. data/lib/buildr/java/commands.rb +211 -0
  98. data/lib/buildr/java/compiler.rb +348 -0
  99. data/lib/buildr/java/deprecated.rb +141 -0
  100. data/lib/buildr/java/jruby.rb +117 -0
  101. data/lib/buildr/java/jtestr_runner.rb.erb +116 -0
  102. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.class +0 -0
  103. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.java +119 -0
  104. data/lib/buildr/java/packaging.rb +713 -0
  105. data/lib/buildr/java/pom.rb +178 -0
  106. data/lib/buildr/java/rjb.rb +155 -0
  107. data/lib/buildr/java/test_result.rb +308 -0
  108. data/lib/buildr/java/tests.rb +324 -0
  109. data/lib/buildr/java/version_requirement.rb +172 -0
  110. data/lib/buildr/packaging.rb +21 -0
  111. data/lib/buildr/packaging/artifact.rb +730 -0
  112. data/lib/buildr/packaging/artifact_namespace.rb +972 -0
  113. data/lib/buildr/packaging/artifact_search.rb +140 -0
  114. data/lib/buildr/packaging/gems.rb +102 -0
  115. data/lib/buildr/packaging/package.rb +233 -0
  116. data/lib/buildr/packaging/tar.rb +104 -0
  117. data/lib/buildr/packaging/zip.rb +722 -0
  118. data/lib/buildr/resources/buildr.icns +0 -0
  119. data/lib/buildr/scala.rb +19 -0
  120. data/lib/buildr/scala/compiler.rb +109 -0
  121. data/lib/buildr/scala/tests.rb +203 -0
  122. data/rakelib/apache.rake +191 -0
  123. data/rakelib/changelog.rake +57 -0
  124. data/rakelib/doc.rake +103 -0
  125. data/rakelib/package.rake +73 -0
  126. data/rakelib/release.rake +65 -0
  127. data/rakelib/rspec.rake +83 -0
  128. data/rakelib/rubyforge.rake +53 -0
  129. data/rakelib/scm.rake +49 -0
  130. data/rakelib/setup.rake +86 -0
  131. data/rakelib/stage.rake +48 -0
  132. data/spec/addon/cobertura_spec.rb +77 -0
  133. data/spec/addon/emma_spec.rb +120 -0
  134. data/spec/addon/test_coverage_spec.rb +255 -0
  135. data/spec/core/application_spec.rb +412 -0
  136. data/spec/core/artifact_namespace_spec.rb +646 -0
  137. data/spec/core/build_spec.rb +415 -0
  138. data/spec/core/checks_spec.rb +537 -0
  139. data/spec/core/common_spec.rb +664 -0
  140. data/spec/core/compile_spec.rb +566 -0
  141. data/spec/core/generate_spec.rb +33 -0
  142. data/spec/core/project_spec.rb +754 -0
  143. data/spec/core/test_spec.rb +1091 -0
  144. data/spec/core/transport_spec.rb +500 -0
  145. data/spec/groovy/bdd_spec.rb +80 -0
  146. data/spec/groovy/compiler_spec.rb +239 -0
  147. data/spec/ide/eclipse_spec.rb +243 -0
  148. data/spec/java/ant.rb +28 -0
  149. data/spec/java/bdd_spec.rb +358 -0
  150. data/spec/java/compiler_spec.rb +446 -0
  151. data/spec/java/java_spec.rb +88 -0
  152. data/spec/java/packaging_spec.rb +1103 -0
  153. data/spec/java/tests_spec.rb +466 -0
  154. data/spec/packaging/archive_spec.rb +503 -0
  155. data/spec/packaging/artifact_spec.rb +754 -0
  156. data/spec/packaging/packaging_helper.rb +63 -0
  157. data/spec/packaging/packaging_spec.rb +589 -0
  158. data/spec/sandbox.rb +137 -0
  159. data/spec/scala/compiler_spec.rb +228 -0
  160. data/spec/scala/tests_spec.rb +215 -0
  161. data/spec/spec_helpers.rb +304 -0
  162. data/spec/version_requirement_spec.rb +123 -0
  163. metadata +369 -0
@@ -0,0 +1,500 @@
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 proxy from environment variable HTTP_PROXY' do
239
+ ENV['HTTP_PROXY'] = @proxy
240
+ Net::HTTP.should_receive(:new).with(*@proxy_args).and_return(@http)
241
+ @uri.read
242
+ end
243
+
244
+ it 'should not use proxy for hosts from environment variable NO_PROXY' do
245
+ ENV['HTTP_PROXY'] = @proxy
246
+ ENV['NO_PROXY'] = @host_domain
247
+ Net::HTTP.should_receive(:new).with(*@no_proxy_args).and_return(@http)
248
+ @uri.read
249
+ end
250
+
251
+ it 'should use proxy for hosts other than those specified by NO_PROXY' do
252
+ ENV['HTTP_PROXY'] = @proxy
253
+ ENV['NO_PROXY'] = 'whatever'
254
+ Net::HTTP.should_receive(:new).with(*@proxy_args).and_return(@http)
255
+ @uri.read
256
+ end
257
+
258
+ it 'should support comma separated list in environment variable NO_PROXY' do
259
+ ENV['HTTP_PROXY'] = @proxy
260
+ ENV['NO_PROXY'] = 'optimus,prime'
261
+ Net::HTTP.should_receive(:new).with('optimus', 80).and_return(@http)
262
+ URI('http://optimus').read
263
+ Net::HTTP.should_receive(:new).with('prime', 80).and_return(@http)
264
+ URI('http://prime').read
265
+ Net::HTTP.should_receive(:new).with('bumblebee', *@proxy_args[1..-1]).and_return(@http)
266
+ URI('http://bumblebee').read
267
+ end
268
+
269
+ it 'should support glob pattern in NO_PROXY' do
270
+ ENV['HTTP_PROXY'] = @proxy
271
+ ENV['NO_PROXY'] = "*.#{@domain}"
272
+ Net::HTTP.should_receive(:new).once.with(*@no_proxy_args).and_return(@http)
273
+ @uri.read
274
+ end
275
+
276
+ it 'should support specific port in NO_PROXY' do
277
+ ENV['HTTP_PROXY'] = @proxy
278
+ ENV['NO_PROXY'] = "#{@host_domain}:80"
279
+ Net::HTTP.should_receive(:new).with(*@no_proxy_args).and_return(@http)
280
+ @uri.read
281
+ ENV['NO_PROXY'] = "#{@host_domain}:800"
282
+ Net::HTTP.should_receive(:new).with(*@proxy_args).and_return(@http)
283
+ @uri.read
284
+ end
285
+
286
+ it 'should not die if content size is zero' do
287
+ ok = Net::HTTPOK.new(nil, nil, nil)
288
+ ok.stub!(:read_body)
289
+ @http.stub!(:request).and_yield(ok)
290
+ Net::HTTP.should_receive(:new).and_return(@http)
291
+ $stdout.should_receive(:isatty).and_return(false)
292
+ @uri.read :progress=>true
293
+ end
294
+
295
+ it 'should use HTTP Basic authentication' do
296
+ Net::HTTP.should_receive(:new).and_return(@http)
297
+ request = mock('request')
298
+ Net::HTTP::Get.should_receive(:new).and_return(request)
299
+ request.should_receive(:basic_auth).with('john', 'secret')
300
+ URI("http://john:secret@#{@host_domain}").read
301
+ end
302
+
303
+ it 'should include the query part when performing HTTP GET' do
304
+ # should this test be generalized or shared with any other URI subtypes?
305
+ Net::HTTP.stub!(:new).and_return(@http)
306
+ Net::HTTP::Get.should_receive(:new).with(/#{Regexp.escape(@query)}$/, nil)
307
+ @uri.read
308
+ end
309
+
310
+ end
311
+
312
+
313
+ describe URI::HTTP, '#write' do
314
+ before do
315
+ @content = 'Readme. Please!'
316
+ @uri = URI('http://john:secret@host.domain/foo/bar/baz.jar')
317
+ @http = mock('Net::HTTP')
318
+ @http.stub!(:request).and_return(Net::HTTPOK.new(nil, nil, nil))
319
+ Net::HTTP.stub!(:new).and_return(@http)
320
+ end
321
+
322
+ it 'should open connection to HTTP server' do
323
+ Net::HTTP.should_receive(:new).with('host.domain', 80).and_return(@http)
324
+ @uri.write @content
325
+ end
326
+
327
+ it 'should use HTTP basic authentication' do
328
+ @http.should_receive(:request) do |request|
329
+ request['authorization'].should == ('Basic ' + ['john:secret'].pack('m').delete("\r\n"))
330
+ Net::HTTPOK.new(nil, nil, nil)
331
+ end
332
+ @uri.write @content
333
+ end
334
+
335
+ it 'should use HTTPS if applicable' do
336
+ Net::HTTP.should_receive(:new).with('host.domain', 443).and_return(@http)
337
+ @http.should_receive(:use_ssl=).with(true)
338
+ URI(@uri.to_s.sub(/http/, 'https')).write @content
339
+ end
340
+
341
+ it 'should upload file with PUT request' do
342
+ @http.should_receive(:request) do |request|
343
+ request.should be_kind_of(Net::HTTP::Put)
344
+ Net::HTTPOK.new(nil, nil, nil)
345
+ end
346
+ @uri.write @content
347
+ end
348
+
349
+ it 'should set Content-Length header' do
350
+ @http.should_receive(:request) do |request|
351
+ request.content_length.should == @content.size
352
+ Net::HTTPOK.new(nil, nil, nil)
353
+ end
354
+ @uri.write @content
355
+ end
356
+
357
+ it 'should set Content-MD5 header' do
358
+ @http.should_receive(:request) do |request|
359
+ request['Content-MD5'].should == Digest::MD5.hexdigest(@content)
360
+ Net::HTTPOK.new(nil, nil, nil)
361
+ end
362
+ @uri.write @content
363
+ end
364
+
365
+ it 'should send entire content' do
366
+ @http.should_receive(:request) do |request|
367
+ body_stream = request.body_stream
368
+ body_stream.read(1024).should == @content
369
+ body_stream.read(1024).should be_nil
370
+ Net::HTTPOK.new(nil, nil, nil)
371
+ end
372
+ @uri.write @content
373
+ end
374
+
375
+ it 'should fail on 4xx response' do
376
+ @http.should_receive(:request).and_return(Net::HTTPBadRequest.new(nil, nil, nil))
377
+ lambda { @uri.write @content }.should raise_error(RuntimeError, /failed to upload/i)
378
+ end
379
+
380
+ it 'should fail on 5xx response' do
381
+ @http.should_receive(:request).and_return(Net::HTTPServiceUnavailable.new(nil, nil, nil))
382
+ lambda { @uri.write @content }.should raise_error(RuntimeError, /failed to upload/i)
383
+ end
384
+
385
+ end
386
+
387
+
388
+ describe URI::SFTP, '#read' do
389
+ before do
390
+ @uri = URI('sftp://john:secret@localhost/root/path/readme')
391
+ @content = 'Readme. Please!'
392
+
393
+ @ssh_session = mock('Net::SSH::Session')
394
+ @sftp_session = mock('Net::SFTP::Session')
395
+ @file_factory = mock('Net::SFTP::Operations::FileFactory')
396
+ Net::SSH.stub!(:start).with('localhost', 'john', :password=>'secret', :port=>22).and_return(@ssh_session) do
397
+ Net::SFTP::Session.should_receive(:new).with(@ssh_session).and_yield(@sftp_session).and_return(@sftp_session)
398
+ @sftp_session.should_receive(:connect!).and_return(@sftp_session)
399
+ @sftp_session.should_receive(:loop)
400
+ @sftp_session.should_receive(:file).with.and_return(@file_factory)
401
+ @file_factory.stub!(:open)
402
+ @ssh_session.should_receive(:close)
403
+ @ssh_session
404
+ end
405
+ end
406
+
407
+ it 'should open connection to SFTP server' do
408
+ @uri.read
409
+ end
410
+
411
+ it 'should open file for reading' do
412
+ @file_factory.should_receive(:open).with('/root/path/readme', 'r')
413
+ @uri.read
414
+ end
415
+
416
+ it 'should read contents of file and return it' do
417
+ file = mock('Net::SFTP::Operations::File')
418
+ file.should_receive(:read).with(an_instance_of(Numeric)).once.and_return(@content, nil)
419
+ @file_factory.should_receive(:open).with('/root/path/readme', 'r').and_yield(file)
420
+ @uri.read.should eql(@content)
421
+ end
422
+
423
+ it 'should read contents of file and pass it to block' do
424
+ file = mock('Net::SFTP::Operations::File')
425
+ file.should_receive(:read).with(an_instance_of(Numeric)).once.and_return(@content, nil)
426
+ @file_factory.should_receive(:open).with('/root/path/readme', 'r').and_yield(file)
427
+ content = ''
428
+ @uri.read do |chunk|
429
+ content << chunk
430
+ end
431
+ content.should eql(@content)
432
+ end
433
+ end
434
+
435
+
436
+ describe URI::SFTP, '#write' do
437
+ before do
438
+ @uri = URI('sftp://john:secret@localhost/root/path/readme')
439
+ @content = 'Readme. Please!'
440
+
441
+ @ssh_session = mock('Net::SSH::Session')
442
+ @sftp_session = mock('Net::SFTP::Session')
443
+ @file_factory = mock('Net::SFTP::Operations::FileFactory')
444
+ Net::SSH.stub!(:start).with('localhost', 'john', :password=>'secret', :port=>22).and_return(@ssh_session) do
445
+ Net::SFTP::Session.should_receive(:new).with(@ssh_session).and_yield(@sftp_session).and_return(@sftp_session)
446
+ @sftp_session.should_receive(:connect!).and_return(@sftp_session)
447
+ @sftp_session.should_receive(:loop)
448
+ @sftp_session.stub!(:opendir!).and_return { fail }
449
+ @sftp_session.stub!(:close)
450
+ @sftp_session.stub!(:mkdir!)
451
+ @sftp_session.should_receive(:file).with.and_return(@file_factory)
452
+ @file_factory.stub!(:open)
453
+ @ssh_session.should_receive(:close)
454
+ @ssh_session
455
+ end
456
+ end
457
+
458
+ it 'should open connection to SFTP server' do
459
+ @uri.write @content
460
+ end
461
+
462
+ it 'should check that path exists on server' do
463
+ paths = ['/root', '/root/path']
464
+ @sftp_session.should_receive(:opendir!).with(anything()).twice { |path| paths.shift.should == path }
465
+ @uri.write @content
466
+ end
467
+
468
+ it 'should close all opened directories' do
469
+ @sftp_session.should_receive(:opendir!).with(anything()).twice do |path|
470
+ @sftp_session.should_receive(:close).with(handle = Object.new)
471
+ handle
472
+ end
473
+ @uri.write @content
474
+ end
475
+
476
+ it 'should create missing paths on server' do
477
+ @sftp_session.should_receive(:opendir!).twice { |path| fail unless path == '/root' }
478
+ @sftp_session.should_receive(:mkdir!).once.with('/root/path', {})
479
+ @uri.write @content
480
+ end
481
+
482
+ it 'should create missing directories recursively' do
483
+ paths = ['/root', '/root/path']
484
+ @sftp_session.should_receive(:mkdir!).with(anything(), {}).twice { |path, options| paths.shift.should == path }
485
+ @uri.write @content
486
+ end
487
+
488
+ it 'should open file for writing' do
489
+ @file_factory.should_receive(:open).with('/root/path/readme', 'w')
490
+ @uri.write @content
491
+ end
492
+
493
+ it 'should write contents to file' do
494
+ file = mock('Net::SFTP::Operations::File')
495
+ file.should_receive(:write).with(@content)
496
+ @file_factory.should_receive(:open).with('/root/path/readme', 'w').and_yield(file)
497
+ @uri.write @content
498
+ end
499
+
500
+ end