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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ae758397369c5c2d912cd7a10b7377683709574d
4
- data.tar.gz: e55ba308d80557c51374868351b2a74c65abc61c
3
+ metadata.gz: 48e68e9a43e8aa6503dfe2d32f11d7f23d64c91c
4
+ data.tar.gz: 38d8d636bd3036953d60ad0a6aed7f26630fee60
5
5
  SHA512:
6
- metadata.gz: 4fd4f632561c47eb0518b37b28ee9b1d4fcac108ba9f2758378128c7921f1f5ddf957fa9d33651ab2f50afb4c36c996b2df01b21bfa61cbcb074a102b3285ca5
7
- data.tar.gz: 6dd7f7123466bebc8dcbdbdb96b6272f6ca29568f565bf4a5a1aeddca53701fb6e84dbab3e073552b5dcbe77487cf799b6e8ea81826fb942f319c543d8505601
6
+ metadata.gz: 6712f8e3953f4956553e8bfb562a06d56276d0186ceaae1d0e4df06ac12c74db9b804ab27c18795833f99e81c4da86ec4fae138728174e65598b82c06b5108e5
7
+ data.tar.gz: 2a6a9cc297711ca0554b2b124faadfffa2ade0b57374bf44485369a0a5fc519169e7ef6e0937a9c1c8f55bb617919073706f47012b10eb3e56ae05787b8af14c
data/TODO.md ADDED
@@ -0,0 +1,7 @@
1
+ # TODO
2
+
3
+ * detection of scalar datatypes
4
+ * integers, floats, strings, bool
5
+ * string overwrite with [key="value"]
6
+ * functions
7
+ * /search(foo)/price/sum()
@@ -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
- object = _resolve_identifier(object, path[:identifier])
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
- unless path[:filter].nil?
60
+ if filter && !(path[:identifier] && path[:identifier] == "**")
41
61
  object = _apply_filters(object, Hpath::Filter.new(path[:filter]))
42
62
  end
43
63
 
@@ -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 ||
@@ -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
  }
@@ -1,3 +1,3 @@
1
1
  module Hpath
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
@@ -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
 
@@ -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: "b"}, {c: "d"}])
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.5
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-10 00:00:00.000000000 Z
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