Skip to content

Instantly share code, notes, and snippets.

@lavn0
Created March 28, 2024 16:21
Show Gist options
  • Save lavn0/2b437735150088d98fe09cbce0d78501 to your computer and use it in GitHub Desktop.
Save lavn0/2b437735150088d98fe09cbce0d78501 to your computer and use it in GitHub Desktop.
require 'minitest/autorun'
require 'yaml'
require_relative "../lib/ypath.rb"
class TestYPath < Minitest::Test
def setup
end
def test_ypath
::Syck::YPath.each_path("/hoge/fuga") { |part|
assert_equal(["hoge", "fuga"], part.segments)
}
end
def test_yaml
data = YAML.load(File.read('test/resource/test.yaml'))
assert_equal("piyo", data['hoge']['fuga'])
# tmp = match_path(data, "/hoge/fuga")
# assert_equal("piyo", tmp[0])
tmp = select(data, "/hoge")
assert_equal("piyo", tmp[0])
assert_equal(1, tmp[0].line_width)
end
def select( psyck, ypath_str )
matches = match_path( psyck, ypath_str )
if matches
result = []
matches.each { |m|
result.push m.last
}
result
end
end
# basenode.rb
def match_path( psyck, ypath_str )
warn "#{caller[0]}: match_path is deprecated" if $VERBOSE
matches = []
::Syck::YPath.each_path( ypath_str ) do |ypath|
seg = match_segment( psyck, ypath, 0)
matches += seg if seg
end
matches.uniq
end
# basenode.rb
def match_segment( psyck, ypath, depth )
warn "#{caller[0]}: match_segment is deprecated" if $VERBOSE
deep_nodes = []
seg = ypath.segments[ depth ]
if seg == "/"
unless String === psyck
idx = -1
psyck.collect { |v|
idx += 1
if Hash === psyck
match_init = [v[0].transform, v[1]]
match_deep = v[1].match_segment( ypath, depth )
else
match_init = [idx, v]
match_deep = v.match_segment( ypath, depth )
end
if match_deep
match_deep.each { |m|
deep_nodes.push( match_init + m )
}
end
}
end
depth += 1
seg = ypath.segments[ depth ]
end
match_nodes =
case seg
when "."
[[nil, psyck]]
when ".."
[["..", nil]]
when "*"
if psyck.is_a? Enumerable
idx = -1
psyckcollect { |h|
idx += 1
if Hash === psyck
[h[0].transform, h[1]]
else
[idx, h]
end
}
end
else
if seg =~ /^"(.*)"$/
seg = $1
elsif seg =~ /^'(.*)'$/
seg = $1
end
if ( v = at( psyck, seg ) )
[[ seg, v ]]
end
end
return deep_nodes unless match_nodes
pred = ypath.predicates[ depth ]
if pred
case pred
when /^\.=/
pred = $' # '
match_nodes.reject! { |n|
n.last != pred
}
else
match_nodes.reject! { |n|
n.last.at( psyck, pred ).nil?
}
end
end
return match_nodes + deep_nodes unless ypath.segments.length > depth + 1
#puts "DEPTH: #{depth + 1}"
deep_nodes = []
match_nodes.each { |n|
if n[1].is_a? Hash
match_deep = match_segment( n[1], ypath, depth + 1 )
if match_deep
match_deep.each { |m|
deep_nodes.push( n + m )
}
end
else
deep_nodes = []
end
}
deep_nodes = nil if deep_nodes.length == 0
deep_nodes
end
def at( psyck, seg )
warn "#{caller[0]}: at() is deprecated" if $VERBOSE
if Hash === psyck
psyck[seg]
elsif Array === psyck and seg =~ /\A\d+\Z/ and psyck[seg.to_i]
psyck[seg.to_i]
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment