http_vanilli 0.0.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.
@@ -0,0 +1,105 @@
1
+ require 'addressable/uri'
2
+ require 'rack'
3
+ require 'pp'
4
+
5
+ class Object
6
+ def tapp(tag=nil)
7
+ print "#{tag}=" if tag
8
+ pp self
9
+ self
10
+ end
11
+ end
12
+
13
+ class AngryWeb
14
+ class ValueMatcher
15
+ attr_reader :mismatch_reason
16
+ def initialize(value)
17
+ @mismatch_reason = "<no reason>"
18
+ @value = value
19
+ end
20
+ end
21
+
22
+ class HashSubsetMatcher < ValueMatcher
23
+ def match?(params)
24
+ @value.keys.all? do |k|
25
+ match = @value[k]
26
+ param = params[k.to_s]
27
+
28
+ case match
29
+ when Regexp
30
+ !! param[match]
31
+ else
32
+ match == param
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ class REMatcher < ValueMatcher
39
+ def match?(other)
40
+ other.to_s.match(@value)
41
+ end
42
+ end
43
+
44
+ class EqlMatcher < ValueMatcher
45
+ def match?(other)
46
+ @value == other
47
+ end
48
+ end
49
+
50
+ class Matcher
51
+ attr_reader :mismatches
52
+
53
+ def initialize(&blk)
54
+ @parts = {}
55
+ yield self
56
+ end
57
+
58
+ def match?(uri)
59
+ uri = Addressable::URI.heuristic_parse(uri)
60
+ uri_hash = uri.to_hash
61
+
62
+ @mismatches = []
63
+
64
+ @parts.each {|k,v|
65
+ unless v.match?(__transform_value_from_uri(uri_hash,k))
66
+ @mismatches << v.mismatch_reason
67
+ end
68
+ }
69
+
70
+ @mismatches.empty?
71
+ end
72
+
73
+ def hash_subset(spec)
74
+ HashSubsetMatcher.new(spec)
75
+ end
76
+
77
+ def method_missing(meth,*args,&block)
78
+ if args.size == 1
79
+ @parts[meth] = __convert_value(args.first)
80
+ else
81
+ super
82
+ end
83
+ end
84
+
85
+ def __convert_value(value)
86
+ case value
87
+ when ValueMatcher
88
+ value
89
+ when Regexp
90
+ REMatcher.new(value)
91
+ else
92
+ EqlMatcher.new(value)
93
+ end
94
+ end
95
+
96
+ def __transform_value_from_uri(uri,key)
97
+ case key
98
+ when :params
99
+ Rack::Utils.parse_query(uri[:query])
100
+ else
101
+ uri[key]
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,13 @@
1
+ module HttpVanilli
2
+ module AbstractResponder
3
+ include HttpVanilli::NetHttp::YieldResponse
4
+
5
+ def response_for_request(request)
6
+ code,headers,body = rack_response(request)
7
+
8
+ response = HttpVanilli::NetHttp::Response.new(code,headers,body)
9
+
10
+ nh_yield_response(response,request)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,60 @@
1
+ require 'addressable/uri'
2
+
3
+ module HttpVanilli
4
+ class BasicMapper
5
+ attr_accessor :responder
6
+
7
+ def initialize(extra_responders = {})
8
+ responder_classes.update(extra_responders)
9
+ end
10
+
11
+ def responder_classes
12
+ @responder_classes ||= {
13
+ :block => HttpVanilli::Responders::Block,
14
+ :rack => HttpVanilli::Responders::Rack
15
+ }
16
+ end
17
+
18
+ def responders; @responders ||= [] end
19
+
20
+ def add_block_responder(*args,&block)
21
+ responders << responder_classes[:block].new(*args,&block)
22
+ end
23
+
24
+ def add_rack_responder(*args,&block)
25
+ responders << responder_classes[:rack].new(*args,&block)
26
+ end
27
+
28
+ def add_responder(kind,*args,&block)
29
+ responders << responder_classes[kind].new(*args,&block)
30
+ end
31
+
32
+ ## Mapping API
33
+
34
+ # Take the info from the innards of Net::HTTP and build a request.
35
+ def build_request(kind,http,request,&block)
36
+ HttpVanilli::Request.build(kind,http,request,&block)
37
+ end
38
+
39
+ # Should we map the request?
40
+ def map_request?(request)
41
+ !! find_responder(request)
42
+ end
43
+
44
+ # Map the request
45
+ def map_request(request)
46
+ find_responder(request).response_for_request(request)
47
+ end
48
+
49
+ # The request wasn't matched and normal net connection was disallowed.
50
+ def unmapped_request(request)
51
+ raise "unmatched_request #{request}"
52
+ end
53
+
54
+ protected
55
+
56
+ def find_responder(request)
57
+ responders.find {|responder| responder.match?(request)}
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,22 @@
1
+ require 'addressable/uri'
2
+
3
+ module Unused
4
+ class BasicMapping
5
+ include HttpVanilli::NetHttp::YieldResponse
6
+
7
+ def initialize(method,url,&block)
8
+ @method = method
9
+ @url = Addressable::URI.heuristic_parse(url)
10
+ @block = block
11
+ end
12
+
13
+ def match?(request)
14
+ (request.host == @url.host)
15
+ end
16
+
17
+ def rack_response
18
+ @block[request]
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,88 @@
1
+ require 'http_vanilli/net_http/stubs'
2
+ require 'http_vanilli/net_http/util'
3
+ require 'http_vanilli/net_http/request'
4
+ require 'http_vanilli/net_http/response'
5
+ require 'net/http'
6
+ require 'net/https'
7
+ require 'stringio'
8
+
9
+ module HttpVanilli
10
+ module NetHttp
11
+ def self.override!
12
+ record_loaded_net_http_replacement_libs
13
+ puts_warning_for_net_http_around_advice_libs_if_needed
14
+ end
15
+ end
16
+ end
17
+
18
+ module Net #:nodoc: all
19
+ class BufferedIO
20
+ def initialize_with_http_vanilli(io, debug_output = nil)
21
+ @read_timeout = 60
22
+ @rbuf = ''
23
+ @debug_output = debug_output
24
+
25
+ @io = case io
26
+ when Socket, OpenSSL::SSL::SSLSocket, IO
27
+ io
28
+ when String
29
+ if !io.include?("\0") && File.exists?(io) && !File.directory?(io)
30
+ File.open(io, "r")
31
+ else
32
+ StringIO.new(io)
33
+ end
34
+ end
35
+ raise "Unable to create local socket" unless @io
36
+ end
37
+ alias_method :initialize_without_http_vanilli, :initialize
38
+ alias_method :initialize, :initialize_with_http_vanilli
39
+ end
40
+
41
+ class HTTP
42
+ class << self
43
+ def socket_type_with_http_vanilli
44
+ HttpVanilli::NetHttp::StubSocket
45
+ end
46
+ alias_method :socket_type_without_http_vanilli, :socket_type
47
+ alias_method :socket_type, :socket_type_with_http_vanilli
48
+ end
49
+
50
+ def request_with_http_vanilli(request, body = nil, &block)
51
+ mapper = HttpVanilli.request_mapper
52
+
53
+ request.set_body_internal body
54
+
55
+ # Wrap Net::HTTPRequest & associated info in a HttpVanilli::Request
56
+ vanilli_request = mapper.build_request(:net_http, self, request, &block)
57
+
58
+ # The mapper can map the request. Do it.
59
+ if mapper.map_request?(vanilli_request)
60
+ @socket = Net::HTTP.socket_type.new
61
+ mapper.map_request(vanilli_request)
62
+
63
+ # otherwise, either allow the request to happen as normal,
64
+ elsif HttpVanilli.allow_net_connect?
65
+ connect_without_http_vanilli
66
+ request_without_http_vanilli(request, body, &block)
67
+
68
+ # or note the request as unmapped.
69
+ else
70
+ mapper.unmapped_request(vanilli_request)
71
+ end
72
+ end
73
+ alias_method :request_without_http_vanilli, :request
74
+ alias_method :request, :request_with_http_vanilli
75
+
76
+
77
+ def connect_with_http_vanilli
78
+ unless @@alredy_checked_for_net_http_replacement_libs ||= false
79
+ HttpVanilli::NetHttp.puts_warning_for_net_http_replacement_libs_if_needed
80
+ @@alredy_checked_for_net_http_replacement_libs = true
81
+ end
82
+ nil
83
+ end
84
+ alias_method :connect_without_http_vanilli, :connect
85
+ alias_method :connect, :connect_with_http_vanilli
86
+ end
87
+
88
+ end
@@ -0,0 +1,33 @@
1
+ require 'http_vanilli/request'
2
+
3
+ module HttpVanilli
4
+ module NetHttp
5
+ class Request < HttpVanilli::Request
6
+ attr_reader :block, :uri, :method, :original_request
7
+
8
+ def initialize(http,request,&block)
9
+ @http = http
10
+ @original_request = request
11
+ @block = block
12
+
13
+ protocol = http.use_ssl? ? "https" : "http"
14
+
15
+ path = request.path
16
+ path = Addressable::URI.parse(request.path).request_uri if request.path =~ /^https?:/
17
+
18
+ @uri = Addressable::URI.parse( "#{protocol}://#{http.address}:#{http.port}#{path}" )
19
+ @method = request.method.downcase.to_sym
20
+ end
21
+
22
+ def host; @uri.host end
23
+
24
+ def to_s
25
+ "#{@method} #{@uri.to_s}"
26
+ end
27
+
28
+ def body
29
+ @original_request.body
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,37 @@
1
+ module HttpVanilli
2
+ module NetHttp
3
+ module YieldResponse
4
+ def nh_yield_response(response,request)
5
+ nh_rsp = response.to_net_http
6
+ request.block[nh_rsp] if request.block
7
+ nh_rsp
8
+ end
9
+ end
10
+
11
+ class Response < HttpVanilli::Response
12
+ attr_accessor :headers, :body
13
+ attr_reader :code, :message
14
+
15
+ def initialize(code,headers,body,message=StatusMessage[code.to_i])
16
+ @code,@body,@message = code.to_i,body,message
17
+ @headers = headers || {}
18
+ end
19
+
20
+ def body
21
+ @body.join("")
22
+ end
23
+
24
+ def to_net_http
25
+ response = Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, message)
26
+
27
+ response.instance_variable_set(:@body, body) if body
28
+ headers.each { |name, value| response[name] = value }
29
+
30
+ response.instance_variable_set(:@read, true)
31
+ response.extend HttpVanilli::NetHttp::ResponseMixin
32
+
33
+ response
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,25 @@
1
+ module HttpVanilli
2
+ module NetHttp
3
+ class StubSocket #:nodoc:
4
+
5
+ def initialize(*args)
6
+ end
7
+
8
+ def closed?
9
+ @closed ||= true
10
+ end
11
+
12
+ def readuntil(*args)
13
+ end
14
+
15
+ end
16
+
17
+ module ResponseMixin #:nodoc:
18
+ def read_body(*args, &block)
19
+ yield @body if block_given?
20
+ @body
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,36 @@
1
+ module HttpVanilli
2
+ module NetHttp
3
+ def self.puts_warning_for_net_http_around_advice_libs_if_needed
4
+ libs = {"Samuel" => defined?(Samuel)}
5
+ warnings = libs.select { |_, loaded| loaded }.map do |name, _|
6
+ <<-TEXT.gsub(/ {10}/, '')
7
+ \e[1mWarning: HttpVanilli was loaded after #{name}\e[0m
8
+ * #{name}'s code is being ignored when a request is handled by HttpVanilli::NetHttp,
9
+ because both libraries work by patching Net::HTTP.
10
+ * To fix this, just reorder your requires so that HttpVanilli is before #{name}.
11
+ TEXT
12
+ end
13
+ $stderr.puts "\n" + warnings.join("\n") + "\n" if warnings.any?
14
+ end
15
+
16
+ def self.record_loaded_net_http_replacement_libs
17
+ libs = {"RightHttpConnection" => defined?(RightHttpConnection)}
18
+ @loaded_net_http_replacement_libs = libs.map { |name, loaded| name if loaded }.compact
19
+ end
20
+
21
+ def self.puts_warning_for_net_http_replacement_libs_if_needed
22
+ libs = {"RightHttpConnection" => defined?(RightHttpConnection)}
23
+ warnings = libs.select { |_, loaded| loaded }.
24
+ reject { |name, _| @loaded_net_http_replacement_libs.include?(name) }.
25
+ map do |name, _|
26
+ <<-TEXT.gsub(/ {10}/, '')
27
+ \e[1mWarning: #{name} was loaded after HttpVanilli::NetHttp\e[0m
28
+ * HttpVanilli's code is being ignored, because #{name} replaces parts of
29
+ Net::HTTP without deferring to other libraries. This will break Net::HTTP requests.
30
+ * To fix this, just reorder your requires so that #{name} is before HttpVanilli.
31
+ TEXT
32
+ end
33
+ $stderr.puts "\n" + warnings.join("\n") + "\n" if warnings.any?
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,54 @@
1
+ require 'ostruct'
2
+ require 'pp'
3
+
4
+ module HttpVanilli
5
+ class OtherMapper
6
+ def customise_request(&block)
7
+ @customise_request = block
8
+ end
9
+
10
+ # Take the info from the innards of Net::HTTP and build a request.
11
+ def build_request(kind,http,request,body,&block)
12
+ req = OpenStruct.new
13
+ req.block = block
14
+
15
+ pp http
16
+ pp request.to_hash
17
+
18
+ protocol = http.use_ssl? ? "https" : "http"
19
+
20
+ path = request.path
21
+ path = Addressable::URI.parse(request.path).request_uri if request.path =~ /^http/
22
+
23
+ req.uri = Addressable::URI.parse( "#{protocol}://#{http.address}:#{http.port}#{path}" )
24
+ req.method = request.method.downcase.to_sym
25
+
26
+ if @customise_request
27
+ @customise_request[req]
28
+ end
29
+
30
+ req
31
+ end
32
+
33
+ # Should we map the request?
34
+ def map_request?(request)
35
+ true
36
+ end
37
+
38
+ # Map the request
39
+ def map_request(request)
40
+ response = HttpVanilli::NetHttp::Response.new(200,'cool')
41
+ response.body = "boddy"
42
+
43
+ nhrsp = response.to_net_http
44
+ request.block[nhrsp] if request.block
45
+
46
+ nhrsp
47
+ end
48
+
49
+ # The request wasn't matched and normal net connection was disallowed.
50
+ def unmapped_request(request)
51
+ raise "unmatched_request :("
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,12 @@
1
+ module HttpVanilli
2
+ class Request
3
+ def self.build(kind,*args,&block)
4
+ case kind
5
+ when :net_http
6
+ HttpVanilli::NetHttp::Request.new(*args,&block)
7
+ else
8
+ raise "Unknown request kind #{kind}"
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,19 @@
1
+ module HttpVanilli
2
+ module Responders
3
+ class Block
4
+ include HttpVanilli::AbstractResponder
5
+
6
+ def initialize(&block)
7
+ @block = block
8
+ end
9
+
10
+ def match?(request)
11
+ !! @block[request]
12
+ end
13
+
14
+ def rack_response(request)
15
+ @block[request]
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,61 @@
1
+ module HttpVanilli
2
+ module Responders
3
+ class Rack
4
+ include HttpVanilli::AbstractResponder
5
+
6
+ def initialize(app_class,*args,&block)
7
+ @app_class = app_class
8
+ @args = args
9
+ @block = block
10
+ end
11
+
12
+ BadStatus = 999
13
+ def match?(request)
14
+ rsp = rack_response(request)
15
+ Array === rsp && rsp.first != BadStatus
16
+ end
17
+
18
+ def rack_response(request)
19
+ uri = request.uri
20
+
21
+ env = {
22
+ 'REQUEST_METHOD' => request.original_request.method,
23
+
24
+ # this'll to for now
25
+ 'SCRIPT_NAME' => "",
26
+ 'PATH_INFO' => uri.path,
27
+
28
+ 'QUERY_STRING' => uri.query,
29
+ 'SERVER_NAME' => uri.host,
30
+ 'SERVER_PORT' => uri.port
31
+ }
32
+
33
+ request.original_request.each_header {|k,v|
34
+ env["HTTP_#{k.upcase}"] = v
35
+ }
36
+
37
+ rack_input = StringIO.new((request.body || '').to_s)
38
+ rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding)
39
+
40
+ env.update({"rack.version" => [1,1],
41
+ "rack.input" => rack_input,
42
+ "rack.errors" => $stderr,
43
+
44
+ "rack.multithread" => true,
45
+ "rack.multiprocess" => false,
46
+ "rack.run_once" => false,
47
+
48
+ "rack.url_scheme" => request.uri.scheme
49
+ })
50
+
51
+ app.call(env)
52
+ end
53
+
54
+ def app
55
+ inner_app = lambda {|l| [BadStatus,{'Content-Type' => 'text/plain'},['']]}
56
+ @app_class.new(inner_app,*@args,&@block)
57
+ end
58
+ end
59
+ end
60
+ end
61
+
@@ -0,0 +1,6 @@
1
+ module HttpVanilli
2
+ module Responders
3
+ autoload :Block, 'http_vanilli/responders/block'
4
+ autoload :Rack , 'http_vanilli/responders/rack'
5
+ end
6
+ end
@@ -0,0 +1,46 @@
1
+ module HttpVanilli
2
+ class Response
3
+ StatusMessage = {
4
+ 100, 'Continue',
5
+ 101, 'Switching Protocols',
6
+ 200, 'OK',
7
+ 201, 'Created',
8
+ 202, 'Accepted',
9
+ 203, 'Non-Authoritative Information',
10
+ 204, 'No Content',
11
+ 205, 'Reset Content',
12
+ 206, 'Partial Content',
13
+ 300, 'Multiple Choices',
14
+ 301, 'Moved Permanently',
15
+ 302, 'Found',
16
+ 303, 'See Other',
17
+ 304, 'Not Modified',
18
+ 305, 'Use Proxy',
19
+ 307, 'Temporary Redirect',
20
+ 400, 'Bad Request',
21
+ 401, 'Unauthorized',
22
+ 402, 'Payment Required',
23
+ 403, 'Forbidden',
24
+ 404, 'Not Found',
25
+ 405, 'Method Not Allowed',
26
+ 406, 'Not Acceptable',
27
+ 407, 'Proxy Authentication Required',
28
+ 408, 'Request Timeout',
29
+ 409, 'Conflict',
30
+ 410, 'Gone',
31
+ 411, 'Length Required',
32
+ 412, 'Precondition Failed',
33
+ 413, 'Request Entity Too Large',
34
+ 414, 'Request-URI Too Large',
35
+ 415, 'Unsupported Media Type',
36
+ 416, 'Request Range Not Satisfiable',
37
+ 417, 'Expectation Failed',
38
+ 500, 'Internal Server Error',
39
+ 501, 'Not Implemented',
40
+ 502, 'Bad Gateway',
41
+ 503, 'Service Unavailable',
42
+ 504, 'Gateway Timeout',
43
+ 505, 'HTTP Version Not Supported'
44
+ }
45
+ end
46
+ end
@@ -0,0 +1,9 @@
1
+ require 'http_vanilli'
2
+
3
+ module HttpVanilli
4
+ module RSpec
5
+ def stub_web(method, url, &block)
6
+ HttpVanilli.mapper.add_mapping(method,url,&block)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,32 @@
1
+ require 'uri'
2
+
3
+ module HttpVanilli
4
+ class Util
5
+ def self.decode_userinfo_from_header(header)
6
+ header.sub(/^Basic /, "").unpack("m").first
7
+ end
8
+
9
+ def self.encode_unsafe_chars_in_userinfo(userinfo)
10
+ unsafe_in_userinfo = /[^#{URI::REGEXP::PATTERN::UNRESERVED};&=+$,]|^(#{URI::REGEXP::PATTERN::ESCAPED})/
11
+ userinfo.split(":").map { |part| uri_escape(part, unsafe_in_userinfo) }.join(":")
12
+ end
13
+
14
+ def self.strip_default_port_from_uri(uri)
15
+ case uri
16
+ when %r{^http://} then uri.sub(%r{:80(/|$)}, '\1')
17
+ when %r{^https://} then uri.sub(%r{:443(/|$)}, '\1')
18
+ else uri
19
+ end
20
+ end
21
+
22
+ # Wrapper for URI escaping that switches between URI::Parser#escape and
23
+ # URI.escape for 1.9-compatibility
24
+ def self.uri_escape(*args)
25
+ if URI.const_defined?(:Parser)
26
+ URI::Parser.new.escape(*args)
27
+ else
28
+ URI.escape(*args)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,3 @@
1
+ module HttpVanilli
2
+ Version = '0.0.2'
3
+ end
@@ -0,0 +1,62 @@
1
+ require 'pathname'
2
+ require 'pp'
3
+
4
+ class Object
5
+ def tapp(tag=nil)
6
+ print "#{tag}=" if tag
7
+ pp self
8
+ self
9
+ end
10
+ end
11
+
12
+ module HttpVanilli
13
+ autoload :Util , 'http_vanilli/util'
14
+
15
+ autoload :BasicMapper , 'http_vanilli/basic_mapper'
16
+
17
+ autoload :AbstractResponder, 'http_vanilli/abstract_responder'
18
+ autoload :Responders , 'http_vanilli/responders'
19
+
20
+ autoload :Request , 'http_vanilli/request'
21
+ autoload :Response, 'http_vanilli/response'
22
+
23
+ class << self
24
+ def here
25
+ @here ||= Pathname(__FILE__).dirname
26
+ end
27
+
28
+ def override_net_http!
29
+ require here+'http_vanilli/net_http/override'
30
+ HttpVanilli::NetHttp.override!
31
+ end
32
+
33
+ def allow_net_connect!
34
+ @allow_net_connect = true
35
+ end
36
+
37
+ def disallow_net_connect!
38
+ @allow_net_connect = false
39
+ end
40
+
41
+ def allow_net_connect?
42
+ !(FalseClass === @allow_net_connect)
43
+ end
44
+
45
+ def use_basic_mapper!(extra_responder_classes={})
46
+ self.request_mapper = BasicMapper.new(extra_responder_classes)
47
+ end
48
+
49
+ def request_mapper=(request_mapper)
50
+ @request_mapper = request_mapper
51
+ end
52
+
53
+ def request_mapper
54
+ unless @request_mapper
55
+ raise "HttpVanilli requires a request mapper.\n" +
56
+ "Use the basic mapper with HttpVanilli.basic_mapper! ,\n" +
57
+ "or plug one in with HttpVanilli.request_mapper=Yourmapper.new"
58
+ end
59
+ @request_mapper
60
+ end
61
+ end
62
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: http_vanilli
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 2
9
+ version: 0.0.2
10
+ platform: ruby
11
+ authors:
12
+ - Lachie Cox
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-08-01 00:00:00 +10:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: exemplor
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :development
31
+ version_requirements: *id001
32
+ description: HttpVanilli gives you lip-synced http connections with pluggable band members for testing.
33
+ email:
34
+ - lachiec@gmail.com
35
+ executables: []
36
+
37
+ extensions: []
38
+
39
+ extra_rdoc_files: []
40
+
41
+ files:
42
+ - lib/angry_web/matcher.rb
43
+ - lib/http_vanilli/abstract_responder.rb
44
+ - lib/http_vanilli/basic_mapper.rb
45
+ - lib/http_vanilli/basic_mapping.rb
46
+ - lib/http_vanilli/net_http/override.rb
47
+ - lib/http_vanilli/net_http/request.rb
48
+ - lib/http_vanilli/net_http/response.rb
49
+ - lib/http_vanilli/net_http/stubs.rb
50
+ - lib/http_vanilli/net_http/util.rb
51
+ - lib/http_vanilli/other_mapper.rb
52
+ - lib/http_vanilli/request.rb
53
+ - lib/http_vanilli/responders/block.rb
54
+ - lib/http_vanilli/responders/rack.rb
55
+ - lib/http_vanilli/responders.rb
56
+ - lib/http_vanilli/response.rb
57
+ - lib/http_vanilli/test_adapters/rspec.rb
58
+ - lib/http_vanilli/util.rb
59
+ - lib/http_vanilli/version.rb
60
+ - lib/http_vanilli.rb
61
+ has_rdoc: true
62
+ homepage: http://github.com/lachie/http_vanilli
63
+ licenses: []
64
+
65
+ post_install_message:
66
+ rdoc_options: []
67
+
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ segments:
75
+ - 0
76
+ version: "0"
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ segments:
82
+ - 1
83
+ - 3
84
+ - 6
85
+ version: 1.3.6
86
+ requirements: []
87
+
88
+ rubyforge_project: http_vanilli
89
+ rubygems_version: 1.3.6
90
+ signing_key:
91
+ specification_version: 3
92
+ summary: Flexible web connection mocking lib.
93
+ test_files: []
94
+