hpath 0.0.6 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/hpath.gemspec +0 -2
- data/lib/hpath.rb +36 -56
- data/lib/hpath/filter.rb +33 -26
- data/lib/hpath/parser.rb +14 -106
- data/lib/hpath/parser/filter_expression_parser.rb +104 -0
- data/lib/hpath/version.rb +1 -1
- data/spec/hpath_spec.rb +6 -3
- metadata +3 -18
- data/spec/hpath/filter_spec.rb +0 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ad0d4d96a06f668bfa028932de928241d21d8aae
|
4
|
+
data.tar.gz: c92b4b2d8d677a084691274c693f42f6b4638956
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 910e80b2f6345207a9797bd685ece086339a393dc0682a1de716bab213cda1b89b3a2b136767b0da7775e7b0af6f7f10660b64c41040cb8f7b8658a32d02ca53
|
7
|
+
data.tar.gz: 6e167078fd602383453230d92f99481be3fbc41609955ade712e864f66ef5cf82b48ec63d70fb231129f377f6fa73d58ec13af16efa8e224d3926fa227f30936
|
data/hpath.gemspec
CHANGED
@@ -16,8 +16,6 @@ Gem::Specification.new do |spec|
|
|
16
16
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
17
17
|
spec.require_paths = ["lib"]
|
18
18
|
|
19
|
-
spec.add_dependency "parslet", ">= 1.6.1"
|
20
|
-
|
21
19
|
spec.add_development_dependency "bundler", "~> 1.5"
|
22
20
|
spec.add_development_dependency "rake"
|
23
21
|
spec.add_development_dependency "rspec", ">= 3.0.0", "< 4.0.0"
|
data/lib/hpath.rb
CHANGED
@@ -1,16 +1,15 @@
|
|
1
1
|
module Hpath
|
2
|
-
require "hpath/filter"
|
3
2
|
require "hpath/parser"
|
4
3
|
require "hpath/version"
|
5
4
|
|
6
5
|
def self.get(object, hpath_string)
|
7
|
-
|
8
|
-
_get(object,
|
6
|
+
parsed_hpath = Hpath::Parser.parse(hpath_string)
|
7
|
+
_get(object, parsed_hpath)
|
9
8
|
end
|
10
9
|
|
11
10
|
def self.set(object, hpath_string, value)
|
12
|
-
|
13
|
-
_set(object,
|
11
|
+
parsed_hpath = Hpath::Parser.parse(hpath_string)
|
12
|
+
_set(object, parsed_hpath, value)
|
14
13
|
end
|
15
14
|
|
16
15
|
#
|
@@ -37,13 +36,9 @@ module Hpath
|
|
37
36
|
path = paths.shift
|
38
37
|
end
|
39
38
|
|
40
|
-
if path[:filter]
|
41
|
-
filter = Hpath::Filter.new(path[:filter])
|
42
|
-
end
|
43
|
-
|
44
39
|
if path[:identifier]
|
45
40
|
if path[:identifier] == "**"
|
46
|
-
object = _dfs(object, filter)
|
41
|
+
object = _dfs(object, path[:filter])
|
47
42
|
else
|
48
43
|
object = _resolve_identifier(object, path[:identifier])
|
49
44
|
end
|
@@ -51,14 +46,33 @@ module Hpath
|
|
51
46
|
object = parent
|
52
47
|
end
|
53
48
|
|
54
|
-
if path[:
|
55
|
-
|
56
|
-
|
57
|
-
object =
|
58
|
-
|
49
|
+
if path[:filter] && !(path[:identifier] && path[:identifier] == "**")
|
50
|
+
filter = path[:filter]
|
51
|
+
|
52
|
+
object =
|
53
|
+
if filter.type == :index
|
54
|
+
indices = path[:filter].operands
|
59
55
|
|
60
|
-
|
61
|
-
|
56
|
+
if object.is_a?(Array)
|
57
|
+
if indices.length == 1
|
58
|
+
object[indices.first]
|
59
|
+
elsif indices.length > 1
|
60
|
+
indices.map { |index| object[index] }
|
61
|
+
end
|
62
|
+
elsif object.is_a?(Hash)
|
63
|
+
object.select do |key, value|
|
64
|
+
indices.include?(key.to_s) || indices.include?(key.to_sym)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
else
|
68
|
+
if object.is_a?(Array)
|
69
|
+
object.select do |element|
|
70
|
+
filter.applies?(element)
|
71
|
+
end
|
72
|
+
else
|
73
|
+
# TODO
|
74
|
+
end
|
75
|
+
end
|
62
76
|
end
|
63
77
|
|
64
78
|
self._get(object, paths, _object)
|
@@ -73,22 +87,14 @@ module Hpath
|
|
73
87
|
|
74
88
|
if (_object = self._get(object, [path])).nil?
|
75
89
|
if object.is_a?(Array)
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
object.push(_object = value)
|
81
|
-
end
|
82
|
-
elsif path[:type] == Hash
|
83
|
-
unless paths.empty?
|
84
|
-
object.push({ path[:identifier].to_sym => (_object = {}) })
|
85
|
-
else
|
86
|
-
object.push({ path[:identifier].to_sym => (_object = value) })
|
87
|
-
end
|
90
|
+
unless paths.empty?
|
91
|
+
object.push({ path[:identifier].to_sym => (_object = {}) })
|
92
|
+
else
|
93
|
+
object.push({ path[:identifier].to_sym => (_object = value) })
|
88
94
|
end
|
89
95
|
elsif object.is_a?(Hash)
|
90
96
|
unless paths.empty?
|
91
|
-
object[path[:identifier].to_sym] = (_object =
|
97
|
+
object[path[:identifier].to_sym] = (_object = {})
|
92
98
|
else
|
93
99
|
object[path[:identifier].to_sym] = (_object = value)
|
94
100
|
end
|
@@ -98,16 +104,6 @@ module Hpath
|
|
98
104
|
self._set(_object, paths, value)
|
99
105
|
end
|
100
106
|
|
101
|
-
def self._apply_filters(object, filter)
|
102
|
-
if object.is_a?(Array)
|
103
|
-
object.select do |element|
|
104
|
-
filter.applies?(element)
|
105
|
-
end
|
106
|
-
else
|
107
|
-
# TODO
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
107
|
def self._resolve_identifier(object, identifier)
|
112
108
|
if object.is_a?(Array) && !object.empty?
|
113
109
|
if identifier.to_s == "*"
|
@@ -135,20 +131,4 @@ module Hpath
|
|
135
131
|
# TODO
|
136
132
|
end
|
137
133
|
end
|
138
|
-
|
139
|
-
def self._resolve_indices(object, indices)
|
140
|
-
if indices.length == 1
|
141
|
-
object[indices.first]
|
142
|
-
elsif indices.length > 1
|
143
|
-
indices.map { |index| object[index] }
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
def self._resolve_keys(object, keys)
|
148
|
-
if object.is_a?(Hash)
|
149
|
-
object.select { |key, value| keys.include?(key.to_s) || keys.include?(key.to_sym) }
|
150
|
-
else
|
151
|
-
raise "Cannot resolve keys for non-hash objects!"
|
152
|
-
end
|
153
|
-
end
|
154
134
|
end
|
data/lib/hpath/filter.rb
CHANGED
@@ -1,39 +1,46 @@
|
|
1
1
|
class Hpath::Filter
|
2
|
+
attr_accessor :operands
|
3
|
+
attr_accessor :type
|
2
4
|
|
3
|
-
def initialize(
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
def initialize(string = nil)
|
6
|
+
string = string.dup unless string.nil? # we should not use the referenced string
|
7
|
+
|
8
|
+
@type, @operands =
|
9
|
+
if string.nil?
|
10
|
+
[:and, []]
|
11
|
+
else
|
12
|
+
case string
|
13
|
+
when /=/ then [:equality, string.split("=")]
|
14
|
+
when /</ then [:less_than, string.split("<")]
|
15
|
+
when />/ then [:greater_than, string.split(">")]
|
16
|
+
when /\?/ then [:existence, string.split("?")]
|
17
|
+
else [:index, [string[/^\d+$/] ? string.to_i : string]] # convert strings to integer of possible
|
9
18
|
end
|
10
|
-
elsif @type == :key_existence_filter
|
11
|
-
@key = filter_hash[:key_existence_filter][:key]
|
12
|
-
elsif @type == :key_value_filter
|
13
|
-
@key = filter_hash[:key_value_filter][:key]
|
14
|
-
@value = filter_hash[:key_value_filter][:value]
|
15
19
|
end
|
20
|
+
|
21
|
+
@operands.select! { |operand| operand != "" } if @operands.is_a?(Array)
|
16
22
|
end
|
17
23
|
|
18
24
|
def applies?(object)
|
19
|
-
if @type == :
|
20
|
-
@
|
21
|
-
elsif @type == :
|
22
|
-
@
|
23
|
-
elsif @type == :
|
25
|
+
if @type == :and
|
26
|
+
@operands.all? { |filter| filter.applies?(object) }
|
27
|
+
elsif @type == :or
|
28
|
+
@operands.any? { |filter| filter.applies?(object) }
|
29
|
+
elsif @type == :existence
|
30
|
+
key = operands.first
|
31
|
+
|
24
32
|
if object.is_a?(Hash)
|
25
|
-
object.keys.include?(
|
33
|
+
object.keys.include?(key.to_s) || object.keys.include?(key.to_sym)
|
26
34
|
end
|
27
|
-
elsif @type == :
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
+
elsif @type == :equality
|
36
|
+
key, value = @operands
|
37
|
+
|
38
|
+
if object.is_a?(Hash)
|
39
|
+
object[key.to_s] == value.to_s || object[key.to_sym] == value.to_s ||
|
40
|
+
object[key.to_s] == value.to_sym || object[key.to_sym] == value.to_sym
|
41
|
+
elsif object.respond_to(key)
|
42
|
+
object.send(key) == value
|
35
43
|
end
|
36
44
|
end
|
37
45
|
end
|
38
|
-
|
39
46
|
end
|
data/lib/hpath/parser.rb
CHANGED
@@ -1,115 +1,23 @@
|
|
1
|
-
require "parslet"
|
2
|
-
|
3
1
|
class Hpath::Parser
|
2
|
+
require_relative "./parser/filter_expression_parser"
|
3
|
+
|
4
4
|
def self.parse(string)
|
5
5
|
self.new.parse(string)
|
6
6
|
end
|
7
7
|
|
8
8
|
def parse(string)
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
element[:indices] = [element[:indices]] if !element[:indices].nil? && !element[:indices].is_a?(Array)
|
22
|
-
element[:keys] ||= nil
|
23
|
-
element[:keys] = [element[:keys]] if !element[:keys].nil? && !element[:keys].is_a?(Array)
|
24
|
-
element[:type] = element[:type] == "[]" || element[:indices].is_a?(Array) ? Array : Hash
|
25
|
-
element
|
9
|
+
string
|
10
|
+
.split("/")
|
11
|
+
.delete_if { |path_element| path_element.empty? }
|
12
|
+
.map! do |path_element|
|
13
|
+
identifier, filter_expression = path_element.gsub("]", "").split("[")
|
14
|
+
filter = FilterExpressionParser.parse(filter_expression) if filter_expression
|
15
|
+
|
16
|
+
{
|
17
|
+
identifier: identifier == "" ? nil : identifier,
|
18
|
+
filter: filter
|
19
|
+
}
|
20
|
+
.select { |key, value| !value.nil? }
|
26
21
|
end
|
27
|
-
|
28
|
-
result_tree
|
29
|
-
end
|
30
|
-
|
31
|
-
def parser
|
32
|
-
@parser ||=
|
33
|
-
Class.new(Parslet::Parser) do
|
34
|
-
rule(:space) { match('\s').repeat(1) }
|
35
|
-
rule(:space?) { space.maybe }
|
36
|
-
|
37
|
-
rule(:key_existence_filter) {
|
38
|
-
space? >> match['0-9a-zA-Z@_'].repeat(1).as(:key) >> str("?") >> space?
|
39
|
-
}
|
40
|
-
|
41
|
-
rule(:key_value_filter) {
|
42
|
-
space? >> match['0-9a-zA-Z@_'].repeat(1).maybe.as(:key) >> (str("<") | str(">") | str("=").repeat(1,3)).as(:operator) >> match['a-zA-Z0-9'].repeat(1).as(:value) >> space?
|
43
|
-
}
|
44
|
-
|
45
|
-
rule(:or_filter) {
|
46
|
-
((and_filter.as(:and_filter) | key_value_filter.as(:key_value_filter)) >> str("|")).repeat(1) >> (and_filter.as(:and_filter) | key_value_filter.as(:key_value_filter))
|
47
|
-
}
|
48
|
-
|
49
|
-
rule(:primary) {
|
50
|
-
str("(") >> or_filter.as(:or_filter) >> str(")")
|
51
|
-
}
|
52
|
-
|
53
|
-
rule(:and_filter) {
|
54
|
-
((primary | key_value_filter.as(:key_value_filter)) >>
|
55
|
-
str(",")).repeat(1) >>
|
56
|
-
(primary | key_value_filter.as(:key_value_filter))
|
57
|
-
}
|
58
|
-
|
59
|
-
rule(:filter) {
|
60
|
-
space? >> (or_filter.as(:or_filter) | and_filter.as(:and_filter) | key_existence_filter.as(:key_existence_filter) | key_value_filter.as(:key_value_filter)).as(:filter) >> space?
|
61
|
-
}
|
62
|
-
|
63
|
-
rule(:keys) {
|
64
|
-
match('[a-zA-Z0-9]').repeat(1).as(:key) >> (space? >> str(",") >> space? >> match('[a-zA-Z0-9]').repeat(1).as(:key)).repeat
|
65
|
-
}
|
66
|
-
|
67
|
-
rule(:indices) {
|
68
|
-
match('[0-9]').repeat(1).as(:index) >> (space? >> str(",") >> match('[0-9]').repeat(1).as(:index)).repeat
|
69
|
-
}
|
70
|
-
|
71
|
-
rule(:identifier) {
|
72
|
-
match('[a-zA-Z0-9*_]').repeat(1)
|
73
|
-
}
|
74
|
-
|
75
|
-
rule(:node) {
|
76
|
-
str("/") >> (identifier.as(:identifier) | (str("::") >> identifier.as(:axis))).maybe >> (str("[]").as(:type) | (str("[") >> space? >> (indices.as(:indices) | filter | keys.as(:keys)) >> space? >> str("]"))).maybe
|
77
|
-
}
|
78
|
-
|
79
|
-
rule(:path) {
|
80
|
-
node.repeat(1).as(:path)
|
81
|
-
}
|
82
|
-
|
83
|
-
# root
|
84
|
-
root(:path)
|
85
|
-
end.new
|
86
|
-
end
|
87
|
-
|
88
|
-
def transform(result_tree)
|
89
|
-
transformation.apply(result_tree)
|
90
|
-
end
|
91
|
-
|
92
|
-
def transformation
|
93
|
-
@transformation ||=
|
94
|
-
Class.new(Parslet::Transform) do
|
95
|
-
rule(axis: simple(:axis), identifier: simple(:identifier), filter: subtree(:filter), indices: subtree(:indices), keys: subtree(:keys), type: simple(:type)) {
|
96
|
-
{
|
97
|
-
axis: axis.nil? ? nil : axis.to_s,
|
98
|
-
identifier: identifier.nil? ? nil : identifier.to_s,
|
99
|
-
filter: filter,
|
100
|
-
indices: indices.nil? ? nil : indices.map { |element| Integer(element[:index]) },
|
101
|
-
keys: keys.nil? ? nil : keys.map { |element| element[:key].to_s.to_sym },
|
102
|
-
type: type
|
103
|
-
}
|
104
|
-
}
|
105
|
-
|
106
|
-
rule(key: simple(:key)) {
|
107
|
-
{ key: key.nil? ? nil : key.to_sym }
|
108
|
-
}
|
109
|
-
|
110
|
-
rule(key: simple(:key), operator: simple(:operator), value: simple(:value)) {
|
111
|
-
{ key: key.nil? ? nil : key.to_sym, operator: operator.to_s, value: value.to_s }
|
112
|
-
}
|
113
|
-
end.new
|
114
22
|
end
|
115
23
|
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
class Hpath::Parser::FilterExpressionParser
|
2
|
+
require "hpath/filter"
|
3
|
+
|
4
|
+
def self.parse(string)
|
5
|
+
self.new.parse(string)
|
6
|
+
end
|
7
|
+
|
8
|
+
def flush_char_buffer(char_buffer, filter)
|
9
|
+
unless char_buffer.empty?
|
10
|
+
new_filter = Hpath::Filter.new(char_buffer)
|
11
|
+
|
12
|
+
if
|
13
|
+
new_filter.type == :index &&
|
14
|
+
!filter.operands.empty? &&
|
15
|
+
filter.operands.all? { |operand| operand.type == :index }
|
16
|
+
filter.operands.first.operands << new_filter.operands.first
|
17
|
+
else
|
18
|
+
filter.operands << new_filter
|
19
|
+
end
|
20
|
+
|
21
|
+
char_buffer.clear
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def parse(string)
|
26
|
+
# reset parser
|
27
|
+
char_buffer = ""
|
28
|
+
current_filter = Hpath::Filter.new
|
29
|
+
parent = {} # look up table
|
30
|
+
|
31
|
+
string.gsub(/\s/, "").each_char do |char|
|
32
|
+
unless special_character?(char)
|
33
|
+
char_buffer << char
|
34
|
+
else
|
35
|
+
flush_char_buffer(char_buffer, current_filter)
|
36
|
+
|
37
|
+
if char == "("
|
38
|
+
new_filter = Hpath::Filter.new
|
39
|
+
parent[new_filter] = current_filter
|
40
|
+
current_filter.operands << new_filter
|
41
|
+
current_filter = new_filter
|
42
|
+
elsif char == ")"
|
43
|
+
# replace operation by operand in parent if only one operand
|
44
|
+
if current_filter.operands.length == 1
|
45
|
+
parent[current_filter].operands.map! do |operand|
|
46
|
+
operand == current_filter ? current_filter.operands.first : operand
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
current_filter = parent[current_filter]
|
51
|
+
elsif char == "," || char == "|"
|
52
|
+
operator =
|
53
|
+
case char
|
54
|
+
when "," then :and
|
55
|
+
when "|" then :or
|
56
|
+
end
|
57
|
+
|
58
|
+
unless current_filter.operands.length == 2
|
59
|
+
current_filter.type = operator
|
60
|
+
else
|
61
|
+
if current_filter.type == :or && operator == :and
|
62
|
+
new_filter = Hpath::Filter.new.tap do |filter|
|
63
|
+
filter.operands << current_filter.operands.pop
|
64
|
+
filter.type = operator
|
65
|
+
end
|
66
|
+
|
67
|
+
parent[new_filter] = current_filter
|
68
|
+
current_filter.operands << new_filter
|
69
|
+
else
|
70
|
+
new_filter = Hpath::Filter.new.tap do |filter|
|
71
|
+
filter.operands << current_filter
|
72
|
+
filter.type = operator
|
73
|
+
end
|
74
|
+
|
75
|
+
parent[new_filter] = parent[current_filter]
|
76
|
+
parent[current_filter] = new_filter
|
77
|
+
end
|
78
|
+
|
79
|
+
current_filter = new_filter
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
flush_char_buffer(char_buffer, current_filter)
|
86
|
+
|
87
|
+
while parent[current_filter] != nil
|
88
|
+
current_filter = parent[current_filter]
|
89
|
+
end
|
90
|
+
|
91
|
+
if current_filter.operands.length == 1
|
92
|
+
current_filter.operands.first
|
93
|
+
else
|
94
|
+
current_filter
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
#
|
99
|
+
private
|
100
|
+
#
|
101
|
+
def special_character?(char)
|
102
|
+
char[/[(),\|]/] == nil ? false : true
|
103
|
+
end
|
104
|
+
end
|
data/lib/hpath/version.rb
CHANGED
data/spec/hpath_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require "some_more_complex_hpath_tests"
|
1
|
+
#require "some_more_complex_hpath_tests"
|
2
2
|
|
3
3
|
describe Hpath do
|
4
4
|
describe "#get" do
|
@@ -57,7 +57,8 @@ describe Hpath do
|
|
57
57
|
hpath_result = Hpath.get([{a:"1", b:"2", c:"3"}, {a:"1", b:"5", c:"6"}, {a:"2", b:"1", c:"3"}], "/a")
|
58
58
|
expect(hpath_result).to eq(["1", "1", "2"])
|
59
59
|
end
|
60
|
-
|
60
|
+
|
61
|
+
=begin
|
61
62
|
it "processes \"/key1/::parent\" for a hash" do
|
62
63
|
hpath_result = Hpath.get({ foo: { bar: "foobar" } }, "/foo/::parent")
|
63
64
|
expect(hpath_result).to eq({ foo: { bar: "foobar" } })
|
@@ -67,6 +68,7 @@ describe Hpath do
|
|
67
68
|
hpath_result = Hpath.get([{ foo: { bar: "foobar" } }], "/[0]/::parent")
|
68
69
|
expect(hpath_result).to eq([{ foo: { bar: "foobar" } }])
|
69
70
|
end
|
71
|
+
=end
|
70
72
|
|
71
73
|
it "processes \"/**[filter]\"" do
|
72
74
|
hpath_result = Hpath.get({
|
@@ -119,7 +121,7 @@ describe Hpath do
|
|
119
121
|
Hpath.set(hash = {}, "/foo/bar", { muff: "foobar"})
|
120
122
|
expect(hash).to eq({foo: { bar: { muff: "foobar"} }})
|
121
123
|
end
|
122
|
-
|
124
|
+
=begin
|
123
125
|
it "processes \"/[]/key2\" for a array" do
|
124
126
|
Hpath.set(array = [], "/[]/bar", { foo: "bar"})
|
125
127
|
expect(array).to eq([{ bar: {foo: "bar"} }])
|
@@ -134,6 +136,7 @@ describe Hpath do
|
|
134
136
|
Hpath.set(hash = {}, "/key1", 1)
|
135
137
|
expect(hash).to eq({key1: 1})
|
136
138
|
end
|
139
|
+
=end
|
137
140
|
end
|
138
141
|
end
|
139
142
|
end
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hpath
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Sievers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-07-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: parslet
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: 1.6.1
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: 1.6.1
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: bundler
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -89,8 +75,8 @@ files:
|
|
89
75
|
- lib/hpath.rb
|
90
76
|
- lib/hpath/filter.rb
|
91
77
|
- lib/hpath/parser.rb
|
78
|
+
- lib/hpath/parser/filter_expression_parser.rb
|
92
79
|
- lib/hpath/version.rb
|
93
|
-
- spec/hpath/filter_spec.rb
|
94
80
|
- spec/hpath/parser_spec.rb
|
95
81
|
- spec/hpath_spec.rb
|
96
82
|
- spec/some_more_complex_hpath_tests.rb
|
@@ -120,7 +106,6 @@ signing_key:
|
|
120
106
|
specification_version: 4
|
121
107
|
summary: HPath for ruby
|
122
108
|
test_files:
|
123
|
-
- spec/hpath/filter_spec.rb
|
124
109
|
- spec/hpath/parser_spec.rb
|
125
110
|
- spec/hpath_spec.rb
|
126
111
|
- spec/some_more_complex_hpath_tests.rb
|
data/spec/hpath/filter_spec.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
describe Hpath::Filter do
|
2
|
-
describe "key exists filter \"[foobar?\"]" do
|
3
|
-
context "when object is a array of hashes" do
|
4
|
-
let(:filter) { Hpath::Filter.new(key_existence_filter: { key: "foobar"} ) }
|
5
|
-
let(:array_of_hashes) { [{foobar: 1}, {foo: 2}, {bar: 3}, {foobar: "foobar"}]}
|
6
|
-
|
7
|
-
it "returns hashes, which include the given key" do
|
8
|
-
filtered_array = array_of_hashes.select{ |e| filter.applies?(e) }
|
9
|
-
expect(filtered_array).to eq([{foobar: 1}, {foobar: "foobar"}])
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
context "initialized with a (nested) filter hash" do
|
15
|
-
let(:filter_hash) { Hpath::Parser.new.parse("/array/*[a=b,c=d,(e=d|e=f)]")[:path].first[:filter] }
|
16
|
-
|
17
|
-
describe ".filter" do
|
18
|
-
context "when given object is an array containing hashes" do
|
19
|
-
let(:filter) { Hpath::Filter.new(Hpath::Parser.new.parse("/array/*[a=b,c=d,(e=d|e=f)]")[:path][1][:filter]) }
|
20
|
-
|
21
|
-
it "returns only hashes which match the filter" do
|
22
|
-
#w = [{a: "b", c: "d", e: "f"}, {a: "b", c: "d", e: "z"}].select { |e| filter.applies?(e) }
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|