tcr 0.2.0 → 0.2.1

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: d304ca968d1155919b181710a474dd9a98a4f269
4
- data.tar.gz: 67e7387321ce706d2b7dc1651bcbdc825ae682d1
3
+ metadata.gz: 228eadaf6c734a9281952492ab146d7fee17e246
4
+ data.tar.gz: 64045b81372a13b4d957ea02bd266b5c7c443d3a
5
5
  SHA512:
6
- metadata.gz: 051e136095dcd34c387d7638124bd453b6ba7134ea06bf784e1501fb04fe2c7d1f1ed11bd64a3edae17dd9bcea54f241be985901bf958cf1652aa129df9bffae
7
- data.tar.gz: e9ffe3fc3379731f11a78ed2fb017480a8372d1ff2563019df12f704e9780e61c8ef5392ebe0057cb91b05940c7b5d7d820f492a161fd351d12ad541b1f652ae
6
+ metadata.gz: 1210aebd2ec013acb28546caeae5b29022e8cd7ddee1cb9e7814140c86d6e8fcc351798b10b2d2637baf104b7617719d3f28001bb3cde4cfee4821fa697625a5
7
+ data.tar.gz: d05fc665286ace6c2b77c6f30890aff288e872344da943a2f5c09afcf468c8c7b82acbabff10f227092fc6322aabbbf9cf82a0c10cdc758b07e004533110d84f
data/lib/tcr/cassette.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require 'fileutils'
2
+
1
3
  module TCR
2
4
  class Cassette
3
5
  attr_reader :name
@@ -5,18 +7,16 @@ module TCR
5
7
  def initialize(name)
6
8
  @name = name
7
9
 
8
- if File.exists?(filename)
9
- @recording = false
10
- @contents = File.open(filename) { |f| f.read }
11
- @sessions = unmarshal(@contents)
12
- else
13
- @recording = true
10
+ if recording?
11
+ verify_cassette_path_is_writable
14
12
  @sessions = []
13
+ else
14
+ @sessions = unmarshal(File.read(filename))
15
15
  end
16
16
  end
17
17
 
18
18
  def recording?
19
- @recording
19
+ @recording ||= !File.exists?(filename)
20
20
  end
21
21
 
22
22
  def next_session
@@ -30,9 +30,10 @@ module TCR
30
30
  end
31
31
 
32
32
  def save
33
- if recording?
34
- File.open(filename, "w") { |f| f.write(marshal(@sessions)) }
35
- end
33
+ return if !recording?
34
+ File.write(filename, marshal(@sessions))
35
+ rescue Encoding::UndefinedConversionError
36
+ File.binwrite(filename, marshal(@sessions))
36
37
  end
37
38
 
38
39
  def check_hits_all_sessions
@@ -52,7 +53,8 @@ module TCR
52
53
  when "marshal"
53
54
  Marshal.load(content)
54
55
  else
55
- raise RuntimeError.new "unrecognized format #{TCR.configuration.format}, please use `json` or `yaml`"
56
+ raise "unrecognized cassette format '#{TCR.configuration.format}'; " \
57
+ "please use one of 'json', 'yaml', or 'marshal'"
56
58
  end
57
59
  end
58
60
 
@@ -65,12 +67,18 @@ module TCR
65
67
  when "marshal"
66
68
  Marshal.dump(content)
67
69
  else
68
- raise RuntimeError.new "unrecognized format #{TCR.configuration.format}, please use `json` or `yaml`"
70
+ raise "unrecognized cassette format '#{TCR.configuration.format}'; " \
71
+ "please use one of 'json', 'yaml', or 'marshal'"
69
72
  end
70
73
  end
71
74
 
72
75
  def filename
73
76
  "#{TCR.configuration.cassette_library_dir}/#{name}.#{TCR.configuration.format}"
74
77
  end
78
+
79
+ def verify_cassette_path_is_writable
80
+ FileUtils.mkdir_p(File.dirname(filename))
81
+ FileUtils.touch(filename)
82
+ end
75
83
  end
76
84
  end
data/lib/tcr/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module TCR
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
data/spec/tcr_spec.rb CHANGED
@@ -6,11 +6,10 @@ require "net/imap"
6
6
  require "net/smtp"
7
7
  require "net/ldap"
8
8
  require "tcr/net/ldap"
9
- require 'thread'
10
9
  require "mail"
11
10
 
12
11
 
13
- describe TCR do
12
+ RSpec.describe TCR do
14
13
  before(:each) do
15
14
  TCR.configuration.reset_defaults!
16
15
  end
@@ -37,44 +36,44 @@ describe TCR do
37
36
  it "defaults to erroring on read/write mismatch access" do
