tcr 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 228eadaf6c734a9281952492ab146d7fee17e246
4
- data.tar.gz: 64045b81372a13b4d957ea02bd266b5c7c443d3a
3
+ metadata.gz: 6c3b335b522930e2cda40cc99bacc68109e13189
4
+ data.tar.gz: 25d3fe32caf69278fc4753763e1c1ba84640a5c1
5
5
  SHA512:
6
- metadata.gz: 1210aebd2ec013acb28546caeae5b29022e8cd7ddee1cb9e7814140c86d6e8fcc351798b10b2d2637baf104b7617719d3f28001bb3cde4cfee4821fa697625a5
7
- data.tar.gz: d05fc665286ace6c2b77c6f30890aff288e872344da943a2f5c09afcf468c8c7b82acbabff10f227092fc6322aabbbf9cf82a0c10cdc758b07e004533110d84f
6
+ metadata.gz: ee2afda4d4a575fee8d988d12a56b1bfe27f30dac317776232fddc019499addec91348d8c3545fbf0cccdfef0c3153b5016f66a21e8767d9e7b345fe1f7f59f9
7
+ data.tar.gz: 7cc411a8feb6d80c3ee2b4541141d90e0d47845853474a69255a6b0773b683d1b2e417dc7539013adb059c5d5abc94464b4825a2e3948b2ebd212747886dfc98
data/lib/tcr.rb CHANGED
@@ -88,11 +88,11 @@ class Socket
88
88
  class << self
89
89
  alias_method :real_tcp, :tcp
90
90
 
91
- def tcp(host, port, socket_opts)
91
+ def tcp(host, port, *socket_opts)
92
92
  if TCR.configuration.hook_tcp_ports.include?(port)
93
93
  TCR::RecordableTCPSocket.new(host, port, TCR.cassette)
94
94
  else
95
- real_tcp(host, port, socket_opts)
95
+ real_tcp(host, port, *socket_opts)
96
96
  end
97
97
  end
98
98
  end
@@ -5,22 +5,26 @@ require 'thread'
5
5
 
6
6
  module TCR
7
7
  class RecordableTCPSocket
8
- attr_reader :live, :socket
9
- attr_accessor :recording
8
+ attr_reader :live, :socket, :recording
10
9
 
11
10
  def initialize(address, port, cassette)
12
11
  raise TCR::NoCassetteError.new unless TCR.cassette
13
12
 
14
13
  @read_lock = Queue.new
14
+ @recording = cassette.next_session
15
+ @live = cassette.recording?
15
16
 
16
- if cassette.recording?
17
- @live = true
18
- @socket = TCPSocket.real_open(address, port)
17
+ if live
18
+ begin
19
+ @socket = TCPSocket.real_open(address, port)
20
+ rescue => e
21
+ recording << ["error", Marshal.dump(e)]
22
+ raise
23
+ end
19
24
  else
20
- @live = false
21
25
  @closed = false
26
+ check_recording_for_errors
22
27
  end
23
- @recording = cassette.next_session
24
28
  end
25
29
 
26
30
  def read(bytes)
@@ -75,6 +79,10 @@ module TCR
75
79
 
76
80
  private
77
81
 
82
+ def check_recording_for_errors
83
+ raise Marshal.load(recording.first.last) if recording.first.first == "error"
84
+ end
85
+
78
86
  def _intercept_socket
79
87
  if @socket
80
88
  @socket = yield @socket
@@ -1,3 +1,3 @@
1
1
  module TCR
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.2"
3
3
  end
@@ -25,54 +25,91 @@ RSpec.describe TCR do
25
25
  end
26
26
 
27
27
  describe ".configuration" do
28
- it "has a default cassette location configured" do
29
- TCR.configuration.cassette_library_dir.should == "fixtures/tcr_cassettes"
30
- end
28
+ it "has a default cassette location configured" do
29
+ TCR.configuration.cassette_library_dir.should == "fixtures/tcr_cassettes"
30
+ end
31
31
 
32
- it "has an empty list of hook ports by default" do
33
- TCR.configuration.hook_tcp_ports.should == []
34
- end
32
+ it "has an empty list of hook ports by default" do
33
+ TCR.configuration.hook_tcp_ports.should == []
34
+ end
35
35
 
