Class: Pact::Query

Inherits:
Object
  • Object
show all
Defined in:
lib/pact/consumer_contract/query.rb

Defined Under Namespace

Classes: NestedQuery

Constant Summary collapse

DEFAULT_SEP =
/[&;] */n
COMMON_SEP =
{ ";" => /[;] */n, ";," => /[;,] */n, "&" => /[&] */n }

Class Method Summary collapse

Class Method Details

.create(query) ⇒ Object



11
12
13
14
15
16
17
# File 'lib/pact/consumer_contract/query.rb', line 11

def self.create query
  if query.is_a? Hash
    Pact::QueryHash.new(query)
  else
    Pact::QueryString.new(query)
  end
end

.is_a_query_object?(object) ⇒ Boolean

Returns:

  • (Boolean)


19
20
21
# File 'lib/pact/consumer_contract/query.rb', line 19

def self.is_a_query_object?(object)
  object.is_a?(Pact::QueryHash) || object.is_a?(Pact::QueryString)
end

.normalize_params(params, name, v) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/pact/consumer_contract/query.rb', line 79

def self.normalize_params(params, name, v)
  name =~ %r(\A[\[\]]*([^\[\]]+)\]*)
  k = $1 || ''
  after = $' || ''

  if k.empty?
    if !v.nil? && name == "[]"
      return Array(v)
    else
      return
    end
  end

  if after == ''
    params[k] = v
  elsif after == "["
    params[name] = v
  elsif after == "[]"
    params[k] ||= []
    raise ParameterTypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
    params[k] << v
  elsif after =~ %r(^\[\]\[([^\[\]]+)\]$) || after =~ %r(^\[\](.+)$)
    child_key = $1
    params[k] ||= []
    raise ParameterTypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
    if params_hash_type?(params[k].last) && !params_hash_has_key?(params[k].last, child_key)
      normalize_params(params[k].last, child_key, v)
    else
      params[k] << normalize_params({}, child_key, v)
    end
  else
    params[k] ||= {}
    raise ParameterTypeError, "expected Hash (got #{params[k].class.name}) for param `#{k}'" unless params_hash_type?(params[k])
    params[k] = normalize_params(params[k], after, v)
  end

  params
end

.params_hash_has_key?(hash, key) ⇒ Boolean

Returns:

  • (Boolean)


122
123
124
125
126
127
128
129
130
131
132
# File 'lib/pact/consumer_contract/query.rb', line 122

def self.params_hash_has_key?(hash, key)
  return false if key =~ /\[\]/

  key.split(/[\[\]]+/).inject(hash) do |h, part|
    next h if part == ''
    return false unless params_hash_type?(h) && h.key?(part)
    h[part]
  end

  true
end

.params_hash_type?(obj) ⇒ Boolean

Returns:

  • (Boolean)


118
119
120
# File 'lib/pact/consumer_contract/query.rb', line 118

def self.params_hash_type?(obj)
  obj.is_a?(Hash)
end

.parse_string(query_string) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/pact/consumer_contract/query.rb', line 27

def self.parse_string query_string
  parsed_query = parse_string_as_non_nested_query(query_string)

  # If Rails nested params...
  if parsed_query.keys.any?{ | key| key =~ /\[.*\]/ }
    parse_string_as_nested_query(query_string)
  else
    parsed_query.each_with_object({}) do | (key, value), new_hash |
      new_hash[key] = [*value]
    end
  end
end

.parse_string_as_nested_query(qs, d = nil) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/pact/consumer_contract/query.rb', line 65

def self.parse_string_as_nested_query(qs, d = nil)
  params = {}

  unless qs.nil? || qs.empty?
    (qs || '').split(d ? (COMMON_SEP[d] || /[#{d}] */n) : DEFAULT_SEP).each do |p|
      k, v = p.split('=', 2).map! { |s| unescape(s) }

      normalize_params(params, k, v)
    end
  end

  return NestedQuery[params.to_h]
end

.parse_string_as_non_nested_query(qs, d = nil, &unescaper) ⇒ Object

Ripped from Rack to avoid adding an unnecessary dependency, thank you Rack github.com/rack/rack/blob/649c72bab9e7b50d657b5b432d0c205c95c2be07/lib/rack/utils.rb



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/pact/consumer_contract/query.rb', line 42

def self.parse_string_as_non_nested_query(qs, d = nil, &unescaper)
  unescaper ||= method(:unescape)

  params = {}

  (qs || '').split(d ? (COMMON_SEP[d] || /[#{d}] */n) : DEFAULT_SEP).each do |p|
    next if p.empty?
    k, v = p.split('=', 2).map!(&unescaper)

    if cur = params[k]
      if cur.class == Array
        params[k] << v
      else
        params[k] = [cur, v]
      end
    else
      params[k] = v
    end
  end

  return params.to_h
end

.parsed_as_nested?(object) ⇒ Boolean

Returns:

  • (Boolean)


23
24
25
# File 'lib/pact/consumer_contract/query.rb', line 23

def self.parsed_as_nested?(object)
  object.is_a?(NestedQuery)
end

.unescape(s, encoding = Encoding::UTF_8) ⇒ Object



134
135
136
# File 'lib/pact/consumer_contract/query.rb', line 134

def self.unescape(s, encoding = Encoding::UTF_8)
  URI.decode_www_form_component(s, encoding)
end