38
37
  TCR.configuration.block_for_reads.should be_falsey
39
38
  end
40
-
39
+
41
40
  it "defaults to hit all to false" do
42
41
  TCR.configuration.hit_all.should be_falsey
43
42
  end
44
43
  end
45
44
 
46
- describe ".configure" 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
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")
50
+ end
52
51
 
53
- it "configures tcp ports to hook" do
54
- expect {
55
- TCR.configure { |c| c.hook_tcp_ports = [2525] }
56
- }.to change{ TCR.configuration.hook_tcp_ports }.from([]).to([2525])
57
- end
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])
56
+ end
58
57
 
59
- it "configures allowing a blocking read mode" do
60
- expect {
61
- TCR.configure { |c| c.block_for_reads = true }
62
- }.to change{ TCR.configuration.block_for_reads }.from(false).to(true)
63
- end
64
-
65
- it "configures to check if all sesstions was hit" do
66
- expect {
67
- TCR.configure { |c| c.hit_all = true }
68
- }.to change{ TCR.configuration.hit_all }.from(false).to(true)
69
- end
70
- end
58
+ it "configures allowing a blocking read mode" do
59
+ expect {
60
+ TCR.configure { |c| c.block_for_reads = true }
61
+ }.to change{ TCR.configuration.block_for_reads }.from(false).to(true)
62
+ end
71
63
 
72
- it "raises an error if you connect to a hooked port without using a cassette" do
73
- TCR.configure { |c| c.hook_tcp_ports = [2525] }
74
- expect {
75
- tcp_socket = TCPSocket.open("smtp.mandrillapp.com", 2525)
76
- }.to raise_error(TCR::NoCassetteError)
77
- end
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)
68
+ end
69
+ end
70
+
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)
76
+ end
78
77
 
79
78
  describe ".turned_off" do
80
79
  it "requires a block to call" do
@@ -151,6 +150,44 @@ describe TCR do
151
150
  }.to raise_error(ArgumentError)
152
151
  end
153
152
 
153
+ context "when path to cassette does not exist" do
154
+ let(:unique_dirname) { Dir.entries(".").sort.last.next }
155
+
156
+ around do |example|
157
+ expect(Dir.exist?(unique_dirname)).to be(false)
158
+ example.run
159
+ FileUtils.rm_rf(unique_dirname)
160
+ end
161
+
162
+ it "creates it" do
163
+ expect { TCR.use_cassette("#{unique_dirname}/foo/bar/test") { } }.not_to raise_error
164
+ end
165
+ end
166
+
167
+ context "when path to cassette is not writable" do
168
+ let(:unique_dirname) { Dir.entries(".").sort.last.next }
169
+
170
+ around do |example|
171
+ FileUtils.mkdir(unique_dirname)
172
+ FileUtils.chmod("u-w", unique_dirname)
173
+ expect { FileUtils.touch("#{unique_dirname}/foo") }.to raise_error(Errno::EACCES)
174
+ example.run
175
+ FileUtils.rm_rf(unique_dirname)
176
+ end
177
+
178
+ it "raises error BEFORE block runs" do
179
+ allow(TCPSocket).to receive(:open)
180
+
181
+ expect do
182
+ TCR.use_cassette("#{unique_dirname}/foo") do
183
+ TCPSocket.open("smtp.mandrillapp.com", 2525)
184
+ end
185
+ end.to raise_error(Errno::EACCES)
186
+
187
+ expect(TCPSocket).not_to have_received(:open)
188
+ end
189
+ end
190
+
154
191
  it "resets the cassette after use" do
155
192
  expect(TCR.cassette).to be_nil
156
193
  TCR.use_cassette("test") { }
@@ -165,57 +202,86 @@ describe TCR do
165
202
  expect(TCR.cassette).to be_nil
166
203
  end
167
204
 
168
- it "creates a cassette file on use" do
169
- expect {
205
+ context "when configured for JSON format" do
206
+ it "creates a cassette file on use" do
207
+ expect {
208
+ TCR.use_cassette("test") do
209
+ tcp_socket = TCPSocket.open("smtp.mandrillapp.com", 2525)
210
+ end
211
+ }.to change{ File.exists?("./test.json") }.from(false).to(true)
212
+ end
213
+
214
+ it "records the tcp session data into the file" do
170
215
  TCR.use_cassette("test") do
171
216
  tcp_socket = TCPSocket.open("smtp.mandrillapp.com", 2525)
217
+ io = Net::InternetMessageIO.new(tcp_socket)
218
+ line = io.readline
219
+ tcp_socket.close
172
220
  end
173
- }.to change{ File.exists?("./test.json") }.from(false).to(true)
221
+ cassette_contents = File.open("test.json") { |f| f.read }
222
+ cassette_contents.include?("220 smtp.mandrillapp.com ESMTP").should == true
223
+ end
174
224
  end
