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 +4 -4
- data/lib/tcr/cassette.rb +20 -12
- data/lib/tcr/version.rb +1 -1
- data/spec/tcr_spec.rb +130 -64
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 228eadaf6c734a9281952492ab146d7fee17e246
|
4
|
+
data.tar.gz: 64045b81372a13b4d957ea02bd266b5c7c443d3a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
9
|
-
|
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
|
-
|
35
|
-
|
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
|
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
|
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
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
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
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
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
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
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
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
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
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
|
-
|
169
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
194
|
-
|
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
|
-
|
208
|
-
|
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
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
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.
|
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-
|
11
|
+
date: 2018-09-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|