tcr 0.2.0 → 0.2.1

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: 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