hpath 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/TODO.md +7 -0
- data/lib/hpath.rb +22 -2
- data/lib/hpath/filter.rb +6 -0
- data/lib/hpath/parser.rb +9 -1
- data/lib/hpath/version.rb +1 -1
- data/spec/hpath/filter_spec.rb +12 -0
- data/spec/hpath_spec.rb +37 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 48e68e9a43e8aa6503dfe2d32f11d7f23d64c91c
|
4
|
+
data.tar.gz: 38d8d636bd3036953d60ad0a6aed7f26630fee60
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6712f8e3953f4956553e8bfb562a06d56276d0186ceaae1d0e4df06ac12c74db9b804ab27c18795833f99e81c4da86ec4fae138728174e65598b82c06b5108e5
|
7
|
+
data.tar.gz: 2a6a9cc297711ca0554b2b124faadfffa2ade0b57374bf44485369a0a5fc519169e7ef6e0937a9c1c8f55bb617919073706f47012b10eb3e56ae05787b8af14c
|
data/TODO.md
ADDED
data/lib/hpath.rb
CHANGED
@@ -16,6 +16,18 @@ module Hpath
|
|
16
16
|
#
|
17
17
|
private
|
18
18
|
#
|
19
|
+
def self._dfs(object, filter)
|
20
|
+
if filter.applies?(object)
|
21
|
+
object
|
22
|
+
elsif object.is_a?(Array)
|
23
|
+
object.map { |e| _dfs(e, filter) }
|
24
|
+
.tap { |o| o.compact! }
|
25
|
+
.tap { |o| o.flatten!(1) }
|
26
|
+
elsif object.is_a?(Hash)
|
27
|
+
_dfs(object.values, filter)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
19
31
|
def self._get(object, paths, parent = object)
|
20
32
|
_object = object
|
21
33
|
|
@@ -25,8 +37,16 @@ module Hpath
|
|
25
37
|
path = paths.shift
|
26
38
|
end
|
27
39
|
|
40
|
+
if path[:filter]
|
41
|
+
filter = Hpath::Filter.new(path[:filter])
|
42
|
+
end
|
43
|
+
|
28
44
|
if path[:identifier]
|
29
|
-
|
45
|
+
if path[:identifier] == "**"
|
46
|
+
object = _dfs(object, filter)
|
47
|
+
else
|
48
|
+
object = _resolve_identifier(object, path[:identifier])
|
49
|
+
end
|
30
50
|
elsif path[:axis] == "parent"
|
31
51
|
object = parent
|
32
52
|
end
|
@@ -37,7 +57,7 @@ module Hpath
|
|
37
57
|
object = _resolve_keys(object, path[:keys])
|
38
58
|
end
|
39
59
|
|
40
|
-
|
60
|
+
if filter && !(path[:identifier] && path[:identifier] == "**")
|
41
61
|
object = _apply_filters(object, Hpath::Filter.new(path[:filter]))
|
42
62
|
end
|
43
63
|
|
data/lib/hpath/filter.rb
CHANGED
@@ -7,6 +7,8 @@ class Hpath::Filter
|
|
7
7
|
@children = filter_hash.values.first.map do |element|
|
8
8
|
Hpath::Filter.new(element)
|
9
9
|
end
|
10
|
+
elsif @type == :key_existence_filter
|
11
|
+
@key = filter_hash[:key_existence_filter][:key]
|
10
12
|
elsif @type == :key_value_filter
|
11
13
|
@key = filter_hash[:key_value_filter][:key]
|
12
14
|
@value = filter_hash[:key_value_filter][:value]
|
@@ -18,6 +20,10 @@ class Hpath::Filter
|
|
18
20
|
@children.all? { |child_filter| child_filter.applies?(object) }
|
19
21
|
elsif @type == :or_filter
|
20
22
|
@children.any? { |child_filter| child_filter.applies?(object) }
|
23
|
+
elsif @type == :key_existence_filter
|
24
|
+
if object.is_a?(Hash)
|
25
|
+
object.keys.include?(@key.to_s) || object.keys.include?(@key.to_sym)
|
26
|
+
end
|
21
27
|
elsif @type == :key_value_filter
|
22
28
|
if object.is_a?(Hash) && (@value.is_a?(String) || @value.is_a?(Symbol))
|
23
29
|
object[@key.to_s] == @value.to_s || object[@key.to_sym] == @value.to_s ||
|
data/lib/hpath/parser.rb
CHANGED
@@ -34,6 +34,10 @@ class Hpath::Parser
|
|
34
34
|
rule(:space) { match('\s').repeat(1) }
|
35
35
|
rule(:space?) { space.maybe }
|
36
36
|
|
37
|
+
rule(:key_existence_filter) {
|
38
|
+
space? >> match['0-9a-zA-Z@_'].repeat(1).as(:key) >> str("?") >> space?
|
39
|
+
}
|
40
|
+
|
37
41
|
rule(:key_value_filter) {
|
38
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?
|
39
43
|
}
|
@@ -53,7 +57,7 @@ class Hpath::Parser
|
|
53
57
|
}
|
54
58
|
|
55
59
|
rule(:filter) {
|
56
|
-
space? >> (or_filter.as(:or_filter) | and_filter.as(:and_filter) | key_value_filter.as(:key_value_filter)).as(:filter) >> space?
|
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?
|
57
61
|
}
|
58
62
|
|
59
63
|
rule(:keys) {
|
@@ -99,6 +103,10 @@ class Hpath::Parser
|
|
99
103
|
}
|
100
104
|
}
|
101
105
|
|
106
|
+
rule(key: simple(:key)) {
|
107
|
+
{ key: key.nil? ? nil : key.to_sym }
|
108
|
+
}
|
109
|
+
|
102
110
|
rule(key: simple(:key), operator: simple(:operator), value: simple(:value)) {
|
103
111
|
{ key: key.nil? ? nil : key.to_sym, operator: operator.to_s, value: value.to_s }
|
104
112
|
}
|
data/lib/hpath/version.rb
CHANGED
data/spec/hpath/filter_spec.rb
CHANGED
@@ -1,4 +1,16 @@
|
|
1
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
|
+
|
2
14
|
context "initialized with a (nested) filter hash" do
|
3
15
|
let(:filter_hash) { Hpath::Parser.new.parse("/array/*[a=b,c=d,(e=d|e=f)]")[:path].first[:filter] }
|
4
16
|
|
data/spec/hpath_spec.rb
CHANGED
@@ -30,7 +30,7 @@ describe Hpath do
|
|
30
30
|
|
31
31
|
it "processes \"/*\" for a hash" do
|
32
32
|
hpath_result = Hpath.get({a: "b", c: "d"}, "/*")
|
33
|
-
expect(hpath_result).to eq([{a
|
33
|
+
expect(hpath_result).to eq([{:a=>"b"}, {:c=>"d"}])
|
34
34
|
end
|
35
35
|
|
36
36
|
it "processes \"/[key1, key2]\" for a hash" do
|
@@ -67,6 +67,42 @@ describe Hpath do
|
|
67
67
|
hpath_result = Hpath.get([{ foo: { bar: "foobar" } }], "/[0]/::parent")
|
68
68
|
expect(hpath_result).to eq([{ foo: { bar: "foobar" } }])
|
69
69
|
end
|
70
|
+
|
71
|
+
it "processes \"/**[filter]\"" do
|
72
|
+
hpath_result = Hpath.get({
|
73
|
+
query: {
|
74
|
+
bool: {
|
75
|
+
must: [
|
76
|
+
{
|
77
|
+
query_string: {
|
78
|
+
query: "linux",
|
79
|
+
fields: ["_all", "title^2"]
|
80
|
+
}
|
81
|
+
},
|
82
|
+
{
|
83
|
+
query_string: {
|
84
|
+
query: "kofler",
|
85
|
+
fields: ["creator"]
|
86
|
+
}
|
87
|
+
}
|
88
|
+
],
|
89
|
+
should: [
|
90
|
+
{
|
91
|
+
query_string: {
|
92
|
+
query: "linux",
|
93
|
+
fields: ["subject"]
|
94
|
+
}
|
95
|
+
}
|
96
|
+
]
|
97
|
+
}
|
98
|
+
}
|
99
|
+
}, "/**[query_string?]")
|
100
|
+
expect(hpath_result).to eq(
|
101
|
+
[{:query_string=>{:query=>"linux", :fields=>["_all", "title^2"]}},
|
102
|
+
{:query_string=>{:query=>"kofler", :fields=>["creator"]}},
|
103
|
+
{:query_string=>{:query=>"linux", :fields=>["subject"]}}]
|
104
|
+
)
|
105
|
+
end
|
70
106
|
end
|
71
107
|
|
72
108
|
describe "returns nil for non-matching hpath expressions" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hpath
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
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-06-
|
11
|
+
date: 2014-06-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parslet
|
@@ -84,6 +84,7 @@ files:
|
|
84
84
|
- LICENSE.txt
|
85
85
|
- README.md
|
86
86
|
- Rakefile
|
87
|
+
- TODO.md
|
87
88
|
- hpath.gemspec
|
88
89
|
- lib/hpath.rb
|
89
90
|
- lib/hpath/filter.rb
|