module Matchers::JSON::JSONPath

Public Instance Methods

json_path_valid?(path) click to toggle source

TODO: the regular expressions below will catch very few errors

# File lib/matchers/json/json_path.rb, line 29
def json_path_valid?(path)
  notation = path.include?('[\'') ? :bracket : :dot
  path_regex = /^\$[a-zA-Z0-9_(\[\d\])\.]*[^\.]$/ if notation == :dot
  path_regex = /^\$[a-zA-Z0-9_(\[\d\])\.\']*[^\.]$/ if notation == :bracket
  path_regex.match(path)
end
value_on_path(json_hash, path) click to toggle source
# File lib/matchers/json/json_path.rb, line 13
def value_on_path(json_hash, path)
  raise ArgumentError, "Invalid json path: #{path}" unless json_path_valid?(path)
  path = translate_to_dot_notation(path)
  current_node = json_hash # start traversal at document root
  path_items(path).each do |path_item|
    element, index = decompose_path_item(path_item)
    begin
      current_node = fetch(current_node, element, index)
    rescue IndexError
      return nil
    end
  end
  current_node
end

Private Instance Methods

decompose_path_item(path_item) click to toggle source

if the path item contains an index (eg 'sample') then the index will be returned if not, second return value will be nil [element,index]

# File lib/matchers/json/json_path.rb, line 48
def decompose_path_item(path_item)
  element, index = path_item.split('[')
  index = index[0..-2].to_i if index
  [element, index]
end
fetch(current_node, element, index) click to toggle source
# File lib/matchers/json/json_path.rb, line 54
def fetch(current_node, element, index)
  current_node = current_node.send(:fetch, element)
  current_node = current_node.send(:fetch, index) if index
  current_node
end
path_items(path) click to toggle source
# File lib/matchers/json/json_path.rb, line 42
def path_items(path)
  path[1..-1].split('.') # removing the leading '$'
end
translate_to_dot_notation(path) click to toggle source
# File lib/matchers/json/json_path.rb, line 37
def translate_to_dot_notation(path)
  path = path.gsub('[\'', '').gsub('\']', '') if path.include?('[\'')
  path
end