36
- it "defaults to erroring on read/write mismatch access" do
37
- TCR.configuration.block_for_reads.should be_falsey
38
- end
36
+ it "defaults to erroring on read/write mismatch access" do
37
+ TCR.configuration.block_for_reads.should be_falsey
38
+ end
39
39
 
40
- it "defaults to hit all to false" do
41
- TCR.configuration.hit_all.should be_falsey
42
- end
43
- end
40
+ it "defaults to hit all to false" do
41
+ TCR.configuration.hit_all.should be_falsey
42
+ end
43
+ end
44
44
 
45
45
  describe ".configure" do
46
- it "configures cassette location" do
47
- expect {
48
- TCR.configure { |c| c.cassette_library_dir = "some/dir" }
49
- }.to change{ TCR.configuration.cassette_library_dir }.from("fixtures/tcr_cassettes").to("some/dir")
46
+ context "with cassette_library_dir option" do
47
+ it "configures cassette location" do
48
+ expect {
49
+ TCR.configure { |c| c.cassette_library_dir = "some/dir" }
50
+ }.to change{ TCR.configuration.cassette_library_dir }.from("fixtures/tcr_cassettes").to("some/dir")
51
+ end
50
52
  end
51
53
 
52
- it "configures tcp ports to hook" do
53
- expect {
54
- TCR.configure { |c| c.hook_tcp_ports = [2525] }
55
- }.to change{ TCR.configuration.hook_tcp_ports }.from([]).to([2525])
54
+ context "with hook_tcp_ports option" do
55
+ it "configures tcp ports to hook" do
56
+ expect {
57
+ TCR.configure { |c| c.hook_tcp_ports = [2525] }
58
+ }.to change{ TCR.configuration.hook_tcp_ports }.from([]).to([2525])
59
+ end
56
60
  end
57
61
 
58
- it "configures allowing a blocking read mode" do
59
- expect {
62
+ context "with block_for_reads option" do
63
+ before(:each) {
64
+ TCR.configure { |c|
65
+ c.hook_tcp_ports = [9999]
66
+ c.cassette_library_dir = '.'
67
+ }
68
+ }
69
+
70
+ it "configures allowing a blocking read mode" do
71
+ expect {
72
+ TCR.configure { |c| c.block_for_reads = true }
73
+ }.to change{ TCR.configuration.block_for_reads }.from(false).to(true)
74
+ end
75
+
76
+ it "blocks read thread until data is available instead of raising mismatch error" do
60
77
  TCR.configure { |c| c.block_for_reads = true }
61
- }.to change{ TCR.configuration.block_for_reads }.from(false).to(true)
62
- end
78
+ reads = Queue.new
63
79
 
64
- it "configures to check if all sesstions was hit" do
65
- expect {
66
- TCR.configure { |c| c.hit_all = true }
67
- }.to change{ TCR.configuration.hit_all }.from(false).to(true)
80
+ TCR.use_cassette("spec/fixtures/block_for_reads") do
81
+ sock = TCPSocket.open("google.com", 9999)
82
+
83
+ t = Thread.new do
84
+ reads << sock.gets
85
+ end
86
+
87
+ expect(reads.size).to eq(0)
88
+ sock.print("hello\n")
89
+ t.value
90
+ expect(reads.size).to eq(1)
91
+ end
92
+ end
93
+
94
+ context "when disabled" do
95
+ it "raises mismatch error" do
96
+ TCR.use_cassette("spec/fixtures/block_for_reads") do
97
+ sock = TCPSocket.open("google.com", 9999)
98
+ expect {
99
+ Timeout::timeout(1) { sock.gets }
100
+ }.to raise_error(TCR::DirectionMismatchError)
101
+ end
102
+ end
103
+ end
68
104
  end
69
- end
70
105
 
