From 70f1b63267ccfe99af7bc6b1ee83ccf52c23265e Mon Sep 17 00:00:00 2001 From: Richard Smiley Date: Sat, 7 Feb 2015 20:35:35 -0500 Subject: [PATCH 01/18] fix spec: be_false fails, be_falsey passes --- spec/tcr_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/tcr_spec.rb b/spec/tcr_spec.rb index a45940d..30038cd 100644 --- a/spec/tcr_spec.rb +++ b/spec/tcr_spec.rb @@ -28,7 +28,7 @@ end it "defaults to erroring on read/write mismatch access" do - TCR.configuration.block_for_reads.should be_false + TCR.configuration.block_for_reads.should be_falsey end end From 40bd423fd60093f6dc085b6f80830625b6b374a1 Mon Sep 17 00:00:00 2001 From: Richard Smiley Date: Sat, 7 Feb 2015 20:38:13 -0500 Subject: [PATCH 02/18] allow cassette format change --- spec/tcr_spec.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/spec/tcr_spec.rb b/spec/tcr_spec.rb index 30038cd..242b567 100644 --- a/spec/tcr_spec.rb +++ b/spec/tcr_spec.rb @@ -30,6 +30,10 @@ it "defaults to erroring on read/write mismatch access" do TCR.configuration.block_for_reads.should be_falsey end + + it "defaults to JSON" do + TCR.configuration.format.should == :json + end end describe ".configure" do @@ -39,6 +43,12 @@ }.to change{ TCR.configuration.cassette_library_dir }.from("fixtures/tcr_cassettes").to("some/dir") end + it "configures cassette format" do + expect { + TCR.configure { |c| c.format = :yaml } + }.to change{ TCR.configuration.format }.from(:json).to(:yaml) + end + it "configures tcp ports to hook" do expect { TCR.configure { |c| c.hook_tcp_ports = [25] } From 8d7c8118eda94cb95d18e3f51306554d6ac2ac0c Mon Sep 17 00:00:00 2001 From: Richard Smiley Date: Sat, 7 Feb 2015 20:39:26 -0500 Subject: [PATCH 03/18] configuration accessor for format --- lib/tcr/configuration.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/tcr/configuration.rb b/lib/tcr/configuration.rb index b60aada..2471e96 100644 --- a/lib/tcr/configuration.rb +++ b/lib/tcr/configuration.rb @@ -1,6 +1,6 @@ module TCR class Configuration - attr_accessor :cassette_library_dir, :hook_tcp_ports, :block_for_reads + attr_accessor :cassette_library_dir, :hook_tcp_ports, :block_for_reads, :format def initialize reset_defaults! @@ -10,6 +10,7 @@ def reset_defaults! @cassette_library_dir = "fixtures/tcr_cassettes" @hook_tcp_ports = [] @block_for_reads = false + @format = :json end end end From 285ca005185abebc87f782e46489b19fd0da7fda Mon Sep 17 00:00:00 2001 From: Richard Smiley Date: Sat, 7 Feb 2015 21:10:31 -0500 Subject: [PATCH 04/18] yaml fixtures --- spec/fixtures/block_for_reads.yaml | 7 +++ spec/fixtures/google_https.yaml | 90 ++++++++++++++++++++++++++++++ spec/fixtures/google_imap.yaml | 46 +++++++++++++++ spec/fixtures/google_smtp.yaml | 3 + spec/fixtures/multitest-smtp.yaml | 23 ++++++++ spec/fixtures/multitest.yaml | 5 ++ spec/fixtures/starwars_telnet.yaml | 3 + 7 files changed, 177 insertions(+) create mode 100644 spec/fixtures/block_for_reads.yaml create mode 100644 spec/fixtures/google_https.yaml create mode 100644 spec/fixtures/google_imap.yaml create mode 100644 spec/fixtures/google_smtp.yaml create mode 100644 spec/fixtures/multitest-smtp.yaml create mode 100644 spec/fixtures/multitest.yaml create mode 100644 spec/fixtures/starwars_telnet.yaml diff --git a/spec/fixtures/block_for_reads.yaml b/spec/fixtures/block_for_reads.yaml new file mode 100644 index 0000000..f6e7ad1 --- /dev/null +++ b/spec/fixtures/block_for_reads.yaml @@ -0,0 +1,7 @@ +--- +- - - write + - | + hello + - - read + - | + world! diff --git a/spec/fixtures/google_https.yaml b/spec/fixtures/google_https.yaml new file mode 100644 index 0000000..e6131f7 --- /dev/null +++ b/spec/fixtures/google_https.yaml @@ -0,0 +1,90 @@ +--- +- - - write + - "GET / HTTP/1.1\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: + */*\r\nUser-Agent: Ruby\r\nConnection: close\r\nHost: www.google.com\r\n\r\n" + - - read + - "HTTP/1.1 200 OK\r\nDate: Thu, 15 May 2014 15:04:03 GMT\r\nExpires: -1\r\nCache-Control: + private, max-age=0\r\nContent-Type: text/html; charset=ISO-8859-1\r\nSet-Cookie: + PREF=ID=46c9c47b277ecf04:FF=0:TM=1400166243:LM=1400166243:S=godo17lIPQRSk5e6; + expires=Sat, 14-May-2016 15:04:03 GMT; path=/; domain=.google.com\r\nSet-Cookie: + NID=67=hkRuWOEJ-mwgTBbt5NpMcYlD7G38o1tTA_mF_l2CvgY9BPVHzf3wom6KaSnvy5Ln6EqfhpD5t0KSia4b-yBj0AUFJbjfZpf_6487tcmyQMw9PtdewdXO1ZtMDD7McNeB; + expires=Fri, 14-Nov-2014 15:04:03 GMT; path=/; domain=.google.com; HttpOnly\r\nP3P: + CP=\"This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 + for more info.\"\r\nServer: gws\r\nX-XSS-Protection: 1; mode=block\r\nX-Frame-Options: + SAMEORIGIN\r\nAlternate-Protocol: 443:quic\r\nConnection: close\r\n\r\nGoogle



 

Advanced searchLanguage tools

© 2013 - Privacy & Terms

diff --git a/spec/fixtures/google_imap.yaml b/spec/fixtures/google_imap.yaml new file mode 100644 index 0000000..21d8e62 --- /dev/null +++ b/spec/fixtures/google_imap.yaml @@ -0,0 +1,46 @@ +--- +- - - read + - "* OK Gimap ready for requests from 72.16.218.22 n58mb218005052yhi\r\n" + - - write + - RUBY0001 LOGIN + - - write + - " " + - - write + - ben.olive@example.net + - - write + - " " + - - write + - password + - - write + - "\r\n" + - - read + - "* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 + UIDPLUS COMPRESS=DEFLATE ENABLE MOVE CONDSTORE ESEARCH\r\n" + - - read + - "RUBY0001 OK ben.olive@example.net Ben Olive authenticated (Success)\r\n" + - - write + - RUBY0002 EXAMINE + - - write + - " " + - - write + - INBOX + - - write + - "\r\n" + - - read + - "* FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen $Phishing $NotPhishing)\r\n" + - - read + - "* OK [PERMANENTFLAGS ()] Flags permitted.\r\n" + - - read + - "* OK [UIDVALIDITY 1] UIDs valid.\r\n" + - - read + - "* 206 EXISTS\r\n" + - - read + - "* 0 RECENT\r\n" + - - read + - "* OK [UIDNEXT 5504] Predicted next UID.\r\n" + - - read + - "* OK [HIGHESTMODSEQ 609503]\r\n" + - - read + - "RUBY0002 OK [READ-ONLY] INBOX selected. (Success)\r\n" + - - read + - diff --git a/spec/fixtures/google_smtp.yaml b/spec/fixtures/google_smtp.yaml new file mode 100644 index 0000000..a24dd54 --- /dev/null +++ b/spec/fixtures/google_smtp.yaml @@ -0,0 +1,3 @@ +--- +- - - read + - "220 mx.google.com ESMTP x3si2474860qas.18 - gsmtp\r\n" diff --git a/spec/fixtures/multitest-smtp.yaml b/spec/fixtures/multitest-smtp.yaml new file mode 100644 index 0000000..12322ba --- /dev/null +++ b/spec/fixtures/multitest-smtp.yaml @@ -0,0 +1,23 @@ +--- +- - - read + - "220 mx.google.com ESMTP d8si2472149qai.124 - gsmtp\r\n" + - - write + - "EHLO localhost\r\n" + - - read + - "250-mx.google.com at your service, [54.227.243.167]\r\n250-SIZE 35882577\r\n250-8BITMIME\r\n250-STARTTLS\r\n250 + ENHANCEDSTATUSCODES\r\n" + - - write + - "QUIT\r\n" + - - read + - "221 2.0.0 closing connection d8si2472149qai.124 - gsmtp\r\n" +- - - read + - "220 mta1579.mail.gq1.yahoo.com ESMTP YSmtpProxy service ready\r\n" + - - write + - "EHLO localhost\r\n" + - - read + - "250-mta1579.mail.gq1.yahoo.com\r\n250-8BITMIME\r\n250-SIZE 41943040\r\n250 + PIPELINING\r\n" + - - write + - "QUIT\r\n" + - - read + - "221 mta1579.mail.gq1.yahoo.com\r\n" diff --git a/spec/fixtures/multitest.yaml b/spec/fixtures/multitest.yaml new file mode 100644 index 0000000..c28604a --- /dev/null +++ b/spec/fixtures/multitest.yaml @@ -0,0 +1,5 @@ +--- +- - - read + - "220 mx.google.com ESMTP h5si2286277qec.54 - gsmtp\r\n" +- - - read + - "220 mta1009.mail.gq1.yahoo.com ESMTP YSmtpProxy service ready\r\n" diff --git a/spec/fixtures/starwars_telnet.yaml b/spec/fixtures/starwars_telnet.yaml new file mode 100644 index 0000000..73f6a1e --- /dev/null +++ b/spec/fixtures/starwars_telnet.yaml @@ -0,0 +1,3 @@ +--- +- - - read + - "\e[H\e[J\e[H\r\n\r\n\r\n\r\n\r\n\r\n " From baaae3981c5b9476d606676d9a76a481210f260b Mon Sep 17 00:00:00 2001 From: Richard Smiley Date: Sat, 7 Feb 2015 21:16:06 -0500 Subject: [PATCH 05/18] add YAML format --- lib/tcr.rb | 3 ++- lib/tcr/cassette.rb | 40 +++++++++++++++++++++++++++++-- lib/tcr/errors.rb | 1 + spec/tcr_spec.rb | 58 +++++++++++++++++++++++++++++++++++++-------- 4 files changed, 89 insertions(+), 13 deletions(-) diff --git a/lib/tcr.rb b/lib/tcr.rb index a93c6e5..a5d1fc0 100644 --- a/lib/tcr.rb +++ b/lib/tcr.rb @@ -5,6 +5,7 @@ require "tcr/version" require "socket" require "json" +require "yaml" module TCR @@ -39,7 +40,7 @@ def save_session def use_cassette(name, options = {}, &block) raise ArgumentError, "`TCR.use_cassette` requires a block." unless block - TCR.cassette = Cassette.new(name) + TCR.cassette = Cassette.get_cassette(name, configuration.format) yield TCR.cassette.save TCR.cassette = nil diff --git a/lib/tcr/cassette.rb b/lib/tcr/cassette.rb index 949bf32..e1eb4cf 100644 --- a/lib/tcr/cassette.rb +++ b/lib/tcr/cassette.rb @@ -8,7 +8,7 @@ def initialize(name) if File.exists?(filename) @recording = false @contents = File.open(filename) { |f| f.read } - @sessions = JSON.parse(@contents) + @sessions = parse else @recording = true @sessions = [] @@ -31,14 +31,50 @@ def next_session def save if recording? - File.open(filename, "w") { |f| f.write(JSON.pretty_generate(@sessions)) } + File.open(filename, "w") { |f| f.write(dump) } end end + def self.get_cassette(name, format) + if format == :json + JSONCassette.new(name) + elsif format == :yaml + YAMLCassette.new(name) + else + raise TCR::FormatError.new + end + end + end + + class JSONCassette < Cassette + def parse + JSON.parse(@contents) + end + + def dump + JSON.pretty_generate(@sessions) + end + protected def filename "#{TCR.configuration.cassette_library_dir}/#{name}.json" end end + + class YAMLCassette < Cassette + def parse + YAML.load(@contents) + end + + def dump + YAML.dump(@sessions) + end + + protected + + def filename + "#{TCR.configuration.cassette_library_dir}/#{name}.yaml" + end + end end diff --git a/lib/tcr/errors.rb b/lib/tcr/errors.rb index c5bb897..bb1cabd 100644 --- a/lib/tcr/errors.rb +++ b/lib/tcr/errors.rb @@ -1,5 +1,6 @@ module TCR class TCRError < StandardError; end + class FormatError < TCRError; end class NoCassetteError < TCRError; end class NoMoreSessionsError < TCRError; end class DirectionMismatchError < TCRError; end diff --git a/spec/tcr_spec.rb b/spec/tcr_spec.rb index 242b567..1f6ac37 100644 --- a/spec/tcr_spec.rb +++ b/spec/tcr_spec.rb @@ -12,12 +12,6 @@ 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" @@ -130,7 +124,7 @@ end end - describe ".use_cassette" do + shared_examples "a cassette" do before(:each) { TCR.configure { |c| c.hook_tcp_ports = [25] @@ -138,6 +132,12 @@ } } + around(:each) do |example| + File.unlink(test_file_name) if File.exists?(test_file_name) + example.run + File.unlink(test_file_name) if File.exists?(test_file_name) + end + it "requires a block to call" do expect { TCR.use_cassette("test") @@ -155,7 +155,7 @@ TCR.use_cassette("test") do tcp_socket = TCPSocket.open("aspmx.l.google.com", 25) end - }.to change{ File.exists?("./test.json") }.from(false).to(true) + }.to change{ File.exists?(test_file_name) }.from(false).to(true) end it "records the tcp session data into the file" do @@ -165,7 +165,7 @@ line = io.readline tcp_socket.close end - cassette_contents = File.open("test.json") { |f| f.read } + cassette_contents = File.open(test_file_name) { |f| f.read } cassette_contents.include?("220 mx.google.com ESMTP").should == true end @@ -234,7 +234,7 @@ smtp = Net::SMTP.start("mta6.am0.yahoodns.net", 25) smtp.finish end - cassette_contents = File.open("test.json") { |f| f.read } + cassette_contents = File.open(test_file_name) { |f| f.read } cassette_contents.include?("google.com ESMTP").should == true cassette_contents.include?("yahoo.com ESMTP").should == true end @@ -291,4 +291,42 @@ end end end + + describe "a JSON cassette" do + let(:test_file_name) { "test.json" } + + before(:each) do + TCR.configure do |c| + c.format = :json + end + end + + it_behaves_like "a cassette" + end + + describe "a YAML cassette" do + let(:test_file_name) { "test.yaml" } + + before(:each) do + TCR.configure do |c| + c.format = :yaml + end + end + + it_behaves_like "a cassette" + end + + describe "an invalid format cassette" do + before(:each) do + TCR.configure do |c| + c.format = :foobar + end + end + + it "raises an error" do + expect { + TCR.use_cassette("test") {} + }.to raise_error(TCR::FormatError) + end + end end From d2e60e23986091fd68bf651fd3573256a80adcb9 Mon Sep 17 00:00:00 2001 From: Richard Smiley Date: Sat, 7 Feb 2015 21:25:01 -0500 Subject: [PATCH 06/18] rename format to recording_format --- lib/tcr.rb | 2 +- lib/tcr/cassette.rb | 6 +++--- lib/tcr/configuration.rb | 4 ++-- spec/tcr_spec.rb | 12 ++++++------ 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/tcr.rb b/lib/tcr.rb index a5d1fc0..03457f7 100644 --- a/lib/tcr.rb +++ b/lib/tcr.rb @@ -40,7 +40,7 @@ def save_session def use_cassette(name, options = {}, &block) raise ArgumentError, "`TCR.use_cassette` requires a block." unless block - TCR.cassette = Cassette.get_cassette(name, configuration.format) + TCR.cassette = Cassette.get_cassette(name, configuration.recording_format) yield TCR.cassette.save TCR.cassette = nil diff --git a/lib/tcr/cassette.rb b/lib/tcr/cassette.rb index e1eb4cf..7f2796a 100644 --- a/lib/tcr/cassette.rb +++ b/lib/tcr/cassette.rb @@ -35,10 +35,10 @@ def save end end - def self.get_cassette(name, format) - if format == :json + def self.get_cassette(name, recording_format) + if recording_format == :json JSONCassette.new(name) - elsif format == :yaml + elsif recording_format == :yaml YAMLCassette.new(name) else raise TCR::FormatError.new diff --git a/lib/tcr/configuration.rb b/lib/tcr/configuration.rb index 2471e96..1d642b4 100644 --- a/lib/tcr/configuration.rb +++ b/lib/tcr/configuration.rb @@ -1,6 +1,6 @@ module TCR class Configuration - attr_accessor :cassette_library_dir, :hook_tcp_ports, :block_for_reads, :format + attr_accessor :cassette_library_dir, :hook_tcp_ports, :block_for_reads, :recording_format def initialize reset_defaults! @@ -10,7 +10,7 @@ def reset_defaults! @cassette_library_dir = "fixtures/tcr_cassettes" @hook_tcp_ports = [] @block_for_reads = false - @format = :json + @recording_format = :json end end end diff --git a/spec/tcr_spec.rb b/spec/tcr_spec.rb index 1f6ac37..e9f438a 100644 --- a/spec/tcr_spec.rb +++ b/spec/tcr_spec.rb @@ -26,7 +26,7 @@ end it "defaults to JSON" do - TCR.configuration.format.should == :json + TCR.configuration.recording_format.should == :json end end @@ -39,8 +39,8 @@ it "configures cassette format" do expect { - TCR.configure { |c| c.format = :yaml } - }.to change{ TCR.configuration.format }.from(:json).to(:yaml) + TCR.configure { |c| c.recording_format = :yaml } + }.to change{ TCR.configuration.recording_format }.from(:json).to(:yaml) end it "configures tcp ports to hook" do @@ -297,7 +297,7 @@ before(:each) do TCR.configure do |c| - c.format = :json + c.recording_format = :json end end @@ -309,7 +309,7 @@ before(:each) do TCR.configure do |c| - c.format = :yaml + c.recording_format = :yaml end end @@ -319,7 +319,7 @@ describe "an invalid format cassette" do before(:each) do TCR.configure do |c| - c.format = :foobar + c.recording_format = :foobar end end From 74324951c67126fa3976eb753b42b4390ba13449 Mon Sep 17 00:00:00 2001 From: Richard Smiley Date: Sat, 7 Feb 2015 21:26:18 -0500 Subject: [PATCH 07/18] since we default to JSON, no need to specify JSON format in tests --- spec/tcr_spec.rb | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/spec/tcr_spec.rb b/spec/tcr_spec.rb index e9f438a..9624531 100644 --- a/spec/tcr_spec.rb +++ b/spec/tcr_spec.rb @@ -294,12 +294,7 @@ describe "a JSON cassette" do let(:test_file_name) { "test.json" } - - before(:each) do - TCR.configure do |c| - c.recording_format = :json - end - end + # we default to JSON so no need to specify recording_format it_behaves_like "a cassette" end From a6626bfa97027b154333bf4a6c5407d158cb0c6f Mon Sep 17 00:00:00 2001 From: Richard Smiley Date: Sat, 7 Feb 2015 21:37:29 -0500 Subject: [PATCH 08/18] use web servers for testing instead of smtp --- spec/tcr_spec.rb | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/spec/tcr_spec.rb b/spec/tcr_spec.rb index 9624531..62f23f7 100644 --- a/spec/tcr_spec.rb +++ b/spec/tcr_spec.rb @@ -151,22 +151,25 @@ end it "creates a cassette file on use" do + TCR.configure { |c| c.hook_tcp_ports = [25] } expect { TCR.use_cassette("test") do - tcp_socket = TCPSocket.open("aspmx.l.google.com", 25) + tcp_socket = TCPSocket.open("google.com", 80) end }.to change{ File.exists?(test_file_name) }.from(false).to(true) end it "records the tcp session data into the file" do + TCR.configure { |c| c.hook_tcp_ports = [80] } TCR.use_cassette("test") do - tcp_socket = TCPSocket.open("aspmx.l.google.com", 25) + tcp_socket = TCPSocket.open("google.com", 80) io = Net::InternetMessageIO.new(tcp_socket) + io.write("GET /\n") line = io.readline tcp_socket.close end cassette_contents = File.open(test_file_name) { |f| f.read } - cassette_contents.include?("220 mx.google.com ESMTP").should == true + cassette_contents.include?("HTTP/1.0 200 OK").should == true end it "plays back tcp sessions without opening a real connection" do @@ -228,15 +231,14 @@ context "multiple connections" do it "records multiple sessions per cassette" do + TCR.configure { |c| c.hook_tcp_ports = [80] } TCR.use_cassette("test") do - smtp = Net::SMTP.start("aspmx.l.google.com", 25) - smtp.finish - smtp = Net::SMTP.start("mta6.am0.yahoodns.net", 25) - smtp.finish + Net::HTTP.get("google.com", "/") + Net::HTTP.get("yahoo.com", "/") end cassette_contents = File.open(test_file_name) { |f| f.read } - cassette_contents.include?("google.com ESMTP").should == true - cassette_contents.include?("yahoo.com ESMTP").should == true + cassette_contents.include?("Host: google.com").should == true + cassette_contents.include?("Host: yahoo.com").should == true end it "plays back multiple sessions per cassette in order" do From 110b99c01f38498e7971a450710ebbabadfb834d Mon Sep 17 00:00:00 2001 From: Richard Smiley Date: Sat, 7 Feb 2015 21:43:34 -0500 Subject: [PATCH 09/18] update the README to point to a web server --- README.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index bba2d39..eff117f 100644 --- a/README.md +++ b/README.md @@ -33,28 +33,31 @@ require 'tcr' TCR.configure do |c| c.cassette_library_dir = 'fixtures/tcr_cassettes' - c.hook_tcp_ports = [25] + c.hook_tcp_ports = [80] end class TCRTest < Test::Unit::TestCase def test_example_dot_com - TCR.use_cassette('google_smtp') do - tcp_socket = TCPSocket.open("aspmx.l.google.com", 25) - io = Net::InternetMessageIO.new(tcp_socket) - assert_match /220 mx.google.com ESMTP/, io.readline + TCR.use_cassette('google') do + data = Net::HTTP.get("google.com", "/") + assert_match /301 Moved/, data end end end ``` -Run this test once, and TCR will record the tcp interactions to fixtures/tcr_cassettes/google_smtp.json. +Run this test once, and TCR will record the tcp interactions to fixtures/tcr_cassettes/google.json. ```json [ [ + [ + "write", + "GET / HTTP/1.1\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nHost: google.com\r\n\r\n" + ], [ "read", - "220 mx.google.com ESMTP x3si2474860qas.18 - gsmtp\r\n" + "HTTP/1.1 301 Moved Permanently\r\nLocation: http://www.google.com/\r\nContent-Type: text/html; charset=UTF-8\r\nDate: Sun, 08 Feb 2015 02:42:29 GMT\r\nExpires: Tue, 10 Mar 2015 02:42:29 GMT\r\nCache-Control: public, max-age=2592000\r\nServer: gws\r\nContent-Length: 219\r\nX-XSS-Protection: 1; mode=block\r\nX-Frame-Options: SAMEORIGIN\r\nAlternate-Protocol: 80:quic,p=0.02\r\n\r\n\n301 Moved\n

301 Moved

\nThe document has moved\nhere.\r\n\r\n" ] ] ] @@ -66,7 +69,7 @@ You can disable TCR hooking TCPSocket ports for a given block via `turned_off`: ```ruby TCR.turned_off do - tcp_socket = TCPSocket.open("aspmx.l.google.com", 25) + data = Net::HTTP.get("google.com", "/") end ``` From 04de3143eace72793cdf53408435a60386640269 Mon Sep 17 00:00:00 2001 From: Richard Smiley Date: Sat, 7 Feb 2015 21:48:11 -0500 Subject: [PATCH 10/18] add in the old readme example --- README.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/README.md b/README.md index eff117f..2980c98 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,41 @@ TCR.turned_off do end ``` +You can use TCR to record any TCP interaction. Here we record the handshake with an SMTP server. **Note that many residential ISPs block port 25 outbound, so this may not work for you.** + +```ruby +require 'test/unit' +require 'tcr' + +TCR.configure do |c| + c.cassette_library_dir = 'fixtures/tcr_cassettes' + c.hook_tcp_ports = [25] +end + +class TCRTest < Test::Unit::TestCase + def test_example_dot_com + TCR.use_cassette('google_smtp') do + tcp_socket = TCPSocket.open("aspmx.l.google.com", 25) + io = Net::InternetMessageIO.new(tcp_socket) + assert_match /220 mx.google.com ESMTP/, io.readline + end + end +end +``` + +TCR will record the tcp interactions to fixtures/tcr_cassettes/google_smtp.json. + +```json +[ + [ + [ + "read", + "220 mx.google.com ESMTP x3si2474860qas.18 - gsmtp\r\n" + ] + ] +] +``` + ## Contributing 1. Fork it From 9e2e2dba8884be1c4883f3809c39fa266436435d Mon Sep 17 00:00:00 2001 From: Richard Smiley Date: Sat, 7 Feb 2015 21:49:32 -0500 Subject: [PATCH 11/18] headers --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 2980c98..cec75cc 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ Or install it yourself as: ## Usage +### HTTP ```ruby require 'test/unit' require 'tcr' @@ -73,6 +74,7 @@ TCR.turned_off do end ``` +### SMTP You can use TCR to record any TCP interaction. Here we record the handshake with an SMTP server. **Note that many residential ISPs block port 25 outbound, so this may not work for you.** ```ruby From 07472d6f2e0b0dc1bf842dee5ed36d6f4e22b5bf Mon Sep 17 00:00:00 2001 From: Richard Smiley Date: Sat, 7 Feb 2015 21:58:20 -0500 Subject: [PATCH 12/18] add a configuration section --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index cec75cc..364aa11 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,13 @@ TCR will record the tcp interactions to fixtures/tcr_cassettes/google_smtp.json. ] ``` +## Configuration +TCR accepts the following configuration parameters: +* **cassette_library_directory**: the directory, relative to your current directory, to save and read recordings from +* **hook_tcp_ports**: the TCP ports that will be intercepted for recording and playback +* **block_for_reads**: when reading data from a cassette, whether TCR should wait for matching "write" data to be written to the socket before allowing a read +* **recording_format**: the format of the cassettes. Can be either :json or :yaml + ## Contributing 1. Fork it From aa7b2a96186df34ba7def6cd3239531abff82566 Mon Sep 17 00:00:00 2001 From: Richard Smiley Date: Sat, 7 Feb 2015 21:59:58 -0500 Subject: [PATCH 13/18] SMTP example isn't a full handshake --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 364aa11..1928f28 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ end ``` ### SMTP -You can use TCR to record any TCP interaction. Here we record the handshake with an SMTP server. **Note that many residential ISPs block port 25 outbound, so this may not work for you.** +You can use TCR to record any TCP interaction. Here we record the start of an SMTP session. **Note that many residential ISPs block port 25 outbound, so this may not work for you.** ```ruby require 'test/unit' From b967bd73e718b8167ca0b199157cdb369792e047 Mon Sep 17 00:00:00 2001 From: Richard Smiley Date: Sat, 7 Feb 2015 22:25:10 -0500 Subject: [PATCH 14/18] let's add in bson too --- README.md | 2 +- lib/tcr.rb | 1 + lib/tcr/cassette.rb | 18 ++++++++++++++++++ spec/fixtures/block_for_reads.bson | Bin 0 -> 83 bytes spec/fixtures/google_https.bson | Bin 0 -> 13171 bytes spec/fixtures/google_imap.bson | Bin 0 -> 1290 bytes spec/fixtures/google_smtp.bson | Bin 0 -> 92 bytes spec/fixtures/multitest-smtp.bson | Bin 0 -> 759 bytes spec/fixtures/multitest.bson | Bin 0 -> 191 bytes spec/fixtures/starwars_telnet.bson | Bin 0 -> 91 bytes spec/tcr_spec.rb | 12 ++++++++++++ tcr.gemspec | 1 + 12 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 spec/fixtures/block_for_reads.bson create mode 100644 spec/fixtures/google_https.bson create mode 100644 spec/fixtures/google_imap.bson create mode 100644 spec/fixtures/google_smtp.bson create mode 100644 spec/fixtures/multitest-smtp.bson create mode 100644 spec/fixtures/multitest.bson create mode 100644 spec/fixtures/starwars_telnet.bson diff --git a/README.md b/README.md index 1928f28..05d5bc1 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ TCR accepts the following configuration parameters: * **cassette_library_directory**: the directory, relative to your current directory, to save and read recordings from * **hook_tcp_ports**: the TCP ports that will be intercepted for recording and playback * **block_for_reads**: when reading data from a cassette, whether TCR should wait for matching "write" data to be written to the socket before allowing a read -* **recording_format**: the format of the cassettes. Can be either :json or :yaml +* **recording_format**: the format of the cassettes. Can be :json, :yaml, or :bson ## Contributing diff --git a/lib/tcr.rb b/lib/tcr.rb index 03457f7..d6e1353 100644 --- a/lib/tcr.rb +++ b/lib/tcr.rb @@ -6,6 +6,7 @@ require "socket" require "json" require "yaml" +require "bson" module TCR diff --git a/lib/tcr/cassette.rb b/lib/tcr/cassette.rb index 7f2796a..861cd9c 100644 --- a/lib/tcr/cassette.rb +++ b/lib/tcr/cassette.rb @@ -40,6 +40,8 @@ def self.get_cassette(name, recording_format) JSONCassette.new(name) elsif recording_format == :yaml YAMLCassette.new(name) + elsif recording_format == :bson + BSONCassette.new(name) else raise TCR::FormatError.new end @@ -77,4 +79,20 @@ def filename "#{TCR.configuration.cassette_library_dir}/#{name}.yaml" end end + + class BSONCassette < Cassette + def parse + Array.from_bson(StringIO.new(@contents)) + end + + def dump + @sessions.to_bson + end + + protected + + def filename + "#{TCR.configuration.cassette_library_dir}/#{name}.bson" + end + end end diff --git a/spec/fixtures/block_for_reads.bson b/spec/fixtures/block_for_reads.bson new file mode 100644 index 0000000000000000000000000000000000000000..a5651dadc42441ef303520e4dc7e545f6c2864c6 GIT binary patch literal 83 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 literal 0 HcmV?d00001 diff --git a/spec/fixtures/google_imap.bson b/spec/fixtures/google_imap.bson new file mode 100644 index 0000000000000000000000000000000000000000..1274a9136b6295cc18a88d0e37d20dcbf5df1065 GIT binary patch literal 1290 zcmaJ>+iuf95M70fM5PKLAznab1VywF3A=8brb0+K_BOHbt+rF8YJ%jZ+s0Dj1lzrR z1E0ZVC6#g+5JD=H;0H-XbV@3W7`U&3`yD#*G@65i zZ{Tc};_l~#$np%%(%BStl{#zI71pXN3M6W4dV+gORjMjC<9K}yRT$YS>7U|qmBzV{ z{Lk^j@3oI8r3@^$V>%eBkk>0hD~JJ}?vT$bPG2E*B9i)S5?_jM;yRknC!(H+9B(up z!!xgzh_ljb3RYv_%50v=*X^ zd@PbY9!0r0g{|OXG!j|1T?p)vYANtvk6-*%P=NO}+jKZu%IJe_VT`<8K_;0^r|tG7 zgYs}!*bc$oEsnH>P!-U#P5@g2Ey=D#ij@rZC(-%2+!$$emg6EOLY6oP1Qx&PjpJ+_ zC+D!~%<{XBvTW8U-pRt#`BdnjqsJciZO!3Mcq_U+1SyumT%^-DN0EAAA5+Pf<$T}Y z^I+=_HOn;QEU}@SgbXgDNql#`Nj@%LmoKae3T>kGI8#BXv`aoLhprc)6nw5@vSnb4 zw3h>Amy5r`G3MalT!O07#t=L-G9F3O5^JUNCgvsi5}E)2 literal 0 HcmV?d00001 diff --git a/spec/fixtures/multitest-smtp.bson b/spec/fixtures/multitest-smtp.bson new file mode 100644 index 0000000000000000000000000000000000000000..28cadca52cea3b7c85b887d6ca96ea94ad09e4f1 GIT binary patch literal 759 zcmbVJT~C8B6s?ON$&x+z59+INOUD1Jv>2pD^*S`f349 zw#={iblcn0bI(2Jtp&g~1}|H6F#!NA40c4x0&fOd1jyn{DTc`sg`9_RfP9`n-7#Go z&eS}jOreBn3ok;1GT4P-o)q_;w%{Y+u;JSk^W zhHDz8{sC}%W7i!z^$qIQpl6-yeaG#&6X$%?*TsX_LISW6wzkEd=v__>w}vnLqFzul!nmfX&U%N#M58gtL&RLsa$Q6pVs6emBJ&kqM^i#ViYb2D!n=9 zD-lf{k%pb|W%+3rtdcGN6VTnJj%x2Zpl@}2X?&FoBN~%1!;Sm4Ve3P~GOUZgo33r@ OIjDUhKloD71Mm)85uafI literal 0 HcmV?d00001 diff --git a/spec/fixtures/multitest.bson b/spec/fixtures/multitest.bson new file mode 100644 index 0000000000000000000000000000000000000000..17c39ccf9952e5dbae3e2233469f0ef9e21f3ceb GIT binary patch literal 191 zcmdnbz`(#_zz_nVe1H^_0Rt Date: Sat, 7 Feb 2015 22:34:59 -0500 Subject: [PATCH 15/18] sure let's add the messagepack format too --- README.md | 2 +- lib/tcr.rb | 1 + lib/tcr/cassette.rb | 18 ++++++++++++++++++ spec/fixtures/block_for_reads.msgpack | 2 ++ spec/fixtures/google_https.msgpack | Bin 0 -> 12950 bytes spec/fixtures/google_imap.msgpack | Bin 0 -> 828 bytes spec/fixtures/google_smtp.msgpack | Bin 0 -> 62 bytes spec/fixtures/multitest-smtp.msgpack | Bin 0 -> 543 bytes spec/fixtures/multitest.msgpack | Bin 0 -> 135 bytes spec/fixtures/starwars_telnet.msgpack | Bin 0 -> 61 bytes spec/tcr_spec.rb | 12 ++++++++++++ tcr.gemspec | 1 + 12 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 spec/fixtures/block_for_reads.msgpack create mode 100644 spec/fixtures/google_https.msgpack create mode 100644 spec/fixtures/google_imap.msgpack create mode 100644 spec/fixtures/google_smtp.msgpack create mode 100644 spec/fixtures/multitest-smtp.msgpack create mode 100644 spec/fixtures/multitest.msgpack create mode 100644 spec/fixtures/starwars_telnet.msgpack diff --git a/README.md b/README.md index 05d5bc1..77a8453 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ TCR accepts the following configuration parameters: * **cassette_library_directory**: the directory, relative to your current directory, to save and read recordings from * **hook_tcp_ports**: the TCP ports that will be intercepted for recording and playback * **block_for_reads**: when reading data from a cassette, whether TCR should wait for matching "write" data to be written to the socket before allowing a read -* **recording_format**: the format of the cassettes. Can be :json, :yaml, or :bson +* **recording_format**: the format of the cassettes. Can be :json, :yaml, :bson, or :msgpack ## Contributing diff --git a/lib/tcr.rb b/lib/tcr.rb index d6e1353..d10272c 100644 --- a/lib/tcr.rb +++ b/lib/tcr.rb @@ -7,6 +7,7 @@ require "json" require "yaml" require "bson" +require "msgpack" module TCR diff --git a/lib/tcr/cassette.rb b/lib/tcr/cassette.rb index 861cd9c..17d8c8f 100644 --- a/lib/tcr/cassette.rb +++ b/lib/tcr/cassette.rb @@ -42,6 +42,8 @@ def self.get_cassette(name, recording_format) YAMLCassette.new(name) elsif recording_format == :bson BSONCassette.new(name) + elsif recording_format == :msgpack + MsgpackCassette.new(name) else raise TCR::FormatError.new end @@ -95,4 +97,20 @@ def filename "#{TCR.configuration.cassette_library_dir}/#{name}.bson" end end + + class MsgpackCassette < Cassette + def parse + MessagePack.unpack(@contents) + end + + def dump + @sessions.to_msgpack + end + + protected + + def filename + "#{TCR.configuration.cassette_library_dir}/#{name}.msgpack" + end + end end diff --git a/spec/fixtures/block_for_reads.msgpack b/spec/fixtures/block_for_reads.msgpack new file mode 100644 index 0000000..c328465 --- /dev/null +++ b/spec/fixtures/block_for_reads.msgpack @@ -0,0 +1,2 @@ +‘’’¥write¦hello +’¤read§world! diff --git a/spec/fixtures/google_https.msgpack b/spec/fixtures/google_https.msgpack new file mode 100644 index 0000000000000000000000000000000000000000..37270dc08bf2ea01e2ef51861cd6340b504510c6 GIT binary patch literal 12950 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 literal 0 HcmV?d00001 diff --git a/spec/fixtures/multitest-smtp.msgpack b/spec/fixtures/multitest-smtp.msgpack new file mode 100644 index 0000000000000000000000000000000000000000..097ace6c06e7e1910b5ccfeb63f9635f5ce7308e GIT binary patch literal 543 zcmaLT-A=+V6bEpxNqC3z0Me{o=e8?@&`1*)!<7p)UNmDFO}16GsqDg+AmI(vYoEub zkqyL;2$wx=&-tIWy?oJ1(pDX?H9e3&_fBGe|Bx(lfgCKNgl z7ioFlZmnLQa#cp}Y%m-{qC=U?by05WyQa^?GCIGT$`UI5kV6sWk1C8#;nt#v5E~I{ zB7A1wwOjS4fZs4MEyp32ZEs7?1s5YeV!H>TdnLp$XimVqLD%cCejvJH8uZ3}wz=4) zdz(zT_|D`Kf`K3d84xDAP+1J2&ax;hmClZCySF-TtV)S3+eN8V35pjORdTNN54h`K zW8~+0S$!=FHFdQQc93n-upR9GFGuY~u}e*Z8e0>e`)tTP?p^LD{-J=HB0Vza6HuM0 AcK`qY literal 0 HcmV?d00001 diff --git a/spec/fixtures/multitest.msgpack b/spec/fixtures/multitest.msgpack new file mode 100644 index 0000000000000000000000000000000000000000..66f8cb85131ef50507cf4011df49db5fb18d030b GIT binary patch literal 135 zcmbOTyV|yV9h0oh6V Date: Sun, 8 Feb 2015 15:21:20 -0500 Subject: [PATCH 16/18] handle binary encoding in BSON --- lib/tcr/cassette.rb | 22 +++++++++++++++++++--- spec/fixtures/block_for_reads.bson | Bin 83 -> 83 bytes spec/fixtures/google_https.bson | Bin 13171 -> 13171 bytes spec/fixtures/google_imap.bson | Bin 1290 -> 1290 bytes spec/fixtures/google_smtp.bson | Bin 92 -> 92 bytes spec/fixtures/multitest-smtp.bson | Bin 759 -> 759 bytes spec/fixtures/multitest.bson | Bin 191 -> 191 bytes spec/fixtures/starwars_telnet.bson | Bin 91 -> 91 bytes 8 files changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/tcr/cassette.rb b/lib/tcr/cassette.rb index 17d8c8f..f003e3a 100644 --- a/lib/tcr/cassette.rb +++ b/lib/tcr/cassette.rb @@ -84,15 +84,31 @@ def filename class BSONCassette < Cassette def parse - Array.from_bson(StringIO.new(@contents)) + data = Array.from_bson(StringIO.new(@contents)) + self.class.debinaryize(data) end def dump - @sessions.to_bson + self.class.binaryize(@sessions).to_bson end - protected + def self.binaryize(data) + if Array === data + data.map { |item| binaryize(item) } + elsif String === data + BSON::Binary.new(data) + end + end + def self.debinaryize(data) + if Array === data + data.map { |item| debinaryize(item) } + elsif BSON::Binary === data + data.data + end + end + + protected def filename "#{TCR.configuration.cassette_library_dir}/#{name}.bson" end diff --git a/spec/fixtures/block_for_reads.bson b/spec/fixtures/block_for_reads.bson index a5651dadc42441ef303520e4dc7e545f6c2864c6..558158a12d69359b740276b7a1c491d97d0ee75a 100644 GIT binary patch literal 83 zcmWG$U|?V|VDN@e3P6h0fPocAF_af&mZY*8GO&R-8L2rr`CJSvh71Zo9#9DjNVF(5 TF$JiC9mForFUm<#WC#HY10`8N zl0~VBDL^@ER)&pN>{umPjBv{z84Sd6htGcat{WS`BvS%H5cBhU~N?5Z~35&+v_ zibL8^3@mMiL%Ks6ENzZM`o02K+5(5PnHpHy5{GoJwjHY!FmMbQ7BOLjP8ZYWrv`mY Gj0^zBpE=tA diff --git a/spec/fixtures/google_imap.bson b/spec/fixtures/google_imap.bson index 1274a9136b6295cc18a88d0e37d20dcbf5df1065..2d7fe3d0b1c7236cba2e4da09981884f6c48ffb2 100644 GIT binary patch literal 1290 zcmaJ>+iuf95FM&iLKPq$;0X{TR74w;U^{V|3L)Xx+r+AGwcRRJ6C^j;HkJ}6*zWBY z_zixP*|Pdcva5MIhDrkydj9x-w{Mi9C_Sp%l|dQVi@h9BiBnW*yL258YMhlm}Xpesg; z(M3MtNgj`)oR4uUxEPIimTe1yU8oiW_jdg94ugWMui2)EKf?S{wwNn&0#$ zaW;vQbKG?1`QMLa+j0|(GSBCNhbDUBG2hl4=7hJT+d~v&87_D_i*q8Wi}A@Sd@bV$ zbrw(XgjRo~S*9VhBoBoWGQ5nY@ojnwK9$p#FRY4+)S}Uorh+BY4ty+!J}a0c^qEe@ zE(6=pDF<#Bfuc34!699us!GivdNjy*B!-so>s%CAG`0(^GRnLEC_S^=V?k)UM!*iR zCGDzGV<`9)39NEvLuB4+RuMm^6Q5~D&2_BfAuh#%87)r~QopZIMTS=o@HS+D_6G|3 B`+NWZ literal 1290 zcmaJ>+iuf95M70fM5PKLAznab1VywF3A=8brb0+K_BOHbt+rF8YJ%jZ+s0Dj1lzrR z1E0ZVC6#g+5JD=H;0H-XbV@3W7`U&3`yD#*G@65i zZ{Tc};_l~#$np%%(%BStl{#zI71pXN3M6W4dV+gORjMjC<9K}yRT$YS>7U|qmBzV{ z{Lk^j@3oI8r3@^$V>%eBkk>0hD~JJ}?vT$bPG2E*B9i)S5?_jM;yRknC!(H+9B(up z!!xgzh_ljb3RYv_%50v=*X^ zd@PbY9!0r0g{|OXG!j|1T?p)vYANtvk6-*%P=NO}+jKZu%IJe_VT`<8K_;0^r|tG7 zgYs}!*bc$oEsnH>P!-U#P5@g2Ey=D#ij@rZC(-%2+!$$emg6EOLY6oP1Qx&PjpJ+_ zC+D!~%<{XBvTW8U-pRt#`BdnjqsJciZO!3Mcq_U+1SyumT%^-DN0EAAA5+Pf<$T}Y z^I+=_HOn;QEU}@SgbXgDNql#`Nj@%LmoKae3T>kGI8#BXv`aoLhprc)6nw5@vSnb4 zw3h>Amy5r`G3MalT!O07#t=L-G9F3O5^qf0|jRQ diff --git a/spec/fixtures/multitest-smtp.bson b/spec/fixtures/multitest-smtp.bson index 28cadca52cea3b7c85b887d6ca96ea94ad09e4f1..786a0a8d5512f577757320a06fd4d196d7af368f 100644 GIT binary patch delta 354 zcmey)`khtzI}-x~ivh!AMlj{ez`($2z`z2e7>ZI8Q&r*x z0z*ARK-x_hf*?we-C@ZvIhxT<9_Wxrh+88t)z~vk-ofZhvSYI_O$ua~?7$RCq-!lP M^(!z;zQCjg0I%XV@Bjb+ delta 355 zcmey)`khtjI}-x~ivh!AMlj{ez`(#{z`zQmic%9(7?=zhOeZQ^xH7O9GH5~M*nm`d zQD#XhNKz2UarN-=SIEgvPRz;3FD~Kb0vcq*Fb$#@*`T_K3mUB%Sd1AIAaW=Mu>-{d zLp?*l+D#aOFtuAvj$yQu2RS4X;?@XEH4c+^GCGs)*epzwf+jmMg%aypOHBQWlP@x< HF){!E_og?_ diff --git a/spec/fixtures/multitest.bson b/spec/fixtures/multitest.bson index 17c39ccf9952e5dbae3e2233469f0ef9e21f3ceb..7400eccf780e4504ee98536b4135c56e472e22cb 100644 GIT binary patch delta 78 zcmdnbxSvsZKLY~;ivdFjgz^DWtOg7$K#HL#H8F+NkinQ?qLPI?iy=b-Pz Date: Sun, 8 Feb 2015 15:41:03 -0500 Subject: [PATCH 17/18] spec for binary files --- spec/tcr_spec.rb | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/spec/tcr_spec.rb b/spec/tcr_spec.rb index 3e35d82..0d2bff8 100644 --- a/spec/tcr_spec.rb +++ b/spec/tcr_spec.rb @@ -294,6 +294,31 @@ end end + shared_examples "a binary compatible cassette" do + before(:each) { + TCR.configure { |c| + c.hook_tcp_ports = [25] + c.cassette_library_dir = "." + } + } + + around(:each) do |example| + File.unlink(test_file_name) if File.exists?(test_file_name) + example.run + File.unlink(test_file_name) if File.exists?(test_file_name) + end + + it "handles binary data properly" do + TCR.configure { |c| c.hook_tcp_ports = [80] } + TCR.use_cassette("test") do + uri = URI("http://c.cyberciti.biz/cbzcache/3rdparty/terminal.png") + data = Net::HTTP.get(uri) + end + cassette_contents = File.open(test_file_name) { |f| f.read } + cassette_contents.include?("User-Agent: Ruby").should == true + end + end + describe "a JSON cassette" do let(:test_file_name) { "test.json" } # we default to JSON so no need to specify recording_format @@ -311,6 +336,7 @@ end it_behaves_like "a cassette" + it_behaves_like "a binary compatible cassette" end describe "a BSON cassette" do @@ -323,6 +349,7 @@ end it_behaves_like "a cassette" + it_behaves_like "a binary compatible cassette" end describe "a msgpack cassette" do @@ -335,6 +362,7 @@ end it_behaves_like "a cassette" + it_behaves_like "a binary compatible cassette" end describe "an invalid format cassette" do From 1370b6ef5de533c16955ca886f9dab547a79edd4 Mon Sep 17 00:00:00 2001 From: Richard Smiley Date: Sun, 8 Feb 2015 15:49:03 -0500 Subject: [PATCH 18/18] spec for reading binary data --- spec/fixtures/binary_data.bson | Bin 0 -> 7234 bytes spec/fixtures/binary_data.msgpack | Bin 0 -> 7166 bytes spec/fixtures/binary_data.yaml | 164 ++++++++++++++++++++++++++++++ spec/tcr_spec.rb | 11 +- 4 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 spec/fixtures/binary_data.bson create mode 100644 spec/fixtures/binary_data.msgpack create mode 100644 spec/fixtures/binary_data.yaml diff --git a/spec/fixtures/binary_data.bson b/spec/fixtures/binary_data.bson new file mode 100644 index 0000000000000000000000000000000000000000..c7cc1fca8d1bfb46b4b665c6904e81a71df2bb4e GIT binary patch literal 7234 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 E3j>ncFaQ7m literal 0 HcmV?d00001 diff --git a/spec/fixtures/binary_data.msgpack b/spec/fixtures/binary_data.msgpack new file mode 100644 index 0000000000000000000000000000000000000000..6a3009ef5220e0a0a6db4823d0cf2f4ea860653d GIT binary patch literal 7166 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 Rf`4xST59^LFO}`1{|B?H-O2y} literal 0 HcmV?d00001 diff --git a/spec/fixtures/binary_data.yaml b/spec/fixtures/binary_data.yaml new file mode 100644 index 0000000..c274ef5 --- /dev/null +++ b/spec/fixtures/binary_data.yaml @@ -0,0 +1,164 @@ +--- +- - - write + - "GET /cbzcache/3rdparty/terminal.png HTTP/1.1\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: + */*\r\nUser-Agent: Ruby\r\nHost: c.cyberciti.biz\r\n\r\n" + - - read + - !binary |- + SFRUUC8xLjEgMjAwIE9LDQpDb250ZW50LVR5cGU6IGltYWdlL3BuZw0KQ29u + dGVudC1MZW5ndGg6IDY0NDINCkNvbm5lY3Rpb246IGtlZXAtYWxpdmUNClNl + cnZlcjogbmdpbngNCkRhdGU6IFR1ZSwgMTggTm92IDIwMTQgMDE6Mjk6NDIg + R01UDQpYLVdob206IGwxLW5ldC1pcHY2dA0KRXhwaXJlczogTW9uLCAwNyBO + b3YgMjAxNiAwMToyOTo0MiBHTVQNCkNhY2hlLUNvbnRyb2w6IG1heC1hZ2U9 + NjIyMDgwMDANCkFjY2VwdC1SYW5nZXM6IGJ5dGVzDQpFVGFnOiAiMzEyNzQy + Mzg3OCINCkxhc3QtTW9kaWZpZWQ6IFdlZCwgMTQgSmFuIDIwMDkgMTg6NDc6 + NDAgR01UDQpYLUdhbGF4eTogQW5kcm9tZWRhLTINCkFnZTogNzE1Mzk5NQ0K + WC1DYWNoZTogSGl0IGZyb20gY2xvdWRmcm9udA0KVmlhOiAxLjEgOWYyMTk1 + MmQzM2Q5MTI2Njg5MGYyYWIzNGI4NDlhOWQuY2xvdWRmcm9udC5uZXQgKENs + b3VkRnJvbnQpDQpYLUFtei1DZi1JZDogYlZuVDRxMVQ5RmVkOWx0N3ZCUTZs + dTVRem5ILWJFeE8wYnpISTBYSnhvZk5DUDdsT2JUNGtnPT0NCg0KiVBORw0K + GgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAABmJLR0QA/wD/AP+gvaeT + AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1wEDCh8dT/Hn+AAAGLdJ + REFUeNrtXXtQVOfdfvbs2V12WVhEhMod0Ri0KgpyMVqRYKoNKjZ2HHVs1TaJ + U5OxTSpO800SY61TW6cmf3xt0mha05jUiMkksYTPGDUKCOIFowLWiCA3QQ2w + y8XdZc9+f7hne/bsue+C2p7fzM5ezmXPe57n/d3e3/seQBVVVFFFFVVUUUUV + VVRRRRVVVFFFFVVUUUUVVVRRRZX/WNGI7bB69erpGo1mjUajySMIYqp6yx5M + cblcFymKOjk4OPjuwYMHzwEYAuBWTIBVq1bNIElyF0EQ3zMYDEhNTUV4eDji + 4+PvSwPdbvd/NcBC7W9ra4PVakVjYyPsdjuGhoYqu7u7Nx86dKgGgBMAJYcA + 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 + +/ZtHDhwQPD6u7q6EBsbi+XLl6OkpMTr + - - read + - !binary |- + jPHF/7T87ne/Q35+PoB7T0l55pln0NXVhffee8977M6dO7F48WKf/0tOTsb6 + 9etRUFCAwsJC9Pb2+mkAOhyUYgICzQMoNgFsZtLS2dmJjo4OXLt2DcXFxTh4 + 8CA2bdrkpypLS0uxdOlSTJkyBfPmzUNpaSl0Oh3Wrl3r3WfevHkAgB07dmDO + nDnIycnB2rVrcfz4cb9eMnr0aCxbtgxz587Fhx9+CAB48sknRTXAO++8AwB4 + 9tlncfjwYXz88cfYvn07CgsLvd43U3sxTV1hYSGysrKwb98+APeWdKf3X758 + ORYvXoyWlhasX78e6enpeOSRR1BYWIiamhqMHz8ev/jFLzg7EF+n4ivECSQT + SCiNAqRUBun1ejz22GMoLCz0s3kvvPACGhoa4HK50NXVhW3btnk1AX0T6d44 + c+ZMrFq1CpmZmaivr8fmzZv9CPD73/8e7e3tcDqd2Lt3r7e3iRHg888/x3PP + PYfy8nIMDg4iPj4e8+fPx5YtW/Dee+8hKiqKU1X/9re/RVtbGxwOB3bv3g3g + 3mLO9H4/+tGPAAC//OUvcfToUfT19cHlcqGurg7PPfccAGDBggWC9p7P6R6W + sYBgmYD4+Hjv40pTUlJQXFyMrVu3wmAwYO/evd7yszVr1mDRokVITk72WVmE + vuEajQY7duzA1q1bkZ+f71W3LS0tKC4uRlNTk8//NjU1eY+jH2ppNBoFZyTR + N+fChQuora0FQRBISEjA1KlTsWrVKowfPx4bN27Eli1b/CKBxsZGrxdPE5X2 + deg8AQCUlJTw/n9cXBynE8hnAvgSXgFHAYEUhbAbQH+nKArXr1/HSy+9BAD4 + 6U9/6t1/8+bNKC4uRlpamt+yMvTzbjUaDU6ePIknn3wSmzdvxgcffICuri4k + JCTg17/+tZ8GYEcCSqID4N5U7EOHDuGFF14AAD/HlD2ELKSuxYQ2MVJNAJcT + eF/mBgpdLNtW0T0wMjLS+9uSJUsAAJs2bUJlZSUGBgZgNptx8uRJvxDLbrfj + xIkTOHnyJN5//3189tlnmDRpkt+NY9YY8OUH5BSBDAwM+PRqtgZgJ4LYv1+7 + dg2TJ0/GkiVLcPXqVZ80MfMz+/qYHUhqscuI5gG48txcbNVqtUhNTfXa9qtX + r3q30Q+pdjqdcDqdiI+Px8svv+zXa19//XVkZ2fDZDIhNDQUc+bM8Q68iPV0 + qRrgT3/6E4qKipCUlASDwQC9Xo+JEyfi1Vdf9WoEKedl32jaEf3zn/+MoqIi + jB07FjqdDgaDASkpKVixYgUOHjwoyQnkSrXLHQsQTQUrGXfmuliup4U6nU78 + 8Y9/9F58ZWUl8vPz8frrr3v3oXs/87y5ubnIzc31O9+JEyeCpgHS0tJ4Vzp1 + uVx45513RDUAV6r3008/xaOPPooVK1Zg+/btoo60kA/ABJ9vUGjY8wBCoQXX + TXa5XLhz5w7OnTuHPXv2eGN7giCwdetWuN1uzJo1C0NDQzh+/Dh27dqFo0eP + +vSujRs3YtmyZZg2bRpMJhNu3bqFY8eO4d133+W1nezGihFgw4YNePzxx5Ge + no64uDhotVr09PSgrq4OBw4cwOXLlwUJwOewEQSBP/zhDzh+/DiWLVuGqVOn + IjIyEi6XC62traipqcFHH33EOYAl9JtSHyCg0UAh8OlXSkoKb5EI+91qtaK4 + uNgvu5Wbm+tz/Pnz51FbWytYfvbEE09wZskWLlwouvSN2+1GY2MjGhsbeYd8 + aaDp9s6bN8/7O3P8ftasWV5PndlTa2pqUF1dzVkqTh9PURRSU1N9yERRFGJj + Y/0Gc5T4AJJGA+WCz/Z4pRSCSikeCaR8TElxi9x6f75xfnYxB/szM5PHJA9X + eCenHG5YowCxmTFcJOACVAh8PuClEkGsWCSQejo5w718gLPB5gKd6zcpQ+By + wZelAcRWxuCr4ZOiEeRUE4mRYTgIIFTpKzasywaajwS0mucjAnufEdUAcleg + ljIBROq7FOLcTxPA5fGL9Xa+8jW+6xarhwi6DyDEKCXgS1XfUv0CrhhYqiZg + X6+UMjAhLSBW0ctHAj7Vz6UJ5E6VCyQUFJ0dLLYYgpJJIlL9gmD4Auz2CRGA + r+KXy/ETquANpr0X0gCBgi/ZBChV/3JAlEqIYPkCSmb7cmkCMXvPBzrzN6kE + 4Krvk2P7RU2AkiVH5Fb5SskTyI0MlPgCQnP+pTp+Uuy9GBGYM4jZtYZcbRV6 + LIxQ1CYrESQGfmRkJCIiIvD0009j6dKlvDc8kOXepHyW8l3pGIdYBCR1/UCp + PpWcjsd8frCU/5EVBkq5EL1eD5IkYTab/Z5orcrIiVySSR4LECNBc3Mz2tvb + eQc3+BZxGKkbIrXXKlkJLBjfhfZjzg7m2y8+Ph7x8fGw2+2SwZc0PVyqDxAX + F4fY2FjZN/V+vD8M16jk3Wq1Sm6rkBbw1gO0tbVxzo1/mN//U8GX29aIiAgf + fP0I4HA4OqxWK2cJtAr+w91WrVYLi8UCq9WKvr4+KwCKTQB3f3//WdqmM0MS + FfyHv62jR48GALS3t6O9vb3NQwAKnmd6EQBc7e3tR202G65fv+5NT6rgP/xt + JUkSSUlJuH79Omw2G+rq6v4F4C4AJ+491AUEgKG33nqrtL+/v6m8vNynkFMF + /+Fu67hx4xASEoLy8nLcvn3726NHj14E0AdgEMCQlwAABqqqqv7XZrOhoqLC + ZyKkCv6D1UapbY2JicF3vvMdVFRUwGaz4Z///OdJAL0AvgUwQBNA67EFREND + Q3dqamoMRVGPhoeHIzo62ruGrwr+w9NGkiQxfvx4JCcn48qVK6iqqsKpU6dq + y8rKTgFoBtAEoMujBdw0AQCAOH36dOOkSZMe7enpiXM4HEhKSgJJkt4iTxX8 + B7uNMTExSEtLQ0REBCoqKlBVVYW6urpvdu/e/QWAVgCNnvdejx/gXVdZCyAU + QByAic8+++yG9PT0grCwMGRmZmLixIk+6/ayV7sWU1lyt8vJnSvdN5jb71cb + tVotQkNDYTabYbFYQJIkrly5gjNnzsBms6G8vPzCvn37TnhA/xeAKwDaAPTT + TiAzM6ADYAEQD2D89OnTZy9atOip2NjYeL1ej5SUFISFhWHs2LFqEv4Bk46O + DtBRnMPhQGtra2dJScmphoaGJgAdnp7/Dbv3swmgAaAHEA4gFkAygMSpU6dO + zcnJmZmUlBQ/mg4qVXng5NatW93Nzc03y8vLrzQ0NNBAdwK44bH77QCsABwM + s++3tD5NAjOAMR4ijAUQ7dEOJs92Asoe0aPKMI2DeZI7Do+H3+tx9Do8wN/y + hH8+4IMHRI1nkMjo0QaRAEZ73sM8v5MIcGaxKkEVyhPWDQKweUK9O553KyPu + d3OBLTRQpAMQ4un5Zg/4Oo/TqGqAB0sDuDy2fdDT2wcYWT/epUalgEhrBNID + PqH2/gdWC1AewIf4erwqqqiiiiqqqKKKKqqooooqqqiiiiqqqKKKKqqo8t8l + /w8NO4Xb+BTdJAAAAABJRU5ErkJggg== diff --git a/spec/tcr_spec.rb b/spec/tcr_spec.rb index 0d2bff8..ae35a11 100644 --- a/spec/tcr_spec.rb +++ b/spec/tcr_spec.rb @@ -308,7 +308,7 @@ File.unlink(test_file_name) if File.exists?(test_file_name) end - it "handles binary data properly" do + it "handles recording binary data properly" do TCR.configure { |c| c.hook_tcp_ports = [80] } TCR.use_cassette("test") do uri = URI("http://c.cyberciti.biz/cbzcache/3rdparty/terminal.png") @@ -317,6 +317,15 @@ cassette_contents = File.open(test_file_name) { |f| f.read } cassette_contents.include?("User-Agent: Ruby").should == true end + + it "handles reading binary data properly" do + TCR.configure { |c| c.hook_tcp_ports = [80] } + TCR.use_cassette("spec/fixtures/binary_data") do + uri = URI("http://c.cyberciti.biz/cbzcache/3rdparty/terminal.png") + data = Net::HTTP.get(uri) + data.include?("PNG").should == true + end + end end describe "a JSON cassette" do