Skip to content

Commit

Permalink
Converts autorization middleware tests.
Browse files Browse the repository at this point in the history
Moves Faraday::Utils classes (Headers and ParamsHash) into separate files.
Converts Faraday::Utils::Headers tests.
  • Loading branch information
iMacTia committed Sep 21, 2018
1 parent 752b64f commit 54b24cd
Show file tree
Hide file tree
Showing 7 changed files with 360 additions and 318 deletions.
188 changes: 3 additions & 185 deletions lib/faraday/utils.rb
@@ -1,194 +1,12 @@
require 'thread'

require_relative 'utils/headers'
require_relative 'utils/params_hash'

module Faraday
module Utils
extend self

# Adapted from Rack::Utils::HeaderHash
class Headers < ::Hash
def self.from(value)
new(value)
end

def self.allocate
new_self = super
new_self.initialize_names
new_self
end

def initialize(hash = nil)
super()
@names = {}
self.update(hash || {})
end

def initialize_names
@names = {}
end

# on dup/clone, we need to duplicate @names hash
def initialize_copy(other)
super
@names = other.names.dup
end

# need to synchronize concurrent writes to the shared KeyMap
keymap_mutex = Mutex.new

# symbol -> string mapper + cache
KeyMap = Hash.new do |map, key|
value = if key.respond_to?(:to_str)
key
else
key.to_s.split('_'). # :user_agent => %w(user agent)
each { |w| w.capitalize! }. # => %w(User Agent)
join('-') # => "User-Agent"
end
keymap_mutex.synchronize { map[key] = value }
end
KeyMap[:etag] = "ETag"

def [](k)
k = KeyMap[k]
super(k) || super(@names[k.downcase])
end

def []=(k, v)
k = KeyMap[k]
k = (@names[k.downcase] ||= k)
# join multiple values with a comma
v = v.to_ary.join(', ') if v.respond_to? :to_ary
super(k, v)
end

def fetch(k, *args, &block)
k = KeyMap[k]
key = @names.fetch(k.downcase, k)
super(key, *args, &block)
end

def delete(k)
k = KeyMap[k]
if k = @names[k.downcase]
@names.delete k.downcase
super(k)
end
end

def include?(k)
@names.include? k.downcase
end

alias_method :has_key?, :include?
alias_method :member?, :include?
alias_method :key?, :include?

def merge!(other)
other.each { |k, v| self[k] = v }
self
end
alias_method :update, :merge!

def merge(other)
hash = dup
hash.merge! other
end

def replace(other)
clear
@names.clear
self.update other
self
end

def to_hash() ::Hash.new.update(self) end

def parse(header_string)
return unless header_string && !header_string.empty?

headers = header_string.split(/\r\n/)