71
- it "raises an error if you connect to a hooked port without using a cassette" do
72
- TCR.configure { |c| c.hook_tcp_ports = [2525] }
73
- expect {
74
- tcp_socket = TCPSocket.open("smtp.mandrillapp.com", 2525)
75
- }.to raise_error(TCR::NoCassetteError)
106
+ context "with hit_all option" do
107
+ it "configures to check if all sessions were hit" do
108
+ expect {
109
+ TCR.configure { |c| c.hit_all = true }
110
+ }.to change{ TCR.configuration.hit_all }.from(false).to(true)
111
+ end
112
+ end
76
113
  end
77
114
 
78
115
  describe ".turned_off" do
@@ -98,44 +135,6 @@ RSpec.describe TCR do
98
135
  end
99
136
  end
100
137
 
101
- describe "block_for_reads" do
102
- before(:each) {
103
- TCR.configure { |c|
104
- c.hook_tcp_ports = [9999]
105
- c.cassette_library_dir = '.'
106
- }
107
- }
108
-
109
- it "blocks read thread until data is available instead of raising mismatch error" do
110
- TCR.configure { |c| c.block_for_reads = true }
111
- reads = Queue.new
112
-
113
- TCR.use_cassette("spec/fixtures/block_for_reads") do
114
- sock = TCPSocket.open("google.com", 9999)
115
-
116
- t = Thread.new do
117
- reads << sock.gets
118
- end
119
-
120
- expect(reads.size).to eq(0)
121
- sock.print("hello\n")
122
- t.value
123
- expect(reads.size).to eq(1)
124
- end
125
- end
126
-
127
- context "when disabled" do
128
- it "raises mismatch error" do
129
- TCR.use_cassette("spec/fixtures/block_for_reads") do
130
- sock = TCPSocket.open("google.com", 9999)
131
- expect {
132
- Timeout::timeout(1) { sock.gets }
133
- }.to raise_error(TCR::DirectionMismatchError)
134
- end
135
- end
136
- end
137
- end
138
-
139
138
  describe ".use_cassette" do
140
139
  before(:each) {
141
140
  TCR.configure { |c|
@@ -144,6 +143,13 @@ RSpec.describe TCR do
144
143
  }
145
144
  }
146
145
 
146
+ it "MUST be used when connecting to hooked ports (or else raises an error)" do
147
+ TCR.configure { |c| c.hook_tcp_ports = [2525] }
148
+ expect {
149
+ tcp_socket = TCPSocket.open("smtp.mandrillapp.com", 2525)
150
+ }.to raise_error(TCR::NoCassetteError)
151
+ end
152
+
147
153
  it "requires a block to call" do
148
154
  expect {
149
155
  TCR.use_cassette("test")
@@ -433,6 +439,32 @@ RSpec.describe TCR do
433
439
  end
434
440
  end
435
441
 
442
+ context "when TCPSocket.open raises an error during recording" do
443
+ before do
444
+ TCR.configure { |c|
445
+ c.format = "yaml" # JSON borks on binary strings
446
+ c.hook_tcp_ports = [143]
447
+ c.cassette_library_dir = "."
448
+ }
449
+
450
+ # record cassette
451
+ TCR.use_cassette("test") do
452
+ expect { Net::IMAP.new(nil) }.to raise_error(SystemCallError)
453
+ end
454
+ end
455
+
456
+ it "records error to cassette" do
457
+ expect(File.exist?('test.yaml')).to be(true)
458
+ expect(File.read('test.yaml')).not_to be_empty
459
+ end
460
+
461
+ it "re-raises the error during replay" do
462
+ TCR.use_cassette("test") do
463
+ expect { Net::IMAP.new(nil) }.to raise_error(SystemCallError)
464
+ end
465
+ end
466
+ end
467
+
436
468
  it "replaces sockets created with Socket.tcp" do
437
469
  TCR.configure { |c|
438
470
  c.hook_tcp_ports = [23]
@@ -440,7 +472,7 @@ RSpec.describe TCR do
440
472
  }
441
473
 
442
474
  TCR.use_cassette("test") do
443
- sock = Socket.tcp("towel.blinkenlights.nl", 23, {})
475
+ sock = Socket.tcp("towel.blinkenlights.nl", 23)
444
476
  expect(sock).to be_a(TCR::RecordableTCPSocket)
445
477
  end
446
478
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tcr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rob Forman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-09-20 00:00:00.000000000 Z
11
+ date: 2018-10-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec