class Object

Constants

CMP_AT_LEAST
CMP_AT_MOST
CMP_EQUALS
CMP_LESS_THAN
CMP_MORE_THAN
FEWER_MORE_THAN_SYNONYM
FIELD_NAME_SYNONYM
GET_TYPES
HAVE_ALTERNATION
INT_AS_WORDS_SYNONYM
MAXIMAL_FIELD_NAME_SYNONYM
RESOURCE_NAME_SYNONYM
WITH_ID

Public Instance Methods

add_to_hash(hash, node) click to toggle source
# File lib/cucumber-rest-bdd/types.rb, line 172
def add_to_hash(hash, node)
  result = nil
  if node[0] == '[' && node[-1] == ']'
    array = Array.new(node[1..-2].to_i + 1)
    array[node[1..-2].to_i] = hash
    result = array
  end
  !result.nil? ? result : { node => hash }
end
child_check(level, child_data, local_nesting, expected, match_value) click to toggle source

check that all the children in child_data match the expected values

# File lib/cucumber-rest-bdd/data.rb, line 54
def child_check(level, child_data, local_nesting, expected, match_value)
  matched = child_data.select do |item|
    nest_match_attributes(item, local_nesting, expected, match_value)
  end
  level[:comparison].compare(matched.count)
end
child_is_list(level, child_data) click to toggle source

is the child a list, and does it match the comparison?

# File lib/cucumber-rest-bdd/data.rb, line 62
def child_is_list(level, child_data)
  child_data.is_a?(Array) \
  && (!level.key?(:comparison) \
    || level[:comparison].compare(child_data.count))
end
get_child_data(level, data) click to toggle source

parse the field and get the data for a given child