175
225
 
176
- it "creates a cassette file on use with yaml" do
177
- TCR.configure { |c| c.format = "yaml" }
226
+ context "when configured for YAML format" do
227
+ before { TCR.configure { |c| c.format = "yaml" } }
178
228
 
179
- expect {
229
+ it "creates a cassette file on use with yaml" do
230
+ expect {
231
+ TCR.use_cassette("test") do
232
+ tcp_socket = TCPSocket.open("smtp.mandrillapp.com", 2525)
233
+ end
234
+ }.to change{ File.exists?("./test.yaml") }.from(false).to(true)
235
+ end
236
+
237
+ it "records the tcp session data into the yaml file" do
180
238
  TCR.use_cassette("test") do
181
239
  tcp_socket = TCPSocket.open("smtp.mandrillapp.com", 2525)
240
+ io = Net::InternetMessageIO.new(tcp_socket)
241
+ line = io.readline
242
+ tcp_socket.close
182
243
  end
183
- }.to change{ File.exists?("./test.yaml") }.from(false).to(true)
244
+ cassette_contents = File.open("test.yaml") { |f| f.read }
245
+ cassette_contents.include?("---").should == true
246
+ cassette_contents.include?("220 smtp.mandrillapp.com ESMTP").should == true
247
+ end
184
248
  end
185
249
 
186
- it "creates a cassette file on use with marshal" do
187
- TCR.configure { |c| c.format = "marshal" }
250
+ context "when configured for Marshal format" do
251
+ before { TCR.configure { |c| c.format = "marshal" } }
188
252
 
189
- expect {
253
+ it "creates a cassette file on use with marshal" do
254
+ expect {
255
+ TCR.use_cassette("test") do
256
+ tcp_socket = TCPSocket.open("smtp.mandrillapp.com", 2525)
257
+ end
258
+ }.to change{ File.exists?("./test.marshal") }.from(false).to(true)
259
+ end
260
+
261
+ it "records the tcp session data into the marshalled file" do
190
262
  TCR.use_cassette("test") do
191
263
  tcp_socket = TCPSocket.open("smtp.mandrillapp.com", 2525)
264
+ io = Net::InternetMessageIO.new(tcp_socket)
265
+ line = io.readline
266
+ tcp_socket.close
192
267
  end
193
- }.to change{ File.exists?("./test.marshal") }.from(false).to(true)
194
- end
195
-
196
- it "records the tcp session data into the file" do
197
- TCR.use_cassette("test") do
198
- tcp_socket = TCPSocket.open("smtp.mandrillapp.com", 2525)
199
- io = Net::InternetMessageIO.new(tcp_socket)
200
- line = io.readline
201
- tcp_socket.close
268
+ unmarshalled_cassette = Marshal.load(File.read("test.marshal"))
269
+ expect(unmarshalled_cassette).to be_a(Array)
270
+ expect(unmarshalled_cassette.first.last.last).to eq("220 smtp.mandrillapp.com ESMTP\r\n")
202
271
  end
203
- cassette_contents = File.open("test.json") { |f| f.read }
204
- cassette_contents.include?("220 smtp.mandrillapp.com ESMTP").should == true
205
- end
206
272
 
207
- it "records the tcp session data into the yaml file" do
208
- TCR.configure { |c| c.format = "yaml" }
273
+ context "when Encoding.default_internal == Encoding::UTF_8 (as in Rails)" do
274
+ before { Encoding.default_internal = Encoding::UTF_8 }
275
+ let(:invalid_unicode_string) { "\u0001\u0001\u0004€" }
209
276
 
210
- TCR.use_cassette("test") do
211
- tcp_socket = TCPSocket.open("smtp.mandrillapp.com", 2525)
212
- io = Net::InternetMessageIO.new(tcp_socket)
213
- line = io.readline
214
- tcp_socket.close
277
+ it "doesn't fail on cassettes with binary content" do
278
+ expect do
279
+ TCR.use_cassette("test") do
280
+ TCR.cassette.instance_variable_get(:@sessions) << ["read", invalid_unicode_string]
281
+ end
282
+ end.not_to raise_error
283
+ end
215
284
  end
216
- cassette_contents = File.open("test.yaml") { |f| f.read }
217
- cassette_contents.include?("---").should == true
218
- cassette_contents.include?("220 smtp.mandrillapp.com ESMTP").should == true
219
285
  end
220
286
 
221
287
  it "plays back tcp sessions without opening a real connection" do
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.0
4
+ version: 0.2.1
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-08-21 00:00:00.000000000 Z
11
+ date: 2018-09-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec