summaryrefslogtreecommitdiff
path: root/spec/ruby/library/net/ftp
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/library/net/ftp')
-rw-r--r--spec/ruby/library/net/ftp/abort_spec.rb62
-rw-r--r--spec/ruby/library/net/ftp/acct_spec.rb58
-rw-r--r--spec/ruby/library/net/ftp/binary_spec.rb24
-rw-r--r--spec/ruby/library/net/ftp/chdir_spec.rb99
-rw-r--r--spec/ruby/library/net/ftp/close_spec.rb30
-rw-r--r--spec/ruby/library/net/ftp/closed_spec.rb21
-rw-r--r--spec/ruby/library/net/ftp/connect_spec.rb49
-rw-r--r--spec/ruby/library/net/ftp/debug_mode_spec.rb23
-rw-r--r--spec/ruby/library/net/ftp/default_passive_spec.rb10
-rw-r--r--spec/ruby/library/net/ftp/delete_spec.rb59
-rw-r--r--spec/ruby/library/net/ftp/dir_spec.rb8
-rw-r--r--spec/ruby/library/net/ftp/fixtures/default_passive.rb3
-rw-r--r--spec/ruby/library/net/ftp/fixtures/passive.rb2
-rw-r--r--spec/ruby/library/net/ftp/fixtures/putbinaryfile3
-rw-r--r--spec/ruby/library/net/ftp/fixtures/puttextfile3
-rw-r--r--spec/ruby/library/net/ftp/fixtures/server.rb273
-rw-r--r--spec/ruby/library/net/ftp/get_spec.rb21
-rw-r--r--spec/ruby/library/net/ftp/getbinaryfile_spec.rb8
-rw-r--r--spec/ruby/library/net/ftp/getdir_spec.rb7
-rw-r--r--spec/ruby/library/net/ftp/gettextfile_spec.rb8
-rw-r--r--spec/ruby/library/net/ftp/help_spec.rb66
-rw-r--r--spec/ruby/library/net/ftp/initialize_spec.rb87
-rw-r--r--spec/ruby/library/net/ftp/last_response_code_spec.rb8
-rw-r--r--spec/ruby/library/net/ftp/last_response_spec.rb25
-rw-r--r--spec/ruby/library/net/ftp/lastresp_spec.rb8
-rw-r--r--spec/ruby/library/net/ftp/list_spec.rb8
-rw-r--r--spec/ruby/library/net/ftp/login_spec.rb195
-rw-r--r--spec/ruby/library/net/ftp/ls_spec.rb8
-rw-r--r--spec/ruby/library/net/ftp/mdtm_spec.rb38
-rw-r--r--spec/ruby/library/net/ftp/mkdir_spec.rb61
-rw-r--r--spec/ruby/library/net/ftp/mtime_spec.rb50
-rw-r--r--spec/ruby/library/net/ftp/nlst_spec.rb92
-rw-r--r--spec/ruby/library/net/ftp/noop_spec.rb38
-rw-r--r--spec/ruby/library/net/ftp/open_spec.rb55
-rw-r--r--spec/ruby/library/net/ftp/passive_spec.rb36
-rw-r--r--spec/ruby/library/net/ftp/put_spec.rb21
-rw-r--r--spec/ruby/library/net/ftp/putbinaryfile_spec.rb8
-rw-r--r--spec/ruby/library/net/ftp/puttextfile_spec.rb8
-rw-r--r--spec/ruby/library/net/ftp/pwd_spec.rb53
-rw-r--r--spec/ruby/library/net/ftp/quit_spec.rb33
-rw-r--r--spec/ruby/library/net/ftp/rename_spec.rb94
-rw-r--r--spec/ruby/library/net/ftp/resume_spec.rb23
-rw-r--r--spec/ruby/library/net/ftp/retrbinary_spec.rb30
-rw-r--r--spec/ruby/library/net/ftp/retrlines_spec.rb34
-rw-r--r--spec/ruby/library/net/ftp/return_code_spec.rb24
-rw-r--r--spec/ruby/library/net/ftp/rmdir_spec.rb58
-rw-r--r--spec/ruby/library/net/ftp/sendcmd_spec.rb54
-rw-r--r--spec/ruby/library/net/ftp/set_socket_spec.rb8
-rw-r--r--spec/ruby/library/net/ftp/shared/getbinaryfile.rb150
-rw-r--r--spec/ruby/library/net/ftp/shared/gettextfile.rb100
-rw-r--r--spec/ruby/library/net/ftp/shared/last_response_code.rb25
-rw-r--r--spec/ruby/library/net/ftp/shared/list.rb104
-rw-r--r--spec/ruby/library/net/ftp/shared/putbinaryfile.rb167
-rw-r--r--spec/ruby/library/net/ftp/shared/puttextfile.rb120
-rw-r--r--spec/ruby/library/net/ftp/shared/pwd.rb3
-rw-r--r--spec/ruby/library/net/ftp/site_spec.rb53
-rw-r--r--spec/ruby/library/net/ftp/size_spec.rb48
-rw-r--r--spec/ruby/library/net/ftp/spec_helper.rb5
-rw-r--r--spec/ruby/library/net/ftp/status_spec.rb63
-rw-r--r--spec/ruby/library/net/ftp/storbinary_spec.rb48
-rw-r--r--spec/ruby/library/net/ftp/storlines_spec.rb43
-rw-r--r--spec/ruby/library/net/ftp/system_spec.rb48
-rw-r--r--spec/ruby/library/net/ftp/voidcmd_spec.rb54
-rw-r--r--spec/ruby/library/net/ftp/welcome_spec.rb25
64 files changed, 3050 insertions, 0 deletions
diff --git a/spec/ruby/library/net/ftp/abort_spec.rb b/spec/ruby/library/net/ftp/abort_spec.rb
new file mode 100644
index 0000000000..ea47eaf9bf
--- /dev/null
+++ b/spec/ruby/library/net/ftp/abort_spec.rb
@@ -0,0 +1,62 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#abort" do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ it "sends the ABOR command to the server" do
+ lambda { @ftp.abort }.should_not raise_error
+ end
+
+ it "ignores the response" do
+ @ftp.abort
+ @ftp.last_response.should == "220 Dummy FTP Server ready!\n"
+ end
+
+ it "returns the full response" do
+ @ftp.abort.should == "226 Closing data connection. (ABOR)\n"
+ end
+
+ it "does not raise any error when the response code is 225" do
+ @server.should_receive(:abor).and_respond("225 Data connection open; no transfer in progress.")
+ lambda { @ftp.abort }.should_not raise_error
+ end
+
+ it "does not raise any error when the response code is 226" do
+ @server.should_receive(:abor).and_respond("226 Closing data connection.")
+ lambda { @ftp.abort }.should_not raise_error
+ end
+
+ it "raises a Net::FTPProtoError when the response code is 500" do
+ @server.should_receive(:abor).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.abort }.should raise_error(Net::FTPProtoError)
+ end
+
+ it "raises a Net::FTPProtoError when the response code is 501" do
+ @server.should_receive(:abor).and_respond("501 Syntax error in parameters or arguments.")
+ lambda { @ftp.abort }.should raise_error(Net::FTPProtoError)
+ end
+
+ it "raises a Net::FTPProtoError when the response code is 502" do
+ @server.should_receive(:abor).and_respond("502 Command not implemented.")
+ lambda { @ftp.abort }.should raise_error(Net::FTPProtoError)
+ end
+
+ it "raises a Net::FTPProtoError when the response code is 421" do
+ @server.should_receive(:abor).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.abort }.should raise_error(Net::FTPProtoError)
+ end
+end
diff --git a/spec/ruby/library/net/ftp/acct_spec.rb b/spec/ruby/library/net/ftp/acct_spec.rb
new file mode 100644
index 0000000000..e60c6b3088
--- /dev/null
+++ b/spec/ruby/library/net/ftp/acct_spec.rb
@@ -0,0 +1,58 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#acct" do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ it "writes the ACCT command to the server" do
+ @ftp.acct("my_account")
+ @ftp.last_response.should == "230 User 'my_account' logged in, proceed. (ACCT)\n"
+ end
+
+ it "returns nil" do
+ @ftp.acct("my_account").should == nil
+ end
+
+ it "does not raise any error when the response code is 230" do
+ @server.should_receive(:acct).and_respond("230 User logged in, proceed.")
+ lambda { @ftp.acct("my_account") }.should_not raise_error
+ end
+
+ it "raises a Net::FTPPermError when the response code is 530" do
+ @server.should_receive(:acct).and_respond("530 Not logged in.")
+ lambda { @ftp.acct("my_account") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:acct).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.acct("my_account") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:acct).and_respond("501 Syntax error in parameters or arguments.")
+ lambda { @ftp.acct("my_account") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 503" do
+ @server.should_receive(:acct).and_respond("503 Bad sequence of commands.")
+ lambda { @ftp.acct("my_account") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:acct).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.acct("my_account") }.should raise_error(Net::FTPTempError)
+ end
+end
diff --git a/spec/ruby/library/net/ftp/binary_spec.rb b/spec/ruby/library/net/ftp/binary_spec.rb
new file mode 100644
index 0000000000..6f1a1ab8ba
--- /dev/null
+++ b/spec/ruby/library/net/ftp/binary_spec.rb
@@ -0,0 +1,24 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+
+describe "Net::FTP#binary" do
+ it "returns true when self is in binary mode" do
+ ftp = Net::FTP.new
+ ftp.binary.should be_true
+
+ ftp.binary = false
+ ftp.binary.should be_false
+ end
+end
+
+describe "Net::FTP#binary=" do
+ it "sets self to binary mode when passed true" do
+ ftp = Net::FTP.new
+
+ ftp.binary = true
+ ftp.binary.should be_true
+
+ ftp.binary = false
+ ftp.binary.should be_false
+ end
+end
diff --git a/spec/ruby/library/net/ftp/chdir_spec.rb b/spec/ruby/library/net/ftp/chdir_spec.rb
new file mode 100644
index 0000000000..f6cfac5b66
--- /dev/null
+++ b/spec/ruby/library/net/ftp/chdir_spec.rb
@@ -0,0 +1,99 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#chdir" do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ describe "when switching to the parent directory" do
+ it "sends the 'CDUP' command to the server" do
+ @ftp.chdir("..")
+ @ftp.last_response.should == "200 Command okay. (CDUP)\n"
+ end
+
+ it "returns nil" do
+ @ftp.chdir("..").should be_nil
+ end
+
+ it "does not raise a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:cdup).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.chdir("..") }.should_not raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:cdup).and_respond("501 Syntax error in parameters or arguments.")
+ lambda { @ftp.chdir("..") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 502" do
+ @server.should_receive(:cdup).and_respond("502 Command not implemented.")
+ lambda { @ftp.chdir("..") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:cdup).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.chdir("..") }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 530" do
+ @server.should_receive(:cdup).and_respond("530 Not logged in.")
+ lambda { @ftp.chdir("..") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 550" do
+ @server.should_receive(:cdup).and_respond("550 Requested action not taken.")
+ lambda { @ftp.chdir("..") }.should raise_error(Net::FTPPermError)
+ end
+ end
+
+ it "writes the 'CWD' command with the passed directory to the socket" do
+ @ftp.chdir("test")
+ @ftp.last_response.should == "200 Command okay. (CWD test)\n"
+ end
+
+ it "returns nil" do
+ @ftp.chdir("test").should be_nil
+ end
+
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:cwd).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.chdir("test") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:cwd).and_respond("501 Syntax error in parameters or arguments.")
+ lambda { @ftp.chdir("test") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 502" do
+ @server.should_receive(:cwd).and_respond("502 Command not implemented.")
+ lambda { @ftp.chdir("test") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:cwd).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.chdir("test") }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 530" do
+ @server.should_receive(:cwd).and_respond("530 Not logged in.")
+ lambda { @ftp.chdir("test") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 550" do
+ @server.should_receive(:cwd).and_respond("550 Requested action not taken.")
+ lambda { @ftp.chdir("test") }.should raise_error(Net::FTPPermError)
+ end
+end
diff --git a/spec/ruby/library/net/ftp/close_spec.rb b/spec/ruby/library/net/ftp/close_spec.rb
new file mode 100644
index 0000000000..0f6866221f
--- /dev/null
+++ b/spec/ruby/library/net/ftp/close_spec.rb
@@ -0,0 +1,30 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+
+describe "Net::FTP#close" do
+ before :each do
+ @socket = mock("Socket")
+ @socket.stub!(:closed?).and_return(false)
+ @socket.stub!(:read_timeout).and_return(60)
+ @socket.stub!(:read_timeout=).and_return(3)
+
+ @ftp = Net::FTP.new
+ @ftp.instance_variable_set(:@sock, @socket)
+ end
+
+ it "closes the socket" do
+ @socket.should_receive(:close)
+ @ftp.close.should be_nil
+ end
+
+ it "does not try to close the socket if it has already been closed" do
+ @socket.should_receive(:closed?).and_return(true)
+ @socket.should_not_receive(:close)
+ @ftp.close.should be_nil
+ end
+
+ it "does not try to close the socket if it is nil" do
+ @ftp.instance_variable_set(:@sock, nil)
+ @ftp.close.should be_nil
+ end
+end
diff --git a/spec/ruby/library/net/ftp/closed_spec.rb b/spec/ruby/library/net/ftp/closed_spec.rb
new file mode 100644
index 0000000000..7b31717c00
--- /dev/null
+++ b/spec/ruby/library/net/ftp/closed_spec.rb
@@ -0,0 +1,21 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+
+describe "Net::FTP#closed?" do
+ before :each do
+ @socket = mock("Socket")
+
+ @ftp = Net::FTP.new
+ @ftp.instance_variable_set(:@sock, @socket)
+ end
+
+ it "returns true when the socket is closed" do
+ @socket.should_receive(:closed?).and_return(true)
+ @ftp.closed?.should be_true
+ end
+
+ it "returns true when the socket is nil" do
+ @ftp.instance_variable_set(:@sock, nil)
+ @ftp.closed?.should be_true
+ end
+end
diff --git a/spec/ruby/library/net/ftp/connect_spec.rb b/spec/ruby/library/net/ftp/connect_spec.rb
new file mode 100644
index 0000000000..f3c1565fc2
--- /dev/null
+++ b/spec/ruby/library/net/ftp/connect_spec.rb
@@ -0,0 +1,49 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+# TODO: Add specs for using the SOCKSSocket
+describe "Net::FTP#connect" do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ end
+
+ after :each do
+ @server.connect_message = nil
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ it "tries to connect to the FTP Server on the given host and port" do
+ lambda { @ftp.connect(@server.hostname, @server.server_port) }.should_not raise_error
+ end
+
+ it "returns nil" do
+ @ftp.connect(@server.hostname, @server.server_port).should be_nil
+ end
+
+ it "prints a small debug line when in debug mode" do
+ @ftp.debug_mode = true
+ lambda { @ftp.connect(@server.hostname, @server.server_port) }.should output(/#{"connect: "}#{@server.hostname}#{", "}#{@server.server_port}#{"\\nget: 220 Dummy FTP Server ready!"}/)
+ @ftp.debug_mode = false
+ end
+
+ it "does not raise any error when the response code is 220" do
+ @server.connect_message = "220 Dummy FTP Server ready!"
+ lambda { @ftp.connect(@server.hostname, @server.server_port) }.should_not raise_error
+ end
+
+ it "raises a Net::FTPReplyError when the response code is 120" do
+ @server.connect_message = "120 Service ready in nnn minutes."
+ lambda { @ftp.connect(@server.hostname, @server.server_port) }.should raise_error(Net::FTPReplyError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.connect_message = "421 Service not available, closing control connection."
+ lambda { @ftp.connect(@server.hostname, @server.server_port) }.should raise_error(Net::FTPTempError)
+ end
+end
diff --git a/spec/ruby/library/net/ftp/debug_mode_spec.rb b/spec/ruby/library/net/ftp/debug_mode_spec.rb
new file mode 100644
index 0000000000..c4aa5eee3c
--- /dev/null
+++ b/spec/ruby/library/net/ftp/debug_mode_spec.rb
@@ -0,0 +1,23 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+
+describe "Net::FTP#debug_mode" do
+ it "returns true when self is in debug mode" do
+ ftp = Net::FTP.new
+ ftp.debug_mode.should be_false
+
+ ftp.debug_mode = true
+ ftp.debug_mode.should be_true
+ end
+end
+
+describe "Net::FTP#debug_mode=" do
+ it "sets self into debug mode when passed true" do
+ ftp = Net::FTP.new
+ ftp.debug_mode = true
+ ftp.debug_mode.should be_true
+
+ ftp.debug_mode = false
+ ftp.debug_mode.should be_false
+ end
+end
diff --git a/spec/ruby/library/net/ftp/default_passive_spec.rb b/spec/ruby/library/net/ftp/default_passive_spec.rb
new file mode 100644
index 0000000000..f526373b82
--- /dev/null
+++ b/spec/ruby/library/net/ftp/default_passive_spec.rb
@@ -0,0 +1,10 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+
+ruby_version_is "2.3" do
+ describe "Net::FTP#default_passive" do
+ it "is true by default" do
+ ruby_exe(fixture(__FILE__, "default_passive.rb")).should == "true\ntrue\n"
+ end
+ end
+end
diff --git a/spec/ruby/library/net/ftp/delete_spec.rb b/spec/ruby/library/net/ftp/delete_spec.rb
new file mode 100644
index 0000000000..b20ef32651
--- /dev/null
+++ b/spec/ruby/library/net/ftp/delete_spec.rb
@@ -0,0 +1,59 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#delete" do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ it "sends the DELE command with the passed filename to the server" do
+ @ftp.delete("test.file")
+ @ftp.last_response.should == "250 Requested file action okay, completed. (DELE test.file)\n"
+ end
+
+ it "raises a Net::FTPTempError when the response code is 450" do
+ @server.should_receive(:dele).and_respond("450 Requested file action not taken.")
+ lambda { @ftp.delete("test.file") }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 550" do
+ @server.should_receive(:dele).and_respond("550 Requested action not taken.")
+ lambda { @ftp.delete("test.file") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:dele).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.delete("test.file") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:dele).and_respond("501 Syntax error in parameters or arguments.")
+ lambda { @ftp.delete("test.file") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 502" do
+ @server.should_receive(:dele).and_respond("502 Command not implemented.")
+ lambda { @ftp.delete("test.file") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:dele).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.delete("test.file") }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 530" do
+ @server.should_receive(:dele).and_respond("530 Not logged in.")
+ lambda { @ftp.delete("test.file") }.should raise_error(Net::FTPPermError)
+ end
+end
diff --git a/spec/ruby/library/net/ftp/dir_spec.rb b/spec/ruby/library/net/ftp/dir_spec.rb
new file mode 100644
index 0000000000..6a2b766ca2
--- /dev/null
+++ b/spec/ruby/library/net/ftp/dir_spec.rb
@@ -0,0 +1,8 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+require File.expand_path('../shared/list', __FILE__)
+
+describe "Net::FTP#dir" do
+ it_behaves_like :net_ftp_list, :dir
+end
diff --git a/spec/ruby/library/net/ftp/fixtures/default_passive.rb b/spec/ruby/library/net/ftp/fixtures/default_passive.rb
new file mode 100644
index 0000000000..b6995d6f34
--- /dev/null
+++ b/spec/ruby/library/net/ftp/fixtures/default_passive.rb
@@ -0,0 +1,3 @@
+require "net/ftp"
+puts Net::FTP.default_passive
+puts Net::FTP.new.passive
diff --git a/spec/ruby/library/net/ftp/fixtures/passive.rb b/spec/ruby/library/net/ftp/fixtures/passive.rb
new file mode 100644
index 0000000000..6b5cde82df
--- /dev/null
+++ b/spec/ruby/library/net/ftp/fixtures/passive.rb
@@ -0,0 +1,2 @@
+require "net/ftp"
+print Net::FTP.new.passive
diff --git a/spec/ruby/library/net/ftp/fixtures/putbinaryfile b/spec/ruby/library/net/ftp/fixtures/putbinaryfile
new file mode 100644
index 0000000000..f3130c6e43
--- /dev/null
+++ b/spec/ruby/library/net/ftp/fixtures/putbinaryfile
@@ -0,0 +1,3 @@
+This is an example file
+which is going to be transmitted
+using #putbinaryfile.
diff --git a/spec/ruby/library/net/ftp/fixtures/puttextfile b/spec/ruby/library/net/ftp/fixtures/puttextfile
new file mode 100644
index 0000000000..b4f3b2b62d
--- /dev/null
+++ b/spec/ruby/library/net/ftp/fixtures/puttextfile
@@ -0,0 +1,3 @@
+This is an example file
+which is going to be transmitted
+using #puttextfile.
diff --git a/spec/ruby/library/net/ftp/fixtures/server.rb b/spec/ruby/library/net/ftp/fixtures/server.rb
new file mode 100644
index 0000000000..a6741820ff
--- /dev/null
+++ b/spec/ruby/library/net/ftp/fixtures/server.rb
@@ -0,0 +1,273 @@
+module NetFTPSpecs
+ class DummyFTP
+ attr_accessor :connect_message
+ attr_reader :login_user, :login_pass, :login_acct
+
+ # hostname or IP address
+ attr_reader :hostname
+ # port number
+ attr_reader :server_port
+
+ def initialize
+ @hostname = "localhost"
+ @server = TCPServer.new(@hostname, 0)
+ @server_port = @server.addr[1]
+
+ @handlers = {}
+ @commands = []
+ @connect_message = nil
+ end
+
+ def serve_once
+ @thread = Thread.new do
+ @socket = @server.accept
+ @socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, 1)
+ begin
+ handle_request
+ ensure
+ @socket.close
+ end
+ end
+ end
+
+ def handle_request
+ # Send out the welcome message.
+ response @connect_message || "220 Dummy FTP Server ready!"
+
+ begin
+ while command = @socket.recv(1024)
+ command, argument = command.chomp.split(" ", 2)
+
+ if command == "QUIT"
+ self.response("221 OK, bye")
+ break
+ elsif proc_handler = @handlers[command.downcase.to_sym]
+ if argument.nil?
+ proc_handler.call(self)
+ else
+ proc_handler.call(self, argument)
+ end
+ else
+ if argument.nil?
+ self.send(command.downcase.to_sym)
+ else
+ self.send(command.downcase.to_sym, argument)
+ end
+ end
+ end
+ rescue => e
+ self.error_response("Exception: #{e} #{e.backtrace.inspect}")
+ end
+ end
+
+ def error_response(text)
+ self.response("451 #{text}")
+ end
+
+ def response(text)
+ @socket.puts(text) unless @socket.closed?
+ end
+
+ def stop
+ @datasocket.close unless @datasocket.nil? || @datasocket.closed?
+ @server.close
+ @thread.join
+ end
+
+
+ ##
+ def handle(sym, &block)
+ @handlers[sym] = block
+ end
+
+ def should_receive(method)
+ @handler_for = method
+ self
+ end
+
+ def and_respond(text)
+ @handlers[@handler_for] = lambda { |s, *args| s.response(text) }
+ end
+
+ ##
+ # FTP methods
+ ##
+
+ def abor
+ self.response("226 Closing data connection. (ABOR)")
+ end
+
+ def acct(account)
+ @login_acct = account
+ self.response("230 User '#{account}' logged in, proceed. (ACCT)")
+ end
+
+ def cdup
+ self.response("200 Command okay. (CDUP)")
+ end
+
+ def cwd(dir)
+ self.response("200 Command okay. (CWD #{dir})")
+ end
+
+ def dele(file)
+ self.response("250 Requested file action okay, completed. (DELE #{file})")
+ end
+
+ def eprt(arg)
+ _, _, host, port = arg.split("|")
+
+ @datasocket = TCPSocket.new(host, port)
+ self.response("200 port opened")
+ end
+
+ def help(param = :default)
+ if param == :default
+ self.response("211 System status, or system help reply. (HELP)")
+ else
+ self.response("211 System status, or system help reply. (HELP #{param})")
+ end
+ end
+
+ def list(folder)
+ self.response("150 opening ASCII connection for file list")
+ @datasocket.puts("-rw-r--r-- 1 spec staff 507 17 Jul 18:41 last_response_code.rb")
+ @datasocket.puts("-rw-r--r-- 1 spec staff 50 17 Jul 18:41 list.rb")
+ @datasocket.puts("-rw-r--r-- 1 spec staff 48 17 Jul 18:41 pwd.rb")
+ @datasocket.close()
+ self.response("226 transfer complete (LIST #{folder})")
+ end
+
+ def mdtm(filename)
+ self.response("213 19980705132316")
+ end
+
+ def mkd(foldername)
+ self.response(%Q{257 "#{foldername.gsub('"', '""')}" created.})
+ end
+
+ def nlst(folder = nil)
+ self.response("150 opening ASCII connection for file list")
+ @datasocket.puts("last_response_code.rb")
+ @datasocket.puts("list.rb")
+ @datasocket.puts("pwd.rb")
+ @datasocket.close()
+ self.response("226 transfer complete (NLST#{folder ? " #{folder}" : ""})")
+ end
+
+ def noop
+ self.response("200 Command okay. (NOOP)")
+ end
+
+ def pass(password)
+ @login_pass = password
+ self.response("230 User logged in, proceed. (PASS #{password})")
+ end
+
+ def port(arg)
+ nums = arg.split(",")
+
+ if nums[0] == "::1"
+ # IPv6
+ port = nums[1].to_i * 256 + nums[2].to_i
+ host = nums[0]
+ else
+ # IPv4
+ port = nums[4].to_i * 256 + nums[5].to_i
+ host = nums[0..3].join(".")
+ end
+
+ @datasocket = TCPSocket.new(host, port)
+ self.response("200 port opened")
+ end
+
+ def pwd
+ self.response('257 "/some/dir/" - current directory')
+ end
+
+ def retr(file)
+ self.response("125 Data transfer starting")
+ if @restart_at && @restart_at == 20
+ @datasocket.puts("of the file named '#{file}'.")
+ @restart_at = nil
+ else
+ @datasocket.puts("This is the content")
+ @datasocket.puts("of the file named '#{file}'.")
+ end
+ @datasocket.close()
+ self.response("226 Closing data connection. (RETR #{file})")
+ end
+
+ def rest(at_bytes)
+ @restart_at = at_bytes.to_i
+ self.response("350 Requested file action pending further information. (REST)")
+ end
+
+ def rmd(folder)
+ self.response("250 Requested file action okay, completed. (RMD #{folder})")
+ end
+
+ def rnfr(from)
+ @rename_from = from
+ self.response("350 Requested file action pending further information.")
+ end
+
+ def rnto(to)
+ self.response("250 Requested file action okay, completed. (Renamed #{@rename_from} to #{to})")
+ @rename_from = nil
+ end
+
+ def site(param)
+ self.response("200 Command okay. (SITE #{param})")
+ end
+
+ def size(filename)
+ if filename == "binary"
+ self.response("213 24")
+ else
+ self.response("213 1024")
+ end
+ end
+
+ def stat
+ self.response("211 System status, or system help reply. (STAT)")
+ end
+
+ def stor(file)
+ tmp_file = tmp("#{file}file", false)
+
+ self.response("125 Data transfer starting.")
+
+ mode = @restart_at ? "a" : "w"
+
+ File.open(tmp_file, mode + "b") do |f|
+ loop do
+ data = @datasocket.recv(1024)
+ break if !data || data.empty?
+ f << data
+ end
+ end
+
+ #@datasocket.close()
+ self.response("200 OK, Data received. (STOR #{file})")
+ end
+
+ def appe(file)
+ @restart_at = true
+ stor(file)
+ end
+
+ def syst
+ self.response("215 FTP Dummy Server (SYST)")
+ end
+
+ def type(type)
+ self.response("200 TYPE switched to #{type}")
+ end
+
+ def user(name)
+ @login_user = name
+ self.response("230 User logged in, proceed. (USER #{name})")
+ end
+ end
+end
diff --git a/spec/ruby/library/net/ftp/get_spec.rb b/spec/ruby/library/net/ftp/get_spec.rb
new file mode 100644
index 0000000000..59fc45d010
--- /dev/null
+++ b/spec/ruby/library/net/ftp/get_spec.rb
@@ -0,0 +1,21 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+require File.expand_path('../shared/gettextfile', __FILE__)
+require File.expand_path('../shared/getbinaryfile', __FILE__)
+
+describe "Net::FTP#get (binary mode)" do
+ before :each do
+ @binary_mode = true
+ end
+
+ it_behaves_like :net_ftp_getbinaryfile, :get
+end
+
+describe "Net::FTP#get (text mode)" do
+ before :each do
+ @binary_mode = false
+ end
+
+ it_behaves_like :net_ftp_gettextfile, :get
+end
diff --git a/spec/ruby/library/net/ftp/getbinaryfile_spec.rb b/spec/ruby/library/net/ftp/getbinaryfile_spec.rb
new file mode 100644
index 0000000000..0f921c8b1d
--- /dev/null
+++ b/spec/ruby/library/net/ftp/getbinaryfile_spec.rb
@@ -0,0 +1,8 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+require File.expand_path('../shared/getbinaryfile', __FILE__)
+
+describe "Net::FTP#getbinaryfile" do
+ it_behaves_like :net_ftp_getbinaryfile, :getbinaryfile
+end
diff --git a/spec/ruby/library/net/ftp/getdir_spec.rb b/spec/ruby/library/net/ftp/getdir_spec.rb
new file mode 100644
index 0000000000..19ace4dff9
--- /dev/null
+++ b/spec/ruby/library/net/ftp/getdir_spec.rb
@@ -0,0 +1,7 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../shared/pwd', __FILE__)
+
+describe "Net::FTP#getdir" do
+ it_behaves_like :net_ftp_pwd, :getdir
+end
diff --git a/spec/ruby/library/net/ftp/gettextfile_spec.rb b/spec/ruby/library/net/ftp/gettextfile_spec.rb
new file mode 100644
index 0000000000..29077df253
--- /dev/null
+++ b/spec/ruby/library/net/ftp/gettextfile_spec.rb
@@ -0,0 +1,8 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+require File.expand_path('../shared/gettextfile', __FILE__)
+
+describe "Net::FTP#gettextfile" do
+ it_behaves_like :net_ftp_gettextfile, :gettextfile
+end
diff --git a/spec/ruby/library/net/ftp/help_spec.rb b/spec/ruby/library/net/ftp/help_spec.rb
new file mode 100644
index 0000000000..6f5f901024
--- /dev/null
+++ b/spec/ruby/library/net/ftp/help_spec.rb
@@ -0,0 +1,66 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#help" do
+ def with_connection
+ yield
+ end
+
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ it "writes the HELP command to the server" do
+ @ftp.help
+ @ftp.last_response.should == "211 System status, or system help reply. (HELP)\n"
+ end
+
+ it "returns the server's response" do
+ @ftp.help.should == "211 System status, or system help reply. (HELP)\n"
+ end
+
+ it "writes the HELP command with an optional parameter to the socket" do
+ @ftp.help("some parameter").should == "211 System status, or system help reply. (HELP some parameter)\n"
+ end
+
+ it "does not raise any error when the response code is 211" do
+ @server.should_receive(:help).and_respond("211 System status, or system help reply.")
+ lambda { @ftp.help }.should_not raise_error
+ end
+
+ it "does not raise any error when the response code is 214" do
+ @server.should_receive(:help).and_respond("214 Help message.")
+ lambda { @ftp.help }.should_not raise_error
+ end
+
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:help).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.help }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:help).and_respond("501 Syntax error in parameters or arguments.")
+ lambda { @ftp.help }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 502" do
+ @server.should_receive(:help).and_respond("502 Command not implemented.")
+ lambda { @ftp.help }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:help).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.help }.should raise_error(Net::FTPTempError)
+ end
+end
diff --git a/spec/ruby/library/net/ftp/initialize_spec.rb b/spec/ruby/library/net/ftp/initialize_spec.rb
new file mode 100644
index 0000000000..767bbecedb
--- /dev/null
+++ b/spec/ruby/library/net/ftp/initialize_spec.rb
@@ -0,0 +1,87 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+
+describe "Net::FTP#initialize" do
+ before :each do
+ @ftp = Net::FTP.allocate
+ @ftp.stub!(:connect)
+ end
+
+ it "is private" do
+ Net::FTP.should have_private_instance_method(:initialize)
+ end
+
+ it "sets self into binary mode" do
+ @ftp.binary.should be_nil
+ @ftp.send(:initialize)
+ @ftp.binary.should be_true
+ end
+
+ it "sets self into active mode" do
+ @ftp.passive.should be_nil
+ @ftp.send(:initialize)
+ @ftp.passive.should be_false
+ end
+
+ it "sets self into non-debug mode" do
+ @ftp.debug_mode.should be_nil
+ @ftp.send(:initialize)
+ @ftp.debug_mode.should be_false
+ end
+
+ it "sets self to not resume file uploads/downloads" do
+ @ftp.resume.should be_nil
+ @ftp.send(:initialize)
+ @ftp.resume.should be_false
+ end
+
+ describe "when passed no arguments" do
+ it "does not try to connect" do
+ @ftp.should_not_receive(:connect)
+ @ftp.send(:initialize)
+ end
+ end
+
+ describe "when passed host" do
+ it "tries to connect to the passed host" do
+ @ftp.should_receive(:connect).with("localhost")
+ @ftp.send(:initialize, "localhost")
+ end
+ end
+
+ describe "when passed host, user" do
+ it "tries to connect to the passed host" do
+ @ftp.should_receive(:connect).with("localhost")
+ @ftp.send(:initialize, "localhost")
+ end
+
+ it "tries to login with the passed username" do
+ @ftp.should_receive(:login).with("rubyspec", nil, nil)
+ @ftp.send(:initialize, "localhost", "rubyspec")
+ end
+ end
+
+ describe "when passed host, user, password" do
+ it "tries to connect to the passed host" do
+ @ftp.should_receive(:connect).with("localhost")
+ @ftp.send(:initialize, "localhost")
+ end
+
+ it "tries to login with the passed username and password" do
+ @ftp.should_receive(:login).with("rubyspec", "rocks", nil)
+ @ftp.send(:initialize, "localhost", "rubyspec", "rocks")
+ end
+ end
+
+ describe "when passed host, user" do
+ it "tries to connect to the passed host" do
+ @ftp.should_receive(:connect).with("localhost")
+ @ftp.send(:initialize, "localhost")
+ end
+
+ it "tries to login with the passed username, password and account" do
+ @ftp.should_receive(:login).with("rubyspec", "rocks", "account")
+ @ftp.send(:initialize, "localhost", "rubyspec", "rocks", "account")
+ end
+ end
+end
diff --git a/spec/ruby/library/net/ftp/last_response_code_spec.rb b/spec/ruby/library/net/ftp/last_response_code_spec.rb
new file mode 100644
index 0000000000..77651a9be4
--- /dev/null
+++ b/spec/ruby/library/net/ftp/last_response_code_spec.rb
@@ -0,0 +1,8 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../shared/last_response_code', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#last_response_code" do
+ it_behaves_like :net_ftp_last_response_code, :last_response_code
+end
diff --git a/spec/ruby/library/net/ftp/last_response_spec.rb b/spec/ruby/library/net/ftp/last_response_spec.rb
new file mode 100644
index 0000000000..eb53f92774
--- /dev/null
+++ b/spec/ruby/library/net/ftp/last_response_spec.rb
@@ -0,0 +1,25 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#last_response" do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ it "returns the last response" do
+ @ftp.last_response.should == "220 Dummy FTP Server ready!\n"
+ @ftp.help
+ @ftp.last_response.should == "211 System status, or system help reply. (HELP)\n"
+ end
+end
diff --git a/spec/ruby/library/net/ftp/lastresp_spec.rb b/spec/ruby/library/net/ftp/lastresp_spec.rb
new file mode 100644
index 0000000000..d2c6f44e48
--- /dev/null
+++ b/spec/ruby/library/net/ftp/lastresp_spec.rb
@@ -0,0 +1,8 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../shared/last_response_code', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#lastresp" do
+ it_behaves_like :net_ftp_last_response_code, :lastresp
+end
diff --git a/spec/ruby/library/net/ftp/list_spec.rb b/spec/ruby/library/net/ftp/list_spec.rb
new file mode 100644
index 0000000000..41c55c42ac
--- /dev/null
+++ b/spec/ruby/library/net/ftp/list_spec.rb
@@ -0,0 +1,8 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+require File.expand_path('../shared/list', __FILE__)
+
+describe "Net::FTP#list" do
+ it_behaves_like :net_ftp_list, :list
+end
diff --git a/spec/ruby/library/net/ftp/login_spec.rb b/spec/ruby/library/net/ftp/login_spec.rb
new file mode 100644
index 0000000000..9768d9cf33
--- /dev/null
+++ b/spec/ruby/library/net/ftp/login_spec.rb
@@ -0,0 +1,195 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#login" do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ describe "when passed no arguments" do
+ it "sends the USER command with 'anonymous' as name to the server" do
+ @ftp.login
+ @server.login_user.should == "anonymous"
+ end
+
+ it "sends 'anonymous@' as a password when required" do
+ @server.should_receive(:user).and_respond("331 User name okay, need password.")
+ @ftp.login
+ @server.login_pass.should == "anonymous@"
+ end
+
+ it "raises a Net::FTPReplyError when the server requests an account" do
+ @server.should_receive(:user).and_respond("331 User name okay, need password.")
+ @server.should_receive(:pass).and_respond("332 Need account for login.")
+ lambda { @ftp.login }.should raise_error(Net::FTPReplyError)
+ end
+ end
+
+ describe "when passed name" do
+ it "sends the USER command with the passed name to the server" do
+ @ftp.login("rubyspec")
+ @server.login_user.should == "rubyspec"
+ end
+
+ it "raises a Net::FTPReplyError when the server requests a password, but none was given" do
+ @server.should_receive(:user).and_respond("331 User name okay, need password.")
+ lambda { @ftp.login("rubyspec") }.should raise_error(Net::FTPReplyError)
+ end
+
+ it "raises a Net::FTPReplyError when the server requests an account, but none was given" do
+ @server.should_receive(:user).and_respond("331 User name okay, need password.")
+ @server.should_receive(:pass).and_respond("332 Need account for login.")
+ lambda { @ftp.login("rubyspec") }.should raise_error(Net::FTPReplyError)
+ end
+ end
+
+ describe "when passed name, password" do
+ it "sends the USER command with the passed name to the server" do
+ @ftp.login("rubyspec", "rocks")
+ @server.login_user.should == "rubyspec"
+ end
+
+ it "sends the passed password when required" do
+ @server.should_receive(:user).and_respond("331 User name okay, need password.")
+ @ftp.login("rubyspec", "rocks")
+ @server.login_pass.should == "rocks"
+ end
+
+ it "raises a Net::FTPReplyError when the server requests an account" do
+ @server.should_receive(:user).and_respond("331 User name okay, need password.")
+ @server.should_receive(:pass).and_respond("332 Need account for login.")
+ lambda { @ftp.login("rubyspec", "rocks") }.should raise_error(Net::FTPReplyError)
+ end
+ end
+
+ describe "when passed name, password, account" do
+ it "sends the USER command with the passed name to the server" do
+ @ftp.login("rubyspec", "rocks", "account")
+ @server.login_user.should == "rubyspec"
+ end
+
+ it "sends the passed password when required" do
+ @server.should_receive(:user).and_respond("331 User name okay, need password.")
+ @ftp.login("rubyspec", "rocks", "account")
+ @server.login_pass.should == "rocks"
+ end
+
+ it "sends the passed account when required" do
+ @server.should_receive(:user).and_respond("331 User name okay, need password.")
+ @server.should_receive(:pass).and_respond("332 Need account for login.")
+ @ftp.login("rubyspec", "rocks", "account")
+ @server.login_acct.should == "account"
+ end
+ end
+
+ describe "when the USER command fails" do
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:user).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.login("rubyspec", "rocks", "account") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:user).and_respond("501 Syntax error in parameters or arguments.")
+ lambda { @ftp.login("rubyspec", "rocks", "account") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 502" do
+ @server.should_receive(:user).and_respond("502 Command not implemented.")
+ lambda { @ftp.login("rubyspec", "rocks", "account") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:user).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.login("rubyspec", "rocks", "account") }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 530" do
+ @server.should_receive(:user).and_respond("530 Not logged in.")
+ lambda { @ftp.login("rubyspec", "rocks", "account") }.should raise_error(Net::FTPPermError)
+ end
+ end
+
+ describe "when the PASS command fails" do
+ before :each do
+ @server.should_receive(:user).and_respond("331 User name okay, need password.")
+ end
+
+ it "does not raise an Error when the response code is 202" do
+ @server.should_receive(:pass).and_respond("202 Command not implemented, superfluous at this site.")
+ lambda { @ftp.login("rubyspec", "rocks", "account") }.should_not raise_error
+ end
+
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:pass).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.login("rubyspec", "rocks", "account") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:pass).and_respond("501 Syntax error in parameters or arguments.")
+ lambda { @ftp.login("rubyspec", "rocks", "account") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 502" do
+ @server.should_receive(:pass).and_respond("502 Command not implemented.")
+ lambda { @ftp.login("rubyspec", "rocks", "account") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:pass).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.login("rubyspec", "rocks", "account") }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 530" do
+ @server.should_receive(:pass).and_respond("530 Not logged in.")
+ lambda { @ftp.login("rubyspec", "rocks", "account") }.should raise_error(Net::FTPPermError)
+ end
+ end
+
+ describe "when the ACCT command fails" do
+ before :each do
+ @server.should_receive(:user).and_respond("331 User name okay, need password.")
+ @server.should_receive(:pass).and_respond("332 Need account for login.")
+ end
+
+ it "does not raise an Error when the response code is 202" do
+ @server.should_receive(:acct).and_respond("202 Command not implemented, superfluous at this site.")
+ lambda { @ftp.login("rubyspec", "rocks", "account") }.should_not raise_error
+ end
+
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:acct).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.login("rubyspec", "rocks", "account") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:acct).and_respond("501 Syntax error in parameters or arguments.")
+ lambda { @ftp.login("rubyspec", "rocks", "account") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 502" do
+ @server.should_receive(:acct).and_respond("502 Command not implemented.")
+ lambda { @ftp.login("rubyspec", "rocks", "account") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:acct).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.login("rubyspec", "rocks", "account") }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 530" do
+ @server.should_receive(:acct).and_respond("530 Not logged in.")
+ lambda { @ftp.login("rubyspec", "rocks", "account") }.should raise_error(Net::FTPPermError)
+ end
+ end
+end
diff --git a/spec/ruby/library/net/ftp/ls_spec.rb b/spec/ruby/library/net/ftp/ls_spec.rb
new file mode 100644
index 0000000000..f713fb46aa
--- /dev/null
+++ b/spec/ruby/library/net/ftp/ls_spec.rb
@@ -0,0 +1,8 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+require File.expand_path('../shared/list', __FILE__)
+
+describe "Net::FTP#ls" do
+ it_behaves_like :net_ftp_list, :ls
+end
diff --git a/spec/ruby/library/net/ftp/mdtm_spec.rb b/spec/ruby/library/net/ftp/mdtm_spec.rb
new file mode 100644
index 0000000000..bbd28d10b1
--- /dev/null
+++ b/spec/ruby/library/net/ftp/mdtm_spec.rb
@@ -0,0 +1,38 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#mdtm" do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ it "sends the MDTM with the passed filename command to the server" do
+ @ftp.mdtm("test.file")
+ @ftp.last_response.should == "213 19980705132316\n"
+ end
+
+ it "returns the last modification time of the passed file" do
+ @ftp.mdtm("test.file").should == "19980705132316"
+ end
+
+ it "raises a Net::FTPPermError when the response code is 550" do
+ @server.should_receive(:mdtm).and_respond("550 Requested action not taken.")
+ lambda { @ftp.mdtm("test.file") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:mdtm).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.mdtm("test.file") }.should raise_error(Net::FTPTempError)
+ end
+end
diff --git a/spec/ruby/library/net/ftp/mkdir_spec.rb b/spec/ruby/library/net/ftp/mkdir_spec.rb
new file mode 100644
index 0000000000..2a7088e5d9
--- /dev/null
+++ b/spec/ruby/library/net/ftp/mkdir_spec.rb
@@ -0,0 +1,61 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#mkdir" do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ it "sends the MKD command with the passed pathname to the server" do
+ @ftp.mkdir("test.folder")
+ @ftp.last_response.should == %{257 "test.folder" created.\n}
+ end
+
+ it "returns the path to the newly created directory" do
+ @ftp.mkdir("test.folder").should == "test.folder"
+ @ftp.mkdir("/absolute/path/to/test.folder").should == "/absolute/path/to/test.folder"
+ @ftp.mkdir("relative/path/to/test.folder").should == "relative/path/to/test.folder"
+ @ftp.mkdir('/usr/dm/foo"bar').should == '/usr/dm/foo"bar'
+ end
+
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:mkd).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.mkdir("test.folder") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:mkd).and_respond("501 Syntax error in parameters or arguments.")
+ lambda { @ftp.mkdir("test.folder") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 502" do
+ @server.should_receive(:mkd).and_respond("502 Command not implemented.")
+ lambda { @ftp.mkdir("test.folder") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:mkd).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.mkdir("test.folder") }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 530" do
+ @server.should_receive(:mkd).and_respond("530 Not logged in.")
+ lambda { @ftp.mkdir("test.folder") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 550" do
+ @server.should_receive(:mkd).and_respond("550 Requested action not taken.")
+ lambda { @ftp.mkdir("test.folder") }.should raise_error(Net::FTPPermError)
+ end
+end
diff --git a/spec/ruby/library/net/ftp/mtime_spec.rb b/spec/ruby/library/net/ftp/mtime_spec.rb
new file mode 100644
index 0000000000..0e76aa079b
--- /dev/null
+++ b/spec/ruby/library/net/ftp/mtime_spec.rb
@@ -0,0 +1,50 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#mtime" do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ it "sends the MDTM with the passed filename command to the server" do
+ @ftp.mtime("test.file")
+ @ftp.last_response.should == "213 19980705132316\n"
+ end
+
+ describe "when passed filename" do
+ it "returns the last modification time of the passed file as a Time object in the local time" do
+ @ftp.mtime("test.file").should == Time.gm("1998", "07", "05", "13", "23", "16")
+ end
+ end
+
+ describe "when passed filename, local_time" do
+ it "returns the last modification time as a Time object in UTC when local_time is true" do
+ @ftp.mtime("test.file", true).should == Time.local("1998", "07", "05", "13", "23", "16")
+ end
+
+ it "returns the last modification time as a Time object in the local time when local_time is false" do
+ @ftp.mtime("test.file", false).should == Time.gm("1998", "07", "05", "13", "23", "16")
+ end
+ end
+
+ it "raises a Net::FTPPermError when the response code is 550" do
+ @server.should_receive(:mdtm).and_respond("550 Requested action not taken.")
+ lambda { @ftp.mtime("test.file") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:mdtm).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.mtime("test.file") }.should raise_error(Net::FTPTempError)
+ end
+end
diff --git a/spec/ruby/library/net/ftp/nlst_spec.rb b/spec/ruby/library/net/ftp/nlst_spec.rb
new file mode 100644
index 0000000000..4723e9f6c6
--- /dev/null
+++ b/spec/ruby/library/net/ftp/nlst_spec.rb
@@ -0,0 +1,92 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#nlst" do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.passive = false
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ describe "when passed no arguments" do
+ it "returns an Array containing a list of files in the current dir" do
+ @ftp.nlst.should == ["last_response_code.rb", "list.rb", "pwd.rb"]
+ @ftp.last_response.should == "226 transfer complete (NLST)\n"
+ end
+ end
+
+ describe "when passed dir" do
+ it "returns an Array containing a list of files in the passed dir" do
+ @ftp.nlst("test.folder").should == ["last_response_code.rb", "list.rb", "pwd.rb"]
+ @ftp.last_response.should == "226 transfer complete (NLST test.folder)\n"
+ end
+ end
+
+ describe "when the NLST command fails" do
+ it "raises a Net::FTPTempError when the response code is 450" do
+ @server.should_receive(:nlst).and_respond("450 Requested file action not taken..")
+ lambda { @ftp.nlst }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:nlst).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.nlst }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:nlst).and_respond("501 Syntax error, command unrecognized.")
+ lambda { @ftp.nlst }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 502" do
+ @server.should_receive(:nlst).and_respond("502 Command not implemented.")
+ lambda { @ftp.nlst }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:nlst).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.nlst }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 530" do
+ @server.should_receive(:nlst).and_respond("530 Not logged in.")
+ lambda { @ftp.nlst }.should raise_error(Net::FTPPermError)
+ end
+ end
+
+ describe "when opening the data port fails" do
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:eprt).and_respond("500 Syntax error, command unrecognized.")
+ @server.should_receive(:port).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.nlst }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:eprt).and_respond("501 Syntax error in parameters or arguments.")
+ @server.should_receive(:port).and_respond("501 Syntax error in parameters or arguments.")
+ lambda { @ftp.nlst }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:eprt).and_respond("421 Service not available, closing control connection.")
+ @server.should_receive(:port).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.nlst }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 530" do
+ @server.should_receive(:eprt).and_respond("530 Not logged in.")
+ @server.should_receive(:port).and_respond("530 Not logged in.")
+ lambda { @ftp.nlst }.should raise_error(Net::FTPPermError)
+ end
+ end
+end
diff --git a/spec/ruby/library/net/ftp/noop_spec.rb b/spec/ruby/library/net/ftp/noop_spec.rb
new file mode 100644
index 0000000000..1bc6ccd913
--- /dev/null
+++ b/spec/ruby/library/net/ftp/noop_spec.rb
@@ -0,0 +1,38 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#noop" do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ it "sends the NOOP command to the server" do
+ @ftp.noop
+ @ftp.last_response.should == "200 Command okay. (NOOP)\n"
+ end
+
+ it "returns nil" do
+ @ftp.noop.should be_nil
+ end
+
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:noop).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.noop }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:noop).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.noop }.should raise_error(Net::FTPTempError)
+ end
+end
diff --git a/spec/ruby/library/net/ftp/open_spec.rb b/spec/ruby/library/net/ftp/open_spec.rb
new file mode 100644
index 0000000000..b422e64c87
--- /dev/null
+++ b/spec/ruby/library/net/ftp/open_spec.rb
@@ -0,0 +1,55 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+
+describe "Net::FTP.open" do
+ before :each do
+ @ftp = mock("Net::FTP instance")
+ Net::FTP.stub!(:new).and_return(@ftp)
+ end
+
+ describe "when passed no block" do
+ it "returns a new Net::FTP instance" do
+ Net::FTP.open("localhost").should equal(@ftp)
+ end
+
+ it "passes the passed arguments down to Net::FTP.new" do
+ Net::FTP.should_receive(:new).with("localhost", "user", "password", "account")
+ Net::FTP.open("localhost", "user", "password", "account")
+ end
+ end
+
+ describe "when passed a block" do
+ before :each do
+ @ftp.stub!(:close)
+ end
+
+ it "yields a new Net::FTP instance to the passed block" do
+ yielded = false
+ Net::FTP.open("localhost") do |ftp|
+ yielded = true
+ ftp.should equal(@ftp)
+ end
+ yielded.should be_true
+ end
+
+ it "closes the Net::FTP instance after yielding" do
+ Net::FTP.open("localhost") do |ftp|
+ ftp.should_receive(:close)
+ end
+ end
+
+ it "closes the Net::FTP instance even if an exception is raised while yielding" do
+ begin
+ Net::FTP.open("localhost") do |ftp|
+ ftp.should_receive(:close)
+ raise ArgumentError, "some exception"
+ end
+ rescue ArgumentError
+ end
+ end
+
+ it "returns the block's return value" do
+ Net::FTP.open("localhost") { :test }.should == :test
+ end
+ end
+end
diff --git a/spec/ruby/library/net/ftp/passive_spec.rb b/spec/ruby/library/net/ftp/passive_spec.rb
new file mode 100644
index 0000000000..fd9a0dffe3
--- /dev/null
+++ b/spec/ruby/library/net/ftp/passive_spec.rb
@@ -0,0 +1,36 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+
+describe "Net::FTP#passive" do
+ it "returns true when self is in passive mode" do
+ ftp = Net::FTP.new
+ ftp.passive.should be_false
+
+ ftp.passive = true
+ ftp.passive.should be_true
+ end
+
+ ruby_version_is ""..."2.3" do
+ it "is false by default" do
+ ruby_exe(fixture(__FILE__, "passive.rb")).should == "false"
+ end
+ end
+
+ ruby_version_is "2.3" do
+ it "is the value of Net::FTP.default_value by default" do
+ ruby_exe(fixture(__FILE__, "passive.rb")).should == "true"
+ end
+ end
+end
+
+describe "Net::FTP#passive=" do
+ it "sets self to passive mode when passed true" do
+ ftp = Net::FTP.new
+
+ ftp.passive = true
+ ftp.passive.should be_true
+
+ ftp.passive = false
+ ftp.passive.should be_false
+ end
+end
diff --git a/spec/ruby/library/net/ftp/put_spec.rb b/spec/ruby/library/net/ftp/put_spec.rb
new file mode 100644
index 0000000000..61a8d00543
--- /dev/null
+++ b/spec/ruby/library/net/ftp/put_spec.rb
@@ -0,0 +1,21 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+require File.expand_path('../shared/puttextfile', __FILE__)
+require File.expand_path('../shared/putbinaryfile', __FILE__)
+
+describe "Net::FTP#put (binary mode)" do
+ before :each do
+ @binary_mode = true
+ end
+
+ it_behaves_like :net_ftp_putbinaryfile, :put
+end
+
+describe "Net::FTP#put (text mode)" do
+ before :each do
+ @binary_mode = false
+ end
+
+ it_behaves_like :net_ftp_puttextfile, :put
+end
diff --git a/spec/ruby/library/net/ftp/putbinaryfile_spec.rb b/spec/ruby/library/net/ftp/putbinaryfile_spec.rb
new file mode 100644
index 0000000000..18955409b6
--- /dev/null
+++ b/spec/ruby/library/net/ftp/putbinaryfile_spec.rb
@@ -0,0 +1,8 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+require File.expand_path('../shared/putbinaryfile', __FILE__)
+
+describe "Net::FTP#putbinaryfile" do
+ it_behaves_like :net_ftp_putbinaryfile, :putbinaryfile
+end
diff --git a/spec/ruby/library/net/ftp/puttextfile_spec.rb b/spec/ruby/library/net/ftp/puttextfile_spec.rb
new file mode 100644
index 0000000000..2ca6e98c92
--- /dev/null
+++ b/spec/ruby/library/net/ftp/puttextfile_spec.rb
@@ -0,0 +1,8 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+require File.expand_path('../shared/puttextfile', __FILE__)
+
+describe "Net::FTP#puttextfile" do
+ it_behaves_like :net_ftp_puttextfile, :puttextfile
+end
diff --git a/spec/ruby/library/net/ftp/pwd_spec.rb b/spec/ruby/library/net/ftp/pwd_spec.rb
new file mode 100644
index 0000000000..d5438d8e56
--- /dev/null
+++ b/spec/ruby/library/net/ftp/pwd_spec.rb
@@ -0,0 +1,53 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#pwd" do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ it "sends the PWD command to the server" do
+ @ftp.pwd
+ @ftp.last_response.should == "257 \"/some/dir/\" - current directory\n"
+ end
+
+ it "returns the current directory" do
+ @ftp.pwd.should == "/some/dir/"
+ end
+
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:pwd).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.pwd }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:pwd).and_respond("501 Syntax error in parameters or arguments.")
+ lambda { @ftp.pwd }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 502" do
+ @server.should_receive(:pwd).and_respond("502 Command not implemented.")
+ lambda { @ftp.pwd }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:pwd).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.pwd }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 550" do
+ @server.should_receive(:pwd).and_respond("550 Requested action not taken.")
+ lambda { @ftp.pwd }.should raise_error(Net::FTPPermError)
+ end
+end
diff --git a/spec/ruby/library/net/ftp/quit_spec.rb b/spec/ruby/library/net/ftp/quit_spec.rb
new file mode 100644
index 0000000000..c053641939
--- /dev/null
+++ b/spec/ruby/library/net/ftp/quit_spec.rb
@@ -0,0 +1,33 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#quit" do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ it "sends the QUIT command to the server" do
+ @ftp.quit
+ @ftp.last_response.should == "221 OK, bye\n"
+ end
+
+ it "does not close the socket automagically" do
+ @ftp.quit
+ @ftp.closed?.should be_false
+ end
+
+ it "returns nil" do
+ @ftp.quit.should be_nil
+ end
+end
diff --git a/spec/ruby/library/net/ftp/rename_spec.rb b/spec/ruby/library/net/ftp/rename_spec.rb
new file mode 100644
index 0000000000..0216d2059a
--- /dev/null
+++ b/spec/ruby/library/net/ftp/rename_spec.rb
@@ -0,0 +1,94 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#rename" do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ describe "when passed from_name, to_name" do
+ it "sends the RNFR command with the passed from_name and the RNTO command with the passed to_name to the server" do
+ @ftp.rename("from.file", "to.file")
+ @ftp.last_response.should == "250 Requested file action okay, completed. (Renamed from.file to to.file)\n"
+ end
+
+ it "returns something" do
+ @ftp.rename("from.file", "to.file").should be_nil
+ end
+ end
+
+ describe "when the RNFR command fails" do
+ it "raises a Net::FTPTempError when the response code is 450" do
+ @server.should_receive(:rnfr).and_respond("450 Requested file action not taken.")
+ lambda { @ftp.rename("from.file", "to.file") }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 550" do
+ @server.should_receive(:rnfr).and_respond("550 Requested action not taken.")
+ lambda { @ftp.rename("from.file", "to.file") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:rnfr).and_respond("501 Syntax error in parameters or arguments.")
+ lambda { @ftp.rename("from.file", "to.file") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 502" do
+ @server.should_receive(:rnfr).and_respond("502 Command not implemented.")
+ lambda { @ftp.rename("from.file", "to.file") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:rnfr).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.rename("from.file", "to.file") }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 530" do
+ @server.should_receive(:rnfr).and_respond("530 Not logged in.")
+ lambda { @ftp.rename("from.file", "to.file") }.should raise_error(Net::FTPPermError)
+ end
+ end
+
+ describe "when the RNTO command fails" do
+ it "raises a Net::FTPPermError when the response code is 532" do
+ @server.should_receive(:rnfr).and_respond("532 Need account for storing files.")
+ lambda { @ftp.rename("from.file", "to.file") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 553" do
+ @server.should_receive(:rnto).and_respond("553 Requested action not taken.")
+ lambda { @ftp.rename("from.file", "to.file") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:rnto).and_respond("501 Syntax error in parameters or arguments.")
+ lambda { @ftp.rename("from.file", "to.file") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 502" do
+ @server.should_receive(:rnto).and_respond("502 Command not implemented.")
+ lambda { @ftp.rename("from.file", "to.file") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:rnto).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.rename("from.file", "to.file") }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 530" do
+ @server.should_receive(:rnto).and_respond("530 Not logged in.")
+ lambda { @ftp.rename("from.file", "to.file") }.should raise_error(Net::FTPPermError)
+ end
+ end
+end
diff --git a/spec/ruby/library/net/ftp/resume_spec.rb b/spec/ruby/library/net/ftp/resume_spec.rb
new file mode 100644
index 0000000000..9ec4a921aa
--- /dev/null
+++ b/spec/ruby/library/net/ftp/resume_spec.rb
@@ -0,0 +1,23 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+
+describe "Net::FTP#resume" do
+ it "returns true when self is set to resume uploads/downloads" do
+ ftp = Net::FTP.new
+ ftp.resume.should be_false
+
+ ftp.resume = true
+ ftp.resume.should be_true
+ end
+end
+
+describe "Net::FTP#resume=" do
+ it "sets self to resume uploads/downloads when set to true" do
+ ftp = Net::FTP.new
+ ftp.resume = true
+ ftp.resume.should be_true
+
+ ftp.resume = false
+ ftp.resume.should be_false
+ end
+end
diff --git a/spec/ruby/library/net/ftp/retrbinary_spec.rb b/spec/ruby/library/net/ftp/retrbinary_spec.rb
new file mode 100644
index 0000000000..fd7af0b62a
--- /dev/null
+++ b/spec/ruby/library/net/ftp/retrbinary_spec.rb
@@ -0,0 +1,30 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#retrbinary" do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ it "sends the passed command to the server" do
+ @ftp.retrbinary("RETR test", 4096) {}
+ @ftp.last_response.should == "226 Closing data connection. (RETR test)\n"
+ end
+
+ it "yields the received content as binary blocks of the passed size" do
+ res = []
+ @ftp.retrbinary("RETR test", 10) { |bin| res << bin }
+ res.should == [ "This is th", "e content\n", "of the fil", "e named 't", "est'.\n" ]
+ end
+end
diff --git a/spec/ruby/library/net/ftp/retrlines_spec.rb b/spec/ruby/library/net/ftp/retrlines_spec.rb
new file mode 100644
index 0000000000..cb8d48ecf7
--- /dev/null
+++ b/spec/ruby/library/net/ftp/retrlines_spec.rb
@@ -0,0 +1,34 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#retrlines" do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ it "sends the passed command over the socket" do
+ @ftp.retrlines("LIST test.dir") {}
+ @ftp.last_response.should == "226 transfer complete (LIST test.dir)\n"
+ end
+
+ it "yields each received line to the passed block" do
+ res = []
+ @ftp.retrlines("LIST test.dir") { |x| res << x }
+ res.should == [
+ "-rw-r--r-- 1 spec staff 507 17 Jul 18:41 last_response_code.rb",
+ "-rw-r--r-- 1 spec staff 50 17 Jul 18:41 list.rb",
+ "-rw-r--r-- 1 spec staff 48 17 Jul 18:41 pwd.rb"
+ ]
+ end
+end
diff --git a/spec/ruby/library/net/ftp/return_code_spec.rb b/spec/ruby/library/net/ftp/return_code_spec.rb
new file mode 100644
index 0000000000..b6090aeb61
--- /dev/null
+++ b/spec/ruby/library/net/ftp/return_code_spec.rb
@@ -0,0 +1,24 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+
+describe "Net::FTP#return_code" do
+ before :each do
+ @ftp = Net::FTP.new
+ end
+
+ it "outputs a warning and returns a newline" do
+ lambda do
+ @ftp.return_code.should == "\n"
+ end.should complain("warning: Net::FTP#return_code is obsolete and do nothing\n")
+ end
+end
+
+describe "Net::FTP#return_code=" do
+ before :each do
+ @ftp = Net::FTP.new
+ end
+
+ it "outputs a warning" do
+ lambda { @ftp.return_code = 123 }.should complain("warning: Net::FTP#return_code= is obsolete and do nothing\n")
+ end
+end
diff --git a/spec/ruby/library/net/ftp/rmdir_spec.rb b/spec/ruby/library/net/ftp/rmdir_spec.rb
new file mode 100644
index 0000000000..453c7823c4
--- /dev/null
+++ b/spec/ruby/library/net/ftp/rmdir_spec.rb
@@ -0,0 +1,58 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#rmdir" do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ it "sends the RMD command with the passed pathname to the server" do
+ @ftp.rmdir("test.folder")
+ @ftp.last_response.should == "250 Requested file action okay, completed. (RMD test.folder)\n"
+ end
+
+ it "returns nil" do
+ @ftp.rmdir("test.folder").should be_nil
+ end
+
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:rmd).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.rmdir("test.folder") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:rmd).and_respond("501 Syntax error in parameters or arguments.")
+ lambda { @ftp.rmdir("test.folder") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 502" do
+ @server.should_receive(:rmd).and_respond("502 Command not implemented.")
+ lambda { @ftp.rmdir("test.folder") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:rmd).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.rmdir("test.folder") }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 530" do
+ @server.should_receive(:rmd).and_respond("530 Not logged in.")
+ lambda { @ftp.rmdir("test.folder") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 550" do
+ @server.should_receive(:rmd).and_respond("550 Requested action not taken.")
+ lambda { @ftp.rmdir("test.folder") }.should raise_error(Net::FTPPermError)
+ end
+end
diff --git a/spec/ruby/library/net/ftp/sendcmd_spec.rb b/spec/ruby/library/net/ftp/sendcmd_spec.rb
new file mode 100644
index 0000000000..9bdca621bc
--- /dev/null
+++ b/spec/ruby/library/net/ftp/sendcmd_spec.rb
@@ -0,0 +1,54 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#sendcmd" do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ it "sends the passed command to the server" do
+ @ftp.sendcmd("HELP")
+ @ftp.last_response.should == "211 System status, or system help reply. (HELP)\n"
+ end
+
+ it "returns the server's response" do
+ @ftp.sendcmd("HELP").should == "211 System status, or system help reply. (HELP)\n"
+ end
+
+ it "raises no error when the response code is 1xx, 2xx or 3xx" do
+ @server.should_receive(:help).and_respond("120 Service ready in nnn minutes.")
+ lambda { @ftp.sendcmd("HELP") }.should_not raise_error
+
+ @server.should_receive(:help).and_respond("200 Command okay.")
+ lambda { @ftp.sendcmd("HELP") }.should_not raise_error
+
+ @server.should_receive(:help).and_respond("350 Requested file action pending further information.")
+ lambda { @ftp.sendcmd("HELP") }.should_not raise_error
+ end
+
+ it "raises a Net::FTPTempError when the response code is 4xx" do
+ @server.should_receive(:help).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.sendcmd("HELP") }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 5xx" do
+ @server.should_receive(:help).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.sendcmd("HELP") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPProtoError when the response code is not between 1xx-5xx" do
+ @server.should_receive(:help).and_respond("999 Invalid response.")
+ lambda { @ftp.sendcmd("HELP") }.should raise_error(Net::FTPProtoError)
+ end
+end
diff --git a/spec/ruby/library/net/ftp/set_socket_spec.rb b/spec/ruby/library/net/ftp/set_socket_spec.rb
new file mode 100644
index 0000000000..1553445219
--- /dev/null
+++ b/spec/ruby/library/net/ftp/set_socket_spec.rb
@@ -0,0 +1,8 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+
+describe "Net::FTP#set_socket" do
+ # TODO: I won't spec this method, as it is not used
+ # anywhere and it should be private anyway.
+ #it "needs to be reviewed for spec completeness"
+end
diff --git a/spec/ruby/library/net/ftp/shared/getbinaryfile.rb b/spec/ruby/library/net/ftp/shared/getbinaryfile.rb
new file mode 100644
index 0000000000..2252935b2d
--- /dev/null
+++ b/spec/ruby/library/net/ftp/shared/getbinaryfile.rb
@@ -0,0 +1,150 @@
+describe :net_ftp_getbinaryfile, shared: :true do
+ before :each do
+ @fixture_file = File.dirname(__FILE__) + "/../fixtures/getbinaryfile"
+ @tmp_file = tmp("getbinaryfile")
+
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ @ftp.binary = @binary_mode
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+
+ rm_r @tmp_file
+ end
+
+ it "sends the RETR command to the server" do
+ @ftp.send(@method, "test", @tmp_file)
+ @ftp.last_response.should == "226 Closing data connection. (RETR test)\n"
+ end
+
+ it "returns nil" do
+ @ftp.send(@method, "test", @tmp_file).should be_nil
+ end
+
+ it "saves the contents of the passed remote file to the passed local file" do
+ @ftp.send(@method, "test", @tmp_file)
+ File.read(@tmp_file).should == "This is the content\nof the file named 'test'.\n"
+ end
+
+ describe "when passed a block" do
+ it "yields the received content as binary blocks of the passed size" do
+ res = []
+ @ftp.send(@method, "test", @tmp_file, 10) { |bin| res << bin }
+ res.should == [ "This is th", "e content\n", "of the fil", "e named 't", "est'.\n" ]
+ end
+ end
+
+ describe "when resuming an existing file" do
+ before :each do
+ @tmp_file = tmp("getbinaryfile_resume")
+
+ File.open(@tmp_file, "wb") do |f|
+ f << "This is the content\n"
+ end
+
+ @ftp.resume = true
+ end
+
+ it "saves the remaining content of the passed remote file to the passed local file" do
+ @ftp.send(@method, "test", @tmp_file)
+ File.read(@tmp_file).should == "This is the content\nof the file named 'test'.\n"
+ end
+
+ describe "and the REST command fails" do
+ it "raises a Net::FTPProtoError when the response code is 550" do
+ @server.should_receive(:rest).and_respond("Requested action not taken.")
+ lambda { @ftp.send(@method, "test", @tmp_file) }.should raise_error(Net::FTPProtoError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:rest).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.send(@method, "test", @tmp_file) }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:rest).and_respond("501 Syntax error, command unrecognized.")
+ lambda { @ftp.send(@method, "test", @tmp_file) }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 502" do
+ @server.should_receive(:rest).and_respond("502 Command not implemented.")
+ lambda { @ftp.send(@method, "test", @tmp_file) }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:rest).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.send(@method, "test", @tmp_file) }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 530" do
+ @server.should_receive(:rest).and_respond("530 Not logged in.")
+ lambda { @ftp.send(@method, "test", @tmp_file) }.should raise_error(Net::FTPPermError)
+ end
+ end
+ end
+
+ describe "when the RETR command fails" do
+ it "raises a Net::FTPTempError when the response code is 450" do
+ @server.should_receive(:retr).and_respond("450 Requested file action not taken.")
+ lambda { @ftp.send(@method, "test", @tmp_file) }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPProtoError when the response code is 550" do
+ @server.should_receive(:retr).and_respond("Requested action not taken.")
+ lambda { @ftp.send(@method, "test", @tmp_file) }.should raise_error(Net::FTPProtoError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:retr).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.send(@method, "test", @tmp_file) }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:retr).and_respond("501 Syntax error, command unrecognized.")
+ lambda { @ftp.send(@method, "test", @tmp_file) }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:retr).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.send(@method, "test", @tmp_file) }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 530" do
+ @server.should_receive(:retr).and_respond("530 Not logged in.")
+ lambda { @ftp.send(@method, "test", @tmp_file) }.should raise_error(Net::FTPPermError)
+ end
+ end
+
+ describe "when opening the data port fails" do
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:eprt).and_respond("500 Syntax error, command unrecognized.")
+ @server.should_receive(:port).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.send(@method, "test", @tmp_file) }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:eprt).and_respond("501 Syntax error in parameters or arguments.")
+ @server.should_receive(:port).and_respond("501 Syntax error in parameters or arguments.")
+ lambda { @ftp.send(@method, "test", @tmp_file) }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:eprt).and_respond("421 Service not available, closing control connection.")
+ @server.should_receive(:port).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.send(@method, "test", @tmp_file) }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 530" do
+ @server.should_receive(:eprt).and_respond("530 Not logged in.")
+ @server.should_receive(:port).and_respond("530 Not logged in.")
+ lambda { @ftp.send(@method, "test", @tmp_file) }.should raise_error(Net::FTPPermError)
+ end
+ end
+end
diff --git a/spec/ruby/library/net/ftp/shared/gettextfile.rb b/spec/ruby/library/net/ftp/shared/gettextfile.rb
new file mode 100644
index 0000000000..6219581d12
--- /dev/null
+++ b/spec/ruby/library/net/ftp/shared/gettextfile.rb
@@ -0,0 +1,100 @@
+describe :net_ftp_gettextfile, shared: :true do
+ before :each do
+ @tmp_file = tmp("gettextfile")
+
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ @ftp.binary = @binary_mode
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+
+ rm_r @tmp_file
+ end
+
+ it "sends the RETR command to the server" do
+ @ftp.send(@method, "test", @tmp_file)
+ @ftp.last_response.should == "226 Closing data connection. (RETR test)\n"
+ end
+
+ it "returns nil" do
+ @ftp.send(@method, "test", @tmp_file).should be_nil
+ end
+
+ it "saves the contents of the passed remote file to the passed local file" do
+ @ftp.send(@method, "test", @tmp_file)
+ File.read(@tmp_file).should == "This is the content\nof the file named 'test'.\n"
+ end
+
+ describe "when passed a block" do
+ it "yields each line of the retrieved file to the passed block" do
+ res = []
+ @ftp.send(@method, "test", @tmp_file) { |line| res << line }
+ res.should == [ "This is the content", "of the file named 'test'."]
+ end
+ end
+
+ describe "when the RETR command fails" do
+ it "raises a Net::FTPTempError when the response code is 450" do
+ @server.should_receive(:retr).and_respond("450 Requested file action not taken.")
+ lambda { @ftp.send(@method, "test", @tmp_file) }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPProtoError when the response code is 550" do
+ @server.should_receive(:retr).and_respond("Requested action not taken.")
+ lambda { @ftp.send(@method, "test", @tmp_file) }.should raise_error(Net::FTPProtoError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:retr).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.send(@method, "test", @tmp_file) }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:retr).and_respond("501 Syntax error, command unrecognized.")
+ lambda { @ftp.send(@method, "test", @tmp_file) }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:retr).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.send(@method, "test", @tmp_file) }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 530" do
+ @server.should_receive(:retr).and_respond("530 Not logged in.")
+ lambda { @ftp.send(@method, "test", @tmp_file) }.should raise_error(Net::FTPPermError)
+ end
+ end
+
+ describe "when opening the data port fails" do
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:eprt).and_respond("500 Syntax error, command unrecognized.")
+ @server.should_receive(:port).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.send(@method, "test", @tmp_file) }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:eprt).and_respond("501 Syntax error in parameters or arguments.")
+ @server.should_receive(:port).and_respond("501 Syntax error in parameters or arguments.")
+ lambda { @ftp.send(@method, "test", @tmp_file) }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:eprt).and_respond("421 Service not available, closing control connection.")
+ @server.should_receive(:port).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.send(@method, "test", @tmp_file) }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 530" do
+ @server.should_receive(:eprt).and_respond("530 Not logged in.")
+ @server.should_receive(:port).and_respond("530 Not logged in.")
+ lambda { @ftp.send(@method, "test", @tmp_file) }.should raise_error(Net::FTPPermError)
+ end
+ end
+end
diff --git a/spec/ruby/library/net/ftp/shared/last_response_code.rb b/spec/ruby/library/net/ftp/shared/last_response_code.rb
new file mode 100644
index 0000000000..4fe53677db
--- /dev/null
+++ b/spec/ruby/library/net/ftp/shared/last_response_code.rb
@@ -0,0 +1,25 @@
+describe :net_ftp_last_response_code, shared: true do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ it "returns the response code for the last response" do
+ @server.should_receive(:help).and_respond("200 Command okay.")
+ @ftp.help
+ @ftp.send(@method).should == "200"
+
+ @server.should_receive(:help).and_respond("212 Directory status.")
+ @ftp.help
+ @ftp.send(@method).should == "212"
+ end
+end
diff --git a/spec/ruby/library/net/ftp/shared/list.rb b/spec/ruby/library/net/ftp/shared/list.rb
new file mode 100644
index 0000000000..50ca8ad119
--- /dev/null
+++ b/spec/ruby/library/net/ftp/shared/list.rb
@@ -0,0 +1,104 @@
+describe :net_ftp_list, shared: true do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.passive = false
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ describe "when passed a block" do
+ it "yields each file in the list of files in the passed dir" do
+ expected = [
+ "-rw-r--r-- 1 spec staff 507 17 Jul 18:41 last_response_code.rb",
+ "-rw-r--r-- 1 spec staff 50 17 Jul 18:41 list.rb",
+ "-rw-r--r-- 1 spec staff 48 17 Jul 18:41 pwd.rb"
+ ]
+
+ res = []
+ @ftp.send(@method, "test.folder") { |line| res << line}
+ res.should == expected
+
+ @ftp.last_response.should == "226 transfer complete (LIST test.folder)\n"
+ end
+ end
+
+ describe "when passed no block" do
+ it "returns an Array containing a list of files in the passed dir" do
+ expected = [
+ "-rw-r--r-- 1 spec staff 507 17 Jul 18:41 last_response_code.rb",
+ "-rw-r--r-- 1 spec staff 50 17 Jul 18:41 list.rb",
+ "-rw-r--r-- 1 spec staff 48 17 Jul 18:41 pwd.rb"
+ ]
+
+ @ftp.send(@method, "test.folder").should == expected
+
+ @ftp.last_response.should == "226 transfer complete (LIST test.folder)\n"
+ end
+ end
+
+ describe "when the LIST command fails" do
+ it "raises a Net::FTPTempError when the response code is 450" do
+ @server.should_receive(:list).and_respond("450 Requested file action not taken..")
+ lambda { @ftp.send(@method) }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:list).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.send(@method) }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:list).and_respond("501 Syntax error, command unrecognized.")
+ lambda { @ftp.send(@method) }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 502" do
+ @server.should_receive(:list).and_respond("502 Command not implemented.")
+ lambda { @ftp.send(@method) }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:list).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.send(@method) }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 530" do
+ @server.should_receive(:list).and_respond("530 Not logged in.")
+ lambda { @ftp.send(@method) }.should raise_error(Net::FTPPermError)
+ end
+ end
+
+ describe "when opening the data port fails" do
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:eprt).and_respond("500 Syntax error, command unrecognized.")
+ @server.should_receive(:port).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.send(@method) }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:eprt).and_respond("501 Syntax error in parameters or arguments.")
+ @server.should_receive(:port).and_respond("501 Syntax error in parameters or arguments.")
+ lambda { @ftp.send(@method) }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:eprt).and_respond("421 Service not available, closing control connection.")
+ @server.should_receive(:port).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.send(@method) }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 530" do
+ @server.should_receive(:eprt).and_respond("530 Not logged in.")
+ @server.should_receive(:port).and_respond("530 Not logged in.")
+ lambda { @ftp.send(@method) }.should raise_error(Net::FTPPermError)
+ end
+ end
+end
diff --git a/spec/ruby/library/net/ftp/shared/putbinaryfile.rb b/spec/ruby/library/net/ftp/shared/putbinaryfile.rb
new file mode 100644
index 0000000000..74eaf320ae
--- /dev/null
+++ b/spec/ruby/library/net/ftp/shared/putbinaryfile.rb
@@ -0,0 +1,167 @@
+describe :net_ftp_putbinaryfile, shared: :true do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @local_fixture_file = File.dirname(__FILE__) + "/../fixtures/putbinaryfile"
+ @remote_tmp_file = tmp("binaryfile", false)
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ @ftp.binary = @binary_mode
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+
+ rm_r @remote_tmp_file
+ end
+
+ it "sends the STOR command to the server" do
+ @ftp.send(@method, @local_fixture_file, "binary")
+ @ftp.last_response.should == "200 OK, Data received. (STOR binary)\n"
+ end
+
+ it "sends the contents of the passed local_file, without modifications" do
+ @ftp.send(@method, @local_fixture_file, "binary")
+
+ remote_lines = File.readlines(@remote_tmp_file)
+ local_lines = File.readlines(@local_fixture_file)
+
+ remote_lines.should == local_lines
+ end
+
+ it "returns nil" do
+ @ftp.send(@method, @local_fixture_file, "binary").should be_nil
+ end
+
+ describe "when passed a block" do
+ it "yields the transmitted content as binary blocks of the passed size" do
+ res = []
+ @ftp.send(@method, @local_fixture_file, "binary", 10) { |x| res << x }
+ res.should == [
+ "This is an", " example f",
+ "ile\nwhich ", "is going t",
+ "o be trans", "mitted\nusi",
+ "ng #putbin", "aryfile.\n"
+ ]
+ end
+ end
+
+ describe "when resuming an existing file" do
+ before :each do
+ File.open(@remote_tmp_file, "w") do |f|
+ f << "This is an example file\n"
+ end
+
+ @ftp.resume = true
+ end
+
+ it "sends the remaining content of the passed local_file to the passed remote_file" do
+ @ftp.send(@method, @local_fixture_file, "binary")
+ File.read(@remote_tmp_file).should == File.read(@local_fixture_file)
+ end
+
+ describe "and the APPE command fails" do
+ it "raises a Net::FTPProtoError when the response code is 550" do
+ @server.should_receive(:appe).and_respond("Requested action not taken.")
+ lambda { @ftp.send(@method, @local_fixture_file, "binary") }.should raise_error(Net::FTPProtoError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:appe).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.send(@method, @local_fixture_file, "binary") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:appe).and_respond("501 Syntax error, command unrecognized.")
+ lambda { @ftp.send(@method, @local_fixture_file, "binary") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 502" do
+ @server.should_receive(:appe).and_respond("502 Command not implemented.")
+ lambda { @ftp.send(@method, @local_fixture_file, "binary") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:appe).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.send(@method, @local_fixture_file, "binary") }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 530" do
+ @server.should_receive(:appe).and_respond("530 Not logged in.")
+ lambda { @ftp.send(@method, @local_fixture_file, "binary") }.should raise_error(Net::FTPPermError)
+ end
+ end
+ end
+
+ describe "when the STOR command fails" do
+ it "raises a Net::FTPPermError when the response code is 532" do
+ @server.should_receive(:stor).and_respond("532 Need account for storing files.")
+ lambda { @ftp.send(@method, @local_fixture_file, "binary") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 450" do
+ @server.should_receive(:stor).and_respond("450 Requested file action not taken.")
+ lambda { @ftp.send(@method, @local_fixture_file, "binary") }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 452" do
+ @server.should_receive(:stor).and_respond("452 Requested action not taken.")
+ lambda { @ftp.send(@method, @local_fixture_file, "binary") }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 553" do
+ @server.should_receive(:stor).and_respond("553 Requested action not taken.")
+ lambda { @ftp.send(@method, @local_fixture_file, "binary") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:stor).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.send(@method, @local_fixture_file, "binary") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:stor).and_respond("501 Syntax error in parameters or arguments.")
+ lambda { @ftp.send(@method, @local_fixture_file, "binary") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:stor).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.send(@method, @local_fixture_file, "binary") }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 530" do
+ @server.should_receive(:stor).and_respond("530 Not logged in.")
+ lambda { @ftp.send(@method, @local_fixture_file, "binary") }.should raise_error(Net::FTPPermError)
+ end
+ end
+
+ describe "when opening the data port fails" do
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:eprt).and_respond("500 Syntax error, command unrecognized.")
+ @server.should_receive(:port).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.send(@method, @local_fixture_file, "binary") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:eprt).and_respond("501 Syntax error in parameters or arguments.")
+ @server.should_receive(:port).and_respond("501 Syntax error in parameters or arguments.")
+ lambda { @ftp.send(@method, @local_fixture_file, "binary") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:eprt).and_respond("421 Service not available, closing control connection.")
+ @server.should_receive(:port).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.send(@method, @local_fixture_file, "binary") }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 530" do
+ @server.should_receive(:eprt).and_respond("530 Not logged in.")
+ @server.should_receive(:port).and_respond("530 Not logged in.")
+ lambda { @ftp.send(@method, @local_fixture_file, "binary") }.should raise_error(Net::FTPPermError)
+ end
+ end
+end
diff --git a/spec/ruby/library/net/ftp/shared/puttextfile.rb b/spec/ruby/library/net/ftp/shared/puttextfile.rb
new file mode 100644
index 0000000000..9bfdc7c41e
--- /dev/null
+++ b/spec/ruby/library/net/ftp/shared/puttextfile.rb
@@ -0,0 +1,120 @@
+describe :net_ftp_puttextfile, shared: true do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @local_fixture_file = File.dirname(__FILE__) + "/../fixtures/puttextfile"
+ @remote_tmp_file = tmp("textfile", false)
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ @ftp.binary = @binary_mode
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+
+ rm_r @remote_tmp_file
+ end
+
+ it "sends the STOR command to the server" do
+ @ftp.send(@method, @local_fixture_file, "text")
+ @ftp.last_response.should == "200 OK, Data received. (STOR text)\n"
+ end
+
+ it "sends the contents of the passed local_file, using \\r\\n as the newline separator" do
+ @ftp.send(@method, @local_fixture_file, "text")
+
+ remote_lines = open(@remote_tmp_file, "rb") {|f| f.read }
+ local_lines = open(@local_fixture_file, "rb") {|f| f.read }
+
+ remote_lines.should_not == local_lines
+ remote_lines.should == local_lines.gsub("\n", "\r\n")
+ end
+
+ it "returns nil" do
+ @ftp.send(@method, @local_fixture_file, "text").should be_nil
+ end
+
+ describe "when passed a block" do
+ it "yields each transmitted line" do
+ res = []
+ @ftp.send(@method, @local_fixture_file, "text") { |x| res << x }
+ res.should == [
+ "This is an example file\r\n",
+ "which is going to be transmitted\r\n",
+ "using #puttextfile.\r\n"
+ ]
+ end
+ end
+
+ describe "when the STOR command fails" do
+ it "raises a Net::FTPPermError when the response code is 532" do
+ @server.should_receive(:stor).and_respond("532 Need account for storing files.")
+ lambda { @ftp.send(@method, @local_fixture_file, "text") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 450" do
+ @server.should_receive(:stor).and_respond("450 Requested file action not taken.")
+ lambda { @ftp.send(@method, @local_fixture_file, "text") }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 452" do
+ @server.should_receive(:stor).and_respond("452 Requested action not taken.")
+ lambda { @ftp.send(@method, @local_fixture_file, "text") }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 553" do
+ @server.should_receive(:stor).and_respond("553 Requested action not taken.")
+ lambda { @ftp.send(@method, @local_fixture_file, "text") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:stor).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.send(@method, @local_fixture_file, "text") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:stor).and_respond("501 Syntax error in parameters or arguments.")
+ lambda { @ftp.send(@method, @local_fixture_file, "text") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:stor).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.send(@method, @local_fixture_file, "text") }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 530" do
+ @server.should_receive(:stor).and_respond("530 Not logged in.")
+ lambda { @ftp.send(@method, @local_fixture_file, "text") }.should raise_error(Net::FTPPermError)
+ end
+ end
+
+ describe "when opening the data port fails" do
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:eprt).and_respond("500 Syntax error, command unrecognized.")
+ @server.should_receive(:port).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.send(@method, @local_fixture_file, "text") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:eprt).and_respond("501 Syntax error in parameters or arguments.")
+ @server.should_receive(:port).and_respond("501 Syntax error in parameters or arguments.")
+ lambda { @ftp.send(@method, @local_fixture_file, "text") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:eprt).and_respond("421 Service not available, closing control connection.")
+ @server.should_receive(:port).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.send(@method, @local_fixture_file, "text") }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 530" do
+ @server.should_receive(:eprt).and_respond("530 Not logged in.")
+ @server.should_receive(:port).and_respond("530 Not logged in.")
+ lambda { @ftp.send(@method, @local_fixture_file, "text") }.should raise_error(Net::FTPPermError)
+ end
+ end
+end
diff --git a/spec/ruby/library/net/ftp/shared/pwd.rb b/spec/ruby/library/net/ftp/shared/pwd.rb
new file mode 100644
index 0000000000..951d020f2d
--- /dev/null
+++ b/spec/ruby/library/net/ftp/shared/pwd.rb
@@ -0,0 +1,3 @@
+describe :net_ftp_pwd, shared: true do
+
+end
diff --git a/spec/ruby/library/net/ftp/site_spec.rb b/spec/ruby/library/net/ftp/site_spec.rb
new file mode 100644
index 0000000000..d02b94e899
--- /dev/null
+++ b/spec/ruby/library/net/ftp/site_spec.rb
@@ -0,0 +1,53 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#site" do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ it "sends the SITE command with the passed argument to the server" do
+ @ftp.site("param")
+ @ftp.last_response.should == "200 Command okay. (SITE param)\n"
+ end
+
+ it "returns nil" do
+ @ftp.site("param").should be_nil
+ end
+
+ it "does not raise an error when the response code is 202" do
+ @server.should_receive(:site).and_respond("202 Command not implemented, superfluous at this site.")
+ lambda { @ftp.site("param") }.should_not raise_error
+ end
+
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:site).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.site("param") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:site).and_respond("501 Syntax error in parameters or arguments.")
+ lambda { @ftp.site("param") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:site).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.site("param") }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 530" do
+ @server.should_receive(:site).and_respond("530 Requested action not taken.")
+ lambda { @ftp.site("param") }.should raise_error(Net::FTPPermError)
+ end
+end
diff --git a/spec/ruby/library/net/ftp/size_spec.rb b/spec/ruby/library/net/ftp/size_spec.rb
new file mode 100644
index 0000000000..a3d5db50b4
--- /dev/null
+++ b/spec/ruby/library/net/ftp/size_spec.rb
@@ -0,0 +1,48 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#size" do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ it "sends the SIZE command to the server" do
+ @ftp.size("test.file")
+ @ftp.last_response.should == "213 1024\n"
+ end
+
+ it "returns the size of the passed file as Integer" do
+ @ftp.size("test.file").should eql(1024)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:size).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.size("test.file") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:size).and_respond("501 Syntax error in parameters or arguments.")
+ lambda { @ftp.size("test.file") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:size).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.size("test.file") }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 550" do
+ @server.should_receive(:size).and_respond("550 Requested action not taken.")
+ lambda { @ftp.size("test.file") }.should raise_error(Net::FTPPermError)
+ end
+end
diff --git a/spec/ruby/library/net/ftp/spec_helper.rb b/spec/ruby/library/net/ftp/spec_helper.rb
new file mode 100644
index 0000000000..c87d16218b
--- /dev/null
+++ b/spec/ruby/library/net/ftp/spec_helper.rb
@@ -0,0 +1,5 @@
+require "net/ftp"
+
+if defined?(Net::FTP.default_passive)
+ Net::FTP.default_passive = false
+end
diff --git a/spec/ruby/library/net/ftp/status_spec.rb b/spec/ruby/library/net/ftp/status_spec.rb
new file mode 100644
index 0000000000..7e9927c3c8
--- /dev/null
+++ b/spec/ruby/library/net/ftp/status_spec.rb
@@ -0,0 +1,63 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#status" do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ it "sends the STAT command to the server" do
+ @ftp.status
+ @ftp.last_response.should == "211 System status, or system help reply. (STAT)\n"
+ end
+
+ it "returns the received information" do
+ @ftp.status.should == "211 System status, or system help reply. (STAT)\n"
+ end
+
+ it "does not raise an error when the response code is 212" do
+ @server.should_receive(:stat).and_respond("212 Directory status.")
+ lambda { @ftp.status }.should_not raise_error
+ end
+
+ it "does not raise an error when the response code is 213" do
+ @server.should_receive(:stat).and_respond("213 File status.")
+ lambda { @ftp.status }.should_not raise_error
+ end
+
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:stat).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.status }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:stat).and_respond("501 Syntax error in parameters or arguments.")
+ lambda { @ftp.status }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 502" do
+ @server.should_receive(:stat).and_respond("502 Command not implemented.")
+ lambda { @ftp.status }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:stat).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.status }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 530" do
+ @server.should_receive(:stat).and_respond("530 Requested action not taken.")
+ lambda { @ftp.status }.should raise_error(Net::FTPPermError)
+ end
+end
diff --git a/spec/ruby/library/net/ftp/storbinary_spec.rb b/spec/ruby/library/net/ftp/storbinary_spec.rb
new file mode 100644
index 0000000000..fc7561b5a9
--- /dev/null
+++ b/spec/ruby/library/net/ftp/storbinary_spec.rb
@@ -0,0 +1,48 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#storbinary" do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @local_fixture_file = File.dirname(__FILE__) + "/fixtures/putbinaryfile"
+ @tmp_file = tmp("binaryfile", false)
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+
+ rm_r @tmp_file
+ end
+
+ it "sends the passed command and the passed File object's content to the server" do
+ File.open(@local_fixture_file) do |f|
+ f.binmode
+
+ @ftp.storbinary("STOR binary", f, 4096) {}
+ @ftp.last_response.should == "200 OK, Data received. (STOR binary)\n"
+ end
+ end
+
+ it "yields the transmitted content as binary blocks of the passed size" do
+ File.open(@local_fixture_file) do |f|
+ f.binmode
+
+ res = []
+ @ftp.storbinary("STOR binary", f, 10) { |x| res << x }
+ res.should == [
+ "This is an", " example f",
+ "ile\nwhich ", "is going t",
+ "o be trans", "mitted\nusi",
+ "ng #putbin", "aryfile.\n"
+ ]
+ end
+ end
+end
diff --git a/spec/ruby/library/net/ftp/storlines_spec.rb b/spec/ruby/library/net/ftp/storlines_spec.rb
new file mode 100644
index 0000000000..9ea4b83603
--- /dev/null
+++ b/spec/ruby/library/net/ftp/storlines_spec.rb
@@ -0,0 +1,43 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#storlines" do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @local_fixture_file = File.dirname(__FILE__) + "/fixtures/puttextfile"
+ @tmp_file = tmp("textfile", false)
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+
+ rm_r @tmp_file
+ end
+
+ it "sends the passed command and the passed File object's content to the server" do
+ File.open(@local_fixture_file) do |f|
+ @ftp.storlines("STOR text", f) {}
+ @ftp.last_response.should == "200 OK, Data received. (STOR text)\n"
+ end
+ end
+
+ it "yields each line of the transmitted content" do
+ File.open(@local_fixture_file) do |f|
+ res = []
+ @ftp.storlines("STOR text", f) { |x| res << x }
+ res.should == [
+ "This is an example file\r\n",
+ "which is going to be transmitted\r\n",
+ "using #puttextfile.\r\n"
+ ]
+ end
+ end
+end
diff --git a/spec/ruby/library/net/ftp/system_spec.rb b/spec/ruby/library/net/ftp/system_spec.rb
new file mode 100644
index 0000000000..603dd09152
--- /dev/null
+++ b/spec/ruby/library/net/ftp/system_spec.rb
@@ -0,0 +1,48 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#system" do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ it "sends the SYST command to the server" do
+ @ftp.system
+ @ftp.last_response.should =~ /\A215 FTP Dummy Server \(SYST\)\Z/
+ end
+
+ it "returns the received information" do
+ @ftp.system.should =~ /\AFTP Dummy Server \(SYST\)\Z/
+ end
+
+ it "raises a Net::FTPPermError when the response code is 500" do
+ @server.should_receive(:syst).and_respond("500 Syntax error, command unrecognized.")
+ lambda { @ftp.system }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 501" do
+ @server.should_receive(:syst).and_respond("501 Syntax error in parameters or arguments.")
+ lambda { @ftp.system }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 502" do
+ @server.should_receive(:syst).and_respond("502 Command not implemented.")
+ lambda { @ftp.system }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 421" do
+ @server.should_receive(:syst).and_respond("421 Service not available, closing control connection.")
+ lambda { @ftp.system }.should raise_error(Net::FTPTempError)
+ end
+end
diff --git a/spec/ruby/library/net/ftp/voidcmd_spec.rb b/spec/ruby/library/net/ftp/voidcmd_spec.rb
new file mode 100644
index 0000000000..8b3e0c17c9
--- /dev/null
+++ b/spec/ruby/library/net/ftp/voidcmd_spec.rb
@@ -0,0 +1,54 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#voidcmd" do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ it "sends the passed command to the server" do
+ @server.should_receive(:help).and_respond("2xx Does not raise.")
+ lambda { @ftp.voidcmd("HELP") }.should_not raise_error
+ end
+
+ it "returns nil" do
+ @server.should_receive(:help).and_respond("2xx Does not raise.")
+ @ftp.voidcmd("HELP").should be_nil
+ end
+
+ it "raises a Net::FTPReplyError when the response code is 1xx" do
+ @server.should_receive(:help).and_respond("1xx Does raise a Net::FTPReplyError.")
+ lambda { @ftp.voidcmd("HELP") }.should raise_error(Net::FTPReplyError)
+ end
+
+ it "raises a Net::FTPReplyError when the response code is 3xx" do
+ @server.should_receive(:help).and_respond("3xx Does raise a Net::FTPReplyError.")
+ lambda { @ftp.voidcmd("HELP") }.should raise_error(Net::FTPReplyError)
+ end
+
+ it "raises a Net::FTPTempError when the response code is 4xx" do
+ @server.should_receive(:help).and_respond("4xx Does raise a Net::FTPTempError.")
+ lambda { @ftp.voidcmd("HELP") }.should raise_error(Net::FTPTempError)
+ end
+
+ it "raises a Net::FTPPermError when the response code is 5xx" do
+ @server.should_receive(:help).and_respond("5xx Does raise a Net::FTPPermError.")
+ lambda { @ftp.voidcmd("HELP") }.should raise_error(Net::FTPPermError)
+ end
+
+ it "raises a Net::FTPProtoError when the response code is not valid" do
+ @server.should_receive(:help).and_respond("999 Does raise a Net::FTPProtoError.")
+ lambda { @ftp.voidcmd("HELP") }.should raise_error(Net::FTPProtoError)
+ end
+end
diff --git a/spec/ruby/library/net/ftp/welcome_spec.rb b/spec/ruby/library/net/ftp/welcome_spec.rb
new file mode 100644
index 0000000000..5505623ce3
--- /dev/null
+++ b/spec/ruby/library/net/ftp/welcome_spec.rb
@@ -0,0 +1,25 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../spec_helper', __FILE__)
+require File.expand_path('../fixtures/server', __FILE__)
+
+describe "Net::FTP#welcome" do
+ before :each do
+ @server = NetFTPSpecs::DummyFTP.new
+ @server.serve_once
+
+ @ftp = Net::FTP.new
+ @ftp.connect(@server.hostname, @server.server_port)
+ end
+
+ after :each do
+ @ftp.quit rescue nil
+ @ftp.close
+ @server.stop
+ end
+
+ it "returns the server's welcome message" do
+ @ftp.welcome.should be_nil
+ @ftp.login
+ @ftp.welcome.should == "230 User logged in, proceed. (USER anonymous)\n"
+ end
+end