hpath 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
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