# Find the last set of response headers.
start_index = headers.rindex { |x| x.match(/^HTTP\//) } || 0
last_response = headers.slice(start_index, headers.size)

last_response.
tap { |a| a.shift if a.first.index('HTTP/') == 0 }. # drop the HTTP status line
map { |h| h.split(/:\s*/, 2) }.reject { |p| p[0].nil? }. # split key and value, ignore blank lines
each { |key, value|
# join multiple values with a comma
if self[key]
self[key] << ', ' << value
else
self[key] = value
end
}
end

protected

def names
@names
end
end

# hash with stringified keys
class ParamsHash < Hash
def [](key)
super(convert_key(key))
end

def []=(key, value)
super(convert_key(key), value)
end

def delete(key)
super(convert_key(key))
end

def include?(key)
super(convert_key(key))
end

alias_method :has_key?, :include?
alias_method :member?, :include?
alias_method :key?, :include?

def update(params)
params.each do |key, value|
self[key] = value
end
self
end
alias_method :merge!, :update

def merge(params)
dup.update(params)
end

def replace(other)
clear
update(other)
end

def merge_query(query, encoder = nil)
if query && !query.empty?
update((encoder || Utils.default_params_encoder).decode(query))
end
self
end

def to_query(encoder = nil)
(encoder || Utils.default_params_encoder).encode(self)
end

private

def convert_key(key)
key.to_s
end
end

def build_query(params)
FlatParamsEncoder.encode(params)
end
Expand Down
131 changes: 131 additions & 0 deletions lib/faraday/utils/headers.rb
@@ -0,0 +1,131 @@
module Faraday
module Utils
# Adapted from Rack::Utils::HeaderHash
class Headers < ::Hash
def self.from(value)
new(value)
end

def self.allocate
new_self = super
new_self.initialize_names
new_self
end

def initialize(hash = nil)
super()
@names = {}
self.update(hash || {})
end

def initialize_names
@names = {}
end

# on dup/clone, we need to duplicate @names hash
def initialize_copy(other)
super
@names = other.names.dup
end

# need to synchronize concurrent writes to the shared KeyMap
keymap_mutex = Mutex.new

# symbol -> string mapper + cache
KeyMap = Hash.new do |map, key|
value = if key.respond_to?(:to_str)
key
else
key.to_s.split('_'). # :user_agent => %w(user agent)
each { |w| w.capitalize! }. # => %w(User Agent)
join('-') # => "User-Agent"
end
keymap_mutex.synchronize { map[key] = value }
end
KeyMap[:etag] = "ETag"

def [](k)
k = KeyMap[k]
super(k) || super(@names[k.downcase])
end

def []=(k, v)
k = KeyMap[k]
k = (@names[k.downcase] ||= k)
# join multiple values with a comma
v = v.to_ary.join(', ') if v.respond_to? :to_ary
super(k, v)
end

def fetch(k, *args, &block)
k = KeyMap[k]
key = @names.fetch(k.downcase, k)
super(key, *args, &block)
end

def delete(k)
k = KeyMap[k]
if k = @names[k.downcase]
@names.delete k.downcase
super(k)
end
end

def include?(k)
@names.include? k.downcase
end

alias_method :has_key?, :include?
alias_method :member?, :include?
alias_method :key?, :include?

def merge!(other)
other.each { |k, v| self[k] = v }
self
end
alias_method :update, :merge!

def merge(other)
hash = dup
hash.merge! other
end

def replace(other)
clear
@names.clear
self.update other
self
end

def to_hash() ::Hash.new.update(self) end

def parse(header_string)
return unless header_string && !header_string.empty?

headers = header_string.split(/\r\n/)

# Find the last set of response headers.
start_index = headers.rindex { |x| x.match(/^HTTP\//) } || 0
last_response = headers.slice(start_index, headers.size)

last_response.
tap { |a| a.shift if a.first.index('HTTP/') == 0 }. # drop the HTTP status line
map { |h| h.split(/:\s*/, 2) }.reject { |p| p[0].nil? }. # split key and value, ignore blank lines

This comment has been minimized.

Copy link
@taleh007

taleh007 Sep 28, 2018

bad indentation. use one line for one method call (for better reading). Maybe it will be better to use lazy iterator for this chain

This comment has been minimized.

Copy link
@iMacTia

iMacTia Sep 28, 2018

Author Member

Yeah indentation went crazy when I moved the code, will fix that - thanks for pointing out.
I'm surprised you found something like this on a WIP branch 😮

each { |key, value|
# join multiple values with a comma
if self[key]
self[key] << ', ' << value
else
self[key] = value
end
}
end

protected

def names
@names
end
end
end
end
60 changes: 60 additions & 0 deletions lib/faraday/utils/params_hash.rb
@@ -0,0 +1,60 @@
module Faraday
module Utils
# Hash with stringified keys
class ParamsHash < Hash
def [](key)
super(convert_key(key))
end

def []=(key, value)
super(convert_key(key), value)
end

def delete(key)
super(convert_key(key))
end

def include?(key)
super(convert_key(key))
end

alias_method :has_key?, :include?
alias_method :member?, :include?
alias_method :key?, :include?

def update(params)
params.each do |key, value|
self[key] = value
end
self
end
alias_method :merge!, :update

def merge(params)
dup.update(params)
end

def replace(other)
clear
update(other)
end

def merge_query(query, encoder = nil)
if query && !query.empty?
update((encoder || Utils.default_params_encoder).decode(query))
end
self
end

def to_query(encoder = nil)
(encoder || Utils.default_params_encoder).encode(self)
end

private

def convert_key(key)
key.to_s
end
end
end
end

0 comments on commit 54b24cd

Please sign in to comment.