tcr 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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