Skip to content

Instantly share code, notes, and snippets.

@macedo
Created April 16, 2015 14:06
Show Gist options
  • Save macedo/96bb5d288118b6f54629 to your computer and use it in GitHub Desktop.
Save macedo/96bb5d288118b6f54629 to your computer and use it in GitHub Desktop.
Request Recorder
module Recorder
module Config
class << self
attr_accessor :records_path
end
end
def self.config
yield Config
end
def self.use_record(record_file, &block)
Recorder::Base.new(record_file, &block).run
end
class Base
def initialize(record_file, &block)
@record_file = record_file
if File.exists?("#{Config.records_path}/#{@record_file}")
@record = File.read("#{Config.records_path}/#{@record_file}")
end
@spec = block
end
def run
@record ? read_record : write_record
end
private
def read_record
record = @record
TCPSocket.class_eval do
alias :original_initialize :initialize
define_method :initialize do |*args|
end
end
OpenSSL::SSL::SSLSocket.class_eval do
alias :original_initialize :initialize
alias :original_read :read
alias :original_write :write
alias :original_connect :connect
define_method :initialize do |*args|
end
define_method :write do |*args|
end
define_method :connect do |*args|
end
define_method :read do |*args|
record
end
end
@spec.call
TCPSocket.class_eval do
alias :initialize :original_initialize
end
OpenSSL::SSL::SSLSocket.class_eval do
alias :initialize :original_initialize
alias :read :original_read
alias :write :original_write
alias :connect :original_connect
end
end
def write_record
path = @record_file.split('/')[0]
record_file = @record_file
FileUtils.mkdir_p File.join("#{Config.records_path}/#{path}")
OpenSSL::SSL::SSLSocket.class_eval do
alias :original_read :read
define_method :read do |*args|
response = self.original_read(*args)
File.open "#{Config.records_path}/#{record_file}", 'w+' do |f|
f.write response.force_encoding('UTF-8')
end
response
end
end
@spec.call
OpenSSL::SSL::SSLSocket.class_eval do
alias :read :original_read
end
end
end
end
Recorder.config do |config|
config.records_path = File.join(Rails.root, 'spec', 'records')
end
RSpec.configure do |c|
c.treat_symbols_as_metadata_keys_with_true_values = true
c.around(:each, :record) do |spec|
record_file = spec.metadata[:full_description].split(/\s+/, 2).join("/").gsub(/[^\w\/]+/, "_")
Recorder.use_record(record_file) { spec.call }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment