spec/tcr_spec.rb in tcr-0.0.4 vs spec/tcr_spec.rb in tcr-0.0.5
- old
+ new
@@ -1,23 +1,37 @@
require "spec_helper"
require "tcr"
require "net/protocol"
+require "net/http"
+require "net/imap"
require "net/smtp"
+require 'thread'
+
describe TCR do
before(:each) do
TCR.configuration.reset_defaults!
end
+ around(:each) do |example|
+ File.unlink("test.json") if File.exists?("test.json")
+ example.run
+ File.unlink("test.json") if File.exists?("test.json")
+ end
+
describe ".configuration" do
it "has a default cassette location configured" do
TCR.configuration.cassette_library_dir.should == "fixtures/tcr_cassettes"
end
it "has an empty list of hook ports by default" do
TCR.configuration.hook_tcp_ports.should == []
end
+
+ it "defaults to erroring on read/write mismatch access" do
+ TCR.configuration.block_for_reads.should be_false
+ end
end
describe ".configure" do
it "configures cassette location" do
expect {
@@ -28,10 +42,16 @@
it "configures tcp ports to hook" do
expect {
TCR.configure { |c| c.hook_tcp_ports = [25] }
}.to change{ TCR.configuration.hook_tcp_ports }.from([]).to([25])
end
+
+ it "configures allowing a blocking read mode" do
+ expect {
+ TCR.configure { |c| c.block_for_reads = true }
+ }.to change{ TCR.configuration.block_for_reads }.from(false).to(true)
+ end
end
it "raises an error if you connect to a hooked port without using a cassette" do
TCR.configure { |c| c.hook_tcp_ports = [25] }
expect {
@@ -60,21 +80,55 @@
tcp_socket = TCPSocket.open("aspmx.l.google.com", 25)
end
end
end
+ describe "block_for_reads" do
+ before(:each) {
+ TCR.configure { |c|
+ c.hook_tcp_ports = [9999]
+ c.cassette_library_dir = '.'
+ }
+ }
+
+ it "blocks read thread until data is available instead of raising mismatch error" do
+ TCR.configure { |c| c.block_for_reads = true }
+ reads = Queue.new
+
+ TCR.use_cassette("spec/fixtures/block_for_reads") do
+ sock = TCPSocket.open("google.com", 9999)
+
+ t = Thread.new do
+ reads << sock.gets
+ end
+
+ expect(reads.size).to eq(0)
+ sock.print("hello\n")
+ t.value
+ expect(reads.size).to eq(1)
+ end
+ end
+
+ context "when disabled" do
+ it "raises mismatch error" do
+ TCR.use_cassette("spec/fixtures/block_for_reads") do
+ sock = TCPSocket.open("google.com", 9999)
+ expect {
+ Timeout::timeout(1) { sock.gets }
+ }.to raise_error(TCR::DirectionMismatchError)
+ end
+ end
+ end
+ end
+
describe ".use_cassette" do
before(:each) {
TCR.configure { |c|
c.hook_tcp_ports = [25]
c.cassette_library_dir = "."
}
- File.unlink("test.json") if File.exists?("test.json")
}
- after(:each) {
- File.unlink("test.json") if File.exists?("test.json")
- }
it "requires a block to call" do
expect {
TCR.use_cassette("test")
}.to raise_error(ArgumentError)
@@ -88,11 +142,10 @@
it "creates a cassette file on use" do
expect {
TCR.use_cassette("test") do
tcp_socket = TCPSocket.open("aspmx.l.google.com", 25)
- tcp_socket.close
end
}.to change{ File.exists?("./test.json") }.from(false).to(true)
end
it "records the tcp session data into the file" do
@@ -124,11 +177,47 @@
io.write("hi")
end
}.to raise_error(TCR::DirectionMismatchError)
end
+ it "stubs out Socket#gets" do
+ TCR.configure { |c|
+ c.hook_tcp_ports = [993]
+ c.block_for_reads = true
+ }
+ expect {
+ TCR.use_cassette("spec/fixtures/google_imap") do
+ conn = Net::IMAP.new("imap.gmail.com", 993, true)
+ conn.login("ben.olive@example.net", "password")
+ conn.examine(Net::IMAP.encode_utf7("INBOX"))
+ conn.disconnect
+ end
+ }.not_to raise_error
+ end
+ it "stubs out Socket#read" do
+ TCR.configure { |c|
+ c.hook_tcp_ports = [23]
+ }
+ TCR.use_cassette("spec/fixtures/starwars_telnet") do
+ sock = TCPSocket.open("towel.blinkenlights.nl", 23)
+ expect(sock.read(50).length).to eq(50)
+ sock.close
+ end
+ end
+
+ it "supports ssl sockets" do
+ TCR.configure { |c| c.hook_tcp_ports = [443] }
+ http = Net::HTTP.new("www.google.com", 443)
+ http.use_ssl = true
+ expect {
+ TCR.use_cassette("spec/fixtures/google_https") do
+ http.request(Net::HTTP::Get.new("/"))
+ end
+ }.not_to raise_error
+ end
+
context "multiple connections" do
it "records multiple sessions per cassette" do
TCR.use_cassette("test") do
smtp = Net::SMTP.start("aspmx.l.google.com", 25)
smtp.finish
@@ -150,10 +239,39 @@
io = Net::InternetMessageIO.new(tcp_socket)
line = io.readline.should include("yahoo.com ESMTP")
end
end
+ context "when a cassette is recorded with connections opens concurrently" do
+ let(:ports) { ["Apple", "Banana"].map { |payload| spawn_server(payload) } }
+ before(:each) do
+ TCR.configure { |c|
+ c.hook_tcp_ports = ports
+ c.cassette_library_dir = "."
+ }
+ end
+ before(:each) do
+ TCR.use_cassette("test") do
+ apple = TCPSocket.open("127.0.0.1", ports.first)
+ banana = TCPSocket.open("127.0.0.1", ports.last)
+
+ banana.gets
+ apple.gets
+
+ banana.close
+ apple.close
+ end
+ end
+
+ it "replays the sessions in the order they were created" do
+ TCR.use_cassette("test") do
+ apple = TCPSocket.open("127.0.0.1", ports.first)
+ expect(apple.gets).to eq("Apple")
+ end
+ end
+ end
+
it "raises an error if you try to playback more sessions than you previously recorded" do
expect {
TCR.use_cassette("spec/fixtures/multitest-smtp") do
smtp = Net::SMTP.start("aspmx.l.google.com", 25)
smtp = Net::SMTP.start("mta6.am0.yahoodns.net", 25)
@@ -161,6 +279,6 @@
end
}.to raise_error(TCR::NoMoreSessionsError)
end
end
end
-end
\ No newline at end of file
+end