# File lib/cucumber-rest-bdd/data.rb, line 69
def get_child_data(level, data)
  return data.dup if level[:root]
  level_key = case level[:type]
              when 'single' then parse_field(level[:key])
              when 'multiple', 'list' then parse_list_field(level[:key])
              end
  raise %(Key not found: #{level[:key]} as #{level_key} in #{data}) \
    if data.is_a?(Array) || !data[level_key]
  data[level_key]
end
get_key(grouping) click to toggle source

gets the relevant key for the response based on the first key element

# File lib/cucumber-rest-bdd/data.rb, line 4
def get_key(grouping)
  error_key = ENV['error_key']
  if error_key && !error_key.empty? && grouping.count > 1 && grouping[-2][:key].singularize == error_key
    '$.'
  else
    root_data_key
  end
end
get_resource(name) click to toggle source
# File lib/cucumber-rest-bdd/types.rb, line 100
def get_resource(name)
  if name[0] == '`' && name[-1] == '`'
    name = name[1..-2]
  else
    name = name.parameterize
    name = ENV.key?('resource_single') && ENV['resource_single'] == 'true' ? name.singularize : name.pluralize
  end
  name
end
get_url(path) click to toggle source
# File lib/cucumber-rest-bdd/url.rb, line 1
def get_url(path)
  raise %(Please set an 'endpoint' environment variable provided with the url of the api) unless ENV.key?('endpoint')
  url = ENV['endpoint']
  url = "#{url}/" unless url.end_with?('/')
  url = "#{url}#{@urlbasepath}/" unless @urlbasepath.to_s.empty?
  url = "#{url}#{path}" unless path.empty?
  url
end
json_path(names) click to toggle source
# File lib/cucumber-rest-bdd/types.rb, line 114
def json_path(names)
  "#{root_data_key}#{split_fields(names).join('.')}"
end
merge_arrays(first, second) click to toggle source
# File lib/cucumber-rest-bdd/types.rb, line 182
def merge_arrays(first, second)
  new_length = [first.length, second.length].max
  new_array = Array.new(new_length)
  new_length.times do |n|
    new_array[n] = if second[n].nil?
                     first[n]
                   else
                     new_array[n] = if first[n].nil?
                                      second[n]
                                    else
                                      first[n].merge(second[n])
                                    end
                   end
  end
  new_array
end
nest_get_match(level, child_data, local_nesting, expected, match_value) click to toggle source

nest_get_match returns true if the child data matches the expected data

# File lib/cucumber-rest-bdd/data.rb, line 40
def nest_get_match(level, child_data, local_nesting, expected, match_value)
  case level[:type]
  when 'single' then
    nest_match_attributes(child_data, local_nesting, expected, match_value)
  when 'multiple' then
    child_check(level, child_data, local_nesting, expected, match_value)
  when 'list' then
    child_is_list(level, child_data)
  else
    raise %(Unknown nested data type: #{level[:type]})
  end
end
nest_match_attributes(data, nesting, expected, match_value) click to toggle source

top level has 2 children

with an item containing
at most three fish with attributes:

nesting = [

{key=fish,count=3,count_mod='<=',type=multiple},
{key=item,type=single},
{key=children,type=multiple,count=2,count_mod='='},
{root=true,type=single}

]

returns true if the expected data is contained within the data based on the nesting information

# File lib/cucumber-rest-bdd/data.rb, line 26
def nest_match_attributes(data, nesting, expected, match_value)
  # puts data.inspect, nesting.inspect, expected.inspect, match_value.inspect
  return false unless data
  return data.deep_include?(expected) if !match_value && nesting.empty?
  return data.include?(expected) if match_value && nesting.empty?

  local_nesting = nesting.dup
  level = local_nesting.pop
  child_data = get_child_data(level, data)

  nest_get_match(level, child_data, local_nesting, expected, match_value)
end
parse_attributes(hashes) click to toggle source
# File lib/cucumber-rest-bdd/types.rb, line 145
def parse_attributes(hashes)
  hashes.each_with_object({}) do |row, hash|
    name = row['attribute']
    value = row['value']
    type = row['type']
    value = resolve_functions(value)
    value = resolve(value)
    value.gsub!(/\\n/, "\n")
    names = split_fields(name)
    new_hash = names.reverse.inject(string_to_type(value, type)) { |a, n| add_to_hash(a, n) }
    hash.deep_merge!(new_hash) { |_, old, new| new.is_a?(Array) ? merge_arrays(old, new) : new }
  end
end
parse_field(name) click to toggle source
# File lib/cucumber-rest-bdd/types.rb, line 122
def parse_field(name)
  if name[0] == '`' && name[-1] == '`'
    name = name[1..-2]
  elsif name[0] != '[' || name[-1] != ']'
    separator = ENV.key?('field_separator') ? ENV['field_separator'] : '_'
    name = name.parameterize(separator: separator)
    name = name.camelize(:lower) if ENV.key?('field_camel') && ENV['field_camel'] == 'true'
  end
  name
end
parse_list_field(name) click to toggle source
# File lib/cucumber-rest-bdd/types.rb, line 133
def parse_list_field(name)
  if name[0] == '`' && name[-1] == '`'
    name = name[1..-2]
  elsif name[0] != '[' || name[-1] != ']'
    separator = ENV.key?('field_separator') ? ENV['field_separator'] : '_'
    name = name.parameterize(separator: separator)
    name = name.pluralize
    name = name.camelize(:lower) if ENV.key?('field_camel') && ENV['field_camel'] == 'true'
  end
  name
end
parse_type(type) click to toggle source
# File lib/cucumber-rest-bdd/types.rb, line 54
def parse_type(type)
  replacements = {
    /^numeric$/i => 'numeric',
    /^int$/i => 'numeric',
    /^long$/i => 'numeric',
    /^number$/i => 'numeric',
    /^decimal$/i => 'numeric',
    /^double$/i => 'numeric',
    /^bool$/i => 'boolean',
    /^null$/i => 'nil_class',
    /^nil$/i => 'nil_class',
    /^string$/i => 'string',
    /^text$/i => 'string'
  }
  type.tr(' ', '_')
  replacements.each { |k, v| type.gsub!(k, v) }
  type
end
resolve_functions(value) click to toggle source
# File lib/cucumber-rest-bdd/types.rb, line 159
def resolve_functions(value)
  value.gsub!(/\[([a-zA-Z0-9_]+)\]/) do |s|
    s.gsub!(/[\[\]]/, '')
    case s.downcase
    when 'datetime'
      Time.now.strftime('%Y%m%d%H%M%S')
    else
      raise 'Unrecognised function ' + s + '?'
    end
  end
  value
end
root_data_key() click to toggle source
# File lib/cucumber-rest-bdd/types.rb, line 110
def root_data_key
  ENV.key?('data_key') && !ENV['data_key'].empty? ? "$.#{ENV['data_key']}." : '$.'
end
split_fields(names) click to toggle source
# File lib/cucumber-rest-bdd/types.rb, line 118
def split_fields(names)
  names.split(':').map { |n| parse_field(n.strip) }
end
string_to_type(value, type) click to toggle source
# File lib/cucumber-rest-bdd/types.rb, line 73
def string_to_type(value, type)
  replacements = {
    /^numeric$/i => 'integer',
    /^int$/i => 'integer',
    /^long$/i => 'integer',
    /^number$/i => 'integer',
    /^decimal$/i => 'float',
    /^double$/i => 'float',
    /^bool$/i => 'boolean',
    /^null$/i => 'nil_class',
    /^nil$/i => 'nil_class',
    /^string$/i => 'string',
    /^text$/i => 'string'
  }
  type.tr(' ', '_')
  replacements.each { |k, v| type.gsub!(k, v) }
  type = type.camelize.constantize
  # cannot use 'case type' which checks for instances of a type rather than type equality
  if type == Boolean then !(value =~ /true|yes/i).nil?
  elsif type == Enum then value.upcase.tr(' ', '_')
  elsif type == Float then value.to_f
  elsif type == Integer then value.to_i
  elsif type == NilClass then nil
  else value
  end
end
to_compare(compare) click to toggle source

take a number modifier string (fewer than, less than, etc) and return an operator '<', etc

# File lib/cucumber-rest-bdd/list.rb, line 140
def to_compare(compare)
  case compare
  when 'fewer than' then CMP_LESS_THAN
  when 'less than' then CMP_LESS_THAN
  when 'more than' then CMP_MORE_THAN
  when 'at least' then CMP_AT_LEAST
  when 'at most' then CMP_AT_MOST
  else CMP_EQUALS
  end
end
to_num(num) click to toggle source
# File lib/cucumber-rest-bdd/list.rb, line 151
def to_num(num)
  if num =~ /^(?:zero|one|two|three|four|five|six|seven|eight|nine|ten)$/
    return %w[zero one two three four five six seven eight nine ten].index(num)
  end
  num.to_i
end