hpath 0.0.1 → 0.0.2

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: 0b2a7bf6f795402f608054a5ff3bda6911c9fa46
4
- data.tar.gz: 268739d05a0fba52a2749607a0a58ed15f9b3c86
3
+ metadata.gz: d97f5894eb225d22238c604ab0fc4e06a31e5fa1
4
+ data.tar.gz: a52d7400d901e41584dafb8613048358cfb78a2f
5
5
  SHA512:
6
- metadata.gz: 89828fbd36cda4309defa91141f7db48f6718c77a8fe78b7c0d4add014c2070b82e34ae92aa830be2cd710d307665c6bd50730e8373acc7a31d218afcdfb4902
7
- data.tar.gz: ff88f0679aa35a6d674de076774c8c51f5589998054a1679ef8e222f23c166095076d165000f511ec4e9f71a5ad9d8876ea31e341518ba4616ccda3662418087
6
+ metadata.gz: 7ed6a57ed11bd16a296a6572ea282190960f0f60ca925d7226c469c461948c9bdc89e10972fed14221316c0fa138382cabf6c10b9a05485bbcf524b1b49f3bc1
7
+ data.tar.gz: 3e0bb084b7274f51c8c53bd175ee3992f7049d3689d257f9851a31376ce88bd01cc8e6800d3a105c761869fd3e8f7fb3497b064c66b004f3f3c2abbf16368af4
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format documentation
3
+ --require spec_helper
data/Gemfile CHANGED
@@ -1,4 +1,9 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in hpath.gemspec
4
4
  gemspec
5
+
6
+ gem "pry", "~> 0.9.12.6"
7
+ gem "pry-nav", "~> 0.2.3"
8
+ gem "pry-stack_explorer", "~> 0.4.9.1"
9
+ gem "pry-syntax-hacks", "~> 0.0.6"
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Hpath
2
2
 
3
- TODO: Write a gem description
3
+ This code is heavy work in progress and does not work today. The examples and usage hints given below only show the goals.
4
4
 
5
5
  ## Installation
6
6
 
@@ -18,7 +18,125 @@ Or install it yourself as:
18
18
 
19
19
  ## Usage
20
20
 
21
- TODO: Write usage instructions here
21
+ Here are some examples of hpath in action.
22
+
23
+ ```ruby
24
+ record = {
25
+ title: "About a hash",
26
+ creator: [
27
+ "Hashman",
28
+ "Hashboy"
29
+ ],
30
+ price: [
31
+ { currency: :USD, value: 12.99 },
32
+ { currency: :EUR, value: 8.99 }
33
+ ],
34
+ subject: [
35
+ { type: "automatic", value: "hash" },
36
+ { type: "automatic", value: "hashes" },
37
+ { type: "automatic", value: "ruby" },
38
+ { type: "manual", value: "hash" },
39
+ { type: "manual", value: "array" },
40
+ { type: "manual", value: "Hashman" },
41
+ { type: "manual", value: "Hashboy" },
42
+ ],
43
+ _source: {
44
+ "id" => "123",
45
+ "title" => "<h1>About a hash</h1>",
46
+ ...
47
+ }
48
+ }
49
+
50
+ Hpath.get record, "/title"
51
+ # => "About a hash"
52
+
53
+ Hpath.get record, "/_source/id"
54
+ # => "123"
55
+
56
+ Hpath.get record, "/_source/[id, title]"
57
+ # => { "id" => "123", "title" => "<h1>About a hash</h1>" }
58
+
59
+ Hpath.get record, "/price/*[currency=USD]"
60
+ # => [{ currency: :USD, value: 12.99 }]
61
+
62
+ Hpath.get record, "/price/*[currency=USD,value<10]"
63
+ # => nil
64
+
65
+ Hpath.get record, "/price/*[(currency=USD|currency=EUR),value<10]"
66
+ # => [{ currency: :EUR, value: 8.99 }]
67
+
68
+ Hpath.get record, "/subject/*[type=automatic]"
69
+ # => [
70
+ # { type: "automatic", value: "hash" },
71
+ # { type: "automatic", value: "hashes" },
72
+ # { type: "automatic", value: "ruby" }
73
+ # ]
74
+
75
+ Hpath.get record, "/subject/*[type=automatic]/type"
76
+ # => ["automatic", "automatic", "automatic"]
77
+ ```
78
+
79
+ ## Syntax
80
+
81
+ ### `/`
82
+ Get the root element.
83
+
84
+ ```ruby
85
+ Hpath.get [:a,:b,:c], "/"
86
+ # => [:a,:b,:c]
87
+ ```
88
+
89
+ ### `/[n]`
90
+ Get the n-th element of an array.
91
+
92
+ ```ruby
93
+ Hpath.get [:a,:b,:c], "/[1]"
94
+ # => :a
95
+ ```
96
+
97
+ ### `/[n,m,...]`
98
+ Get the n-th, m-th and ... element of an array.
99
+
100
+ ```ruby
101
+ Hpath.get [:a,:b,:c], "/[1,2]"
102
+ # => [:a,:b]
103
+ ```
104
+
105
+ ### `/[key1, key2, ...]`
106
+ If current element is a hash, get a hash only with the given keys. Since it cannot be determined, if the key is a symbol or a string, both interpretations are checked. If the current object is not a hash, but has methods named `key1, key2`, this methods are called and the results are returned.
107
+
108
+ ```ruby
109
+ Hpath.get {a: "b", c: "d", e: "f"}, "/[a,c]"
110
+ # => {a: "b", c: "d"}
111
+ ```
112
+
113
+ ### `/*`
114
+ Get all elements of the current root element. If it's a array, this simply returns the array. If it's a hash, an array of all key/value pairs is returned.
115
+
116
+ ```ruby
117
+ Hpath.get [:a,:b,:c], "/*"
118
+ # => [:a,:b,:c]
119
+ ```
120
+
121
+ ```ruby
122
+ Hpath.get {a: "b", c: "d", e: "f"}, "/*"
123
+ # => [{a: "b"}, {c: "d"}, {e: "f"}]
124
+ ```
125
+
126
+ ### `/key`
127
+ If the current element is a hash, return the value of the given key. If the current element is not a hash, but has a method named `key`, this method is called and the result is returned.
128
+
129
+ ```ruby
130
+ Hpath.get {a: { b: "c" } }, "/a"
131
+ # => { b: "c" }
132
+ ```
133
+
134
+ If the current element is an array, the non-array behaviour is applied to all members of the array.
135
+
136
+ ```ruby
137
+ Hpath.get([{a:"1", b:"2", c:"3"}, {a:"2", b:"5", c:"6"}], "/a")
138
+ # => ["1", "2"]
139
+ ```
22
140
 
23
141
  ## Contributing
24
142
 
data/Rakefile CHANGED
@@ -1 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/hpath.gemspec CHANGED
@@ -1,13 +1,12 @@
1
1
  # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
2
+ lib = File.expand_path("../lib", __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'hpath/version'
4
+ require "hpath/version"
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "hpath"
8
8
  spec.version = Hpath::VERSION
9
9
  spec.authors = ["Michael Sievers"]
10
- #spec.email = ["michael_sievers@web.de"]
11
10
  spec.summary = %q{HPath for ruby}
12
11
  spec.homepage = "https://github.com/hpath/hpath-ruby"
13
12
  spec.license = "MIT"
@@ -17,6 +16,9 @@ Gem::Specification.new do |spec|
17
16
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
17
  spec.require_paths = ["lib"]
19
18
 
19
+ spec.add_dependency "parslet", ">= 1.6.1"
20
+
20
21
  spec.add_development_dependency "bundler", "~> 1.5"
21
22
  spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec", ">= 3.0.0", "< 4.0.0"
22
24
  end
data/lib/hpath.rb CHANGED
@@ -1,5 +1,93 @@
1
- require "hpath/version"
2
-
3
1
  module Hpath
4
- # Your code goes here...
2
+ require "hpath/filter"
3
+ require "hpath/parser"
4
+ require "hpath/version"
5
+
6
+ def self.get(object, hpath_string)
7
+ hpath = Hpath::Parser.parse(hpath_string)
8
+ _get(object, hpath[:path])
9
+ end
10
+
11
+ #
12
+ private
13
+ #
14
+ def self._get(object, paths, parent = object)
15
+ _object = object
16
+
17
+ if paths.empty?
18
+ return object
19
+ else
20
+ path = paths.shift
21
+ end
22
+
23
+ if path[:identifier]
24
+ object = _resolve_identifier(object, path[:identifier])
25
+ elsif path[:axis] == "parent"
26
+ object = parent
27
+ end
28
+
29
+ if path[:indices]
30
+ object = _resolve_indices(object, path[:indices])
31
+ elsif path[:keys]
32
+ object = _resolve_keys(object, path[:keys])
33
+ end
34
+
35
+ unless path[:filter].nil?
36
+ object = _apply_filters(object, Hpath::Filter.new(path[:filter]))
37
+ end
38
+
39
+ self._get(object, paths, _object)
40
+ end
41
+
42
+ def self._apply_filters(object, filter)
43
+ if object.is_a?(Array)
44
+ object.select do |element|
45
+ filter.applies?(element)
46
+ end
47
+ else
48
+ #binding.pry
49
+ end
50
+ end
51
+
52
+ def self._resolve_identifier(object, identifier)
53
+ if object.is_a?(Array)
54
+ if identifier.to_s == "*"
55
+ object
56
+ else
57
+ object.map do |element|
58
+ if element.is_a?(Hash)
59
+ element[identifier.to_s] || element[identifier.to_sym]
60
+ elsif element.respond_to?(identifier)
61
+ element.send(identifier)
62
+ else
63
+ raise "Cannot apply identifier to collection object!"
64
+ end
65
+ end
66
+ end
67
+ elsif object.is_a?(Hash)
68
+ if identifier.to_s == "*"
69
+ object.map { |key, value| {key => value} }
70
+ else
71
+ object[identifier.to_s] || object[identifier.to_sym]
72
+ end
73
+ else
74
+ #binding.pry
75
+ end
76
+ end
77
+
78
+ def self._resolve_indices(object, indices)
79
+ if indices.length == 1
80
+ object[indices.first]
81
+ else
82
+ indices.map { |index| object[index] }
83
+ end
84
+ end
85
+
86
+ def self._resolve_keys(object, keys)
87
+ if object.is_a?(Hash)
88
+ object.select { |key, value| keys.include?(key.to_s) || keys.include?(key.to_sym) }
89
+ else
90
+ raise "Cannot resolve keys for non-hash objects!"
91
+ end
92
+ end
5
93
  end
@@ -0,0 +1,33 @@
1
+ class Hpath::Filter
2
+
3
+ def initialize(filter_hash)
4
+ @type = filter_hash.keys.first
5
+
6
+ if @type == :and_filter || @type == :or_filter
7
+ @children = filter_hash.values.first.map do |element|
8
+ Hpath::Filter.new(element)
9
+ end
10
+ elsif @type == :key_value_filter
11
+ @key = filter_hash[:key_value_filter][:key]
12
+ @value = filter_hash[:key_value_filter][:value]
13
+ end
14
+ end
15
+
16
+ def applies?(object)
17
+ if @type == :and_filter
18
+ @children.all? { |child_filter| child_filter.applies?(object) }
19
+ elsif @type == :or_filter
20
+ @children.any? { |child_filter| child_filter.applies?(object) }
21
+ elsif @type == :key_value_filter
22
+ if object.is_a?(Hash) && (@value.is_a?(String) || @value.is_a?(Symbol))
23
+ object[@key.to_s] == @value.to_s || object[@key.to_sym] == @value.to_s ||
24
+ object[@key.to_s] == @value.to_sym || object[@key.to_sym] == @value.to_sym
25
+ else
26
+ if object.respond_to(@key)
27
+ object.send(@key) == @value
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,105 @@
1
+ require "parslet"
2
+
3
+ class Hpath::Parser
4
+ def self.parse(string)
5
+ self.new.parse(string)
6
+ end
7
+
8
+ def parse(string)
9
+ transform(normalize(parser.parse(string)))
10
+ end
11
+
12
+ #
13
+ private
14
+ #
15
+ def normalize(result_tree) # to ease transformation
16
+ result_tree[:path].map! do |element|
17
+ element[:axis] ||= nil
18
+ element[:identifier] ||= nil
19
+ element[:filter] ||= nil
20
+ element[:indices] ||= nil
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
25
+ end
26
+
27
+ result_tree
28
+ end
29
+
30
+ def parser
31
+ @parser ||=
32
+ Class.new(Parslet::Parser) do
33
+ rule(:space) { match('\s').repeat(1) }
34
+ rule(:space?) { space.maybe }
35
+
36
+ rule(:key_value_filter) {
37
+ space? >> match['a-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?
38
+ }
39
+
40
+ rule(:or_filter) {
41
+ ((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))
42
+ }
43
+
44
+ rule(:primary) {
45
+ str("(") >> or_filter.as(:or_filter) >> str(")")
46
+ }
47
+
48
+ rule(:and_filter) {
49
+ ((primary | key_value_filter.as(:key_value_filter)) >>
50
+ str(",")).repeat(1) >>
51
+ (primary | key_value_filter.as(:key_value_filter))
52
+ }
53
+
54
+ rule(:filter) {
55
+ space? >> (or_filter.as(:or_filter) | and_filter.as(:and_filter) | key_value_filter.as(:key_value_filter)).as(:filter) >> space?
56
+ }
57
+
58
+ rule(:keys) {
59
+ match('[a-zA-Z0-9]').repeat(1).as(:key) >> (space? >> str(",") >> space? >> match('[a-zA-Z0-9]').repeat(1).as(:key)).repeat
60
+ }
61
+
62
+ rule(:indices) {
63
+ match('[0-9]').repeat(1).as(:index) >> (space? >> str(",") >> match('[0-9]').repeat(1).as(:index)).repeat
64
+ }
65
+
66
+ rule(:identifier) {
67
+ match('[a-zA-Z0-9*_]').repeat(1)
68
+ }
69
+
70
+ rule(:node) {
71
+ str("/") >> (identifier.as(:identifier) | (str("::") >> identifier.as(:axis))).maybe >> (str("[") >> space? >> (indices.as(:indices) | filter | keys.as(:keys)) >> space? >> str("]")).maybe
72
+ }
73
+
74
+ rule(:path) {
75
+ node.repeat(1).as(:path)
76
+ }
77
+
78
+ # root
79
+ root(:path)
80
+ end.new
81
+ end
82
+
83
+ def transform(result_tree)
84
+ transformation.apply(result_tree)
85
+ end
86
+
87
+ def transformation
88
+ @transformation ||=
89
+ Class.new(Parslet::Transform) do
90
+ rule(axis: simple(:axis), identifier: simple(:identifier), filter: subtree(:filter), indices: subtree(:indices), keys: subtree(:keys)) {
91
+ {
92
+ axis: axis.nil? ? nil : axis.to_s,
93
+ identifier: identifier.nil? ? nil : identifier.to_s,
94
+ filter: filter,
95
+ indices: indices.nil? ? nil : indices.map { |element| Integer(element[:index]) },
96
+ keys: keys.nil? ? nil : keys.map { |element| element[:key].to_s.to_sym }
97
+ }
98
+ }
99
+
100
+ rule(key: simple(:key), operator: simple(:operator), value: simple(:value)) {
101
+ { key: key.nil? ? nil : key.to_sym, operator: operator.to_s, value: value.to_s }
102
+ }
103
+ end.new
104
+ end
105
+ end
data/lib/hpath/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Hpath
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -0,0 +1,15 @@
1
+ describe Hpath::Filter do
2
+ context "initialized with a (nested) filter hash" do
3
+ let(:filter_hash) { Hpath::Parser.new.parse("/array/*[a=b,c=d,(e=d|e=f)]")[:path].first[:filter] }
4
+
5
+ describe ".filter" do
6
+ context "when given object is an array containing hashes" do
7
+ let(:filter) { Hpath::Filter.new(Hpath::Parser.new.parse("/array/*[a=b,c=d,(e=d|e=f)]")[:path][1][:filter]) }
8
+
9
+ it "returns only hashes which match the filter" do
10
+ #w = [{a: "b", c: "d", e: "f"}, {a: "b", c: "d", e: "z"}].select { |e| filter.applies?(e) }
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,26 @@
1
+ describe Hpath::Parser do
2
+ let(:parser) { Hpath::Parser.new }
3
+
4
+ it "parses a hpath string into a tree structure" do
5
+ =begin
6
+ expect(parser.parse("/foo/bar/*[a=b,c=d,(e<d|e>f)]/foo[1]/bar[<10]")).to eq(
7
+ {:path=>
8
+ [{:identifier=>:foo, :filter=>nil, :index=>nil},
9
+ {:identifier=>:bar, :filter=>nil, :index=>nil},
10
+ {:identifier=>:*,
11
+ :filter=>
12
+ {:and_filter=>
13
+ [{:key_value_filter=>{:key=>:a, :operator=>"=", :value=>"b"}},
14
+ {:key_value_filter=>{:key=>:c, :operator=>"=", :value=>"d"}},
15
+ {:or_filter=>
16
+ [{:key_value_filter=>{:key=>:e, :operator=>"<", :value=>"d"}},
17
+ {:key_value_filter=>{:key=>:e, :operator=>">", :value=>"f"}}]}]},
18
+ :index=>nil},
19
+ {:identifier=>:foo, :filter=>nil, :index=>1},
20
+ {:identifier=>:bar,
21
+ :filter=>{:key_value_filter=>{:key=>nil, :operator=>"<", :value=>"10"}},
22
+ :index=>nil}]}
23
+ )
24
+ =end
25
+ end
26
+ end
@@ -0,0 +1,70 @@
1
+ describe Hpath do
2
+ describe "#get" do
3
+ describe "returns the corresponding value from the given object" do
4
+ it "processes \"/key\" for a nested hash" do
5
+ hpath_result = Hpath.get({ foo: { bar: 1 } }, "/foo")
6
+ expect(hpath_result).to eq({ bar: 1 })
7
+ end
8
+
9
+ it "processes \"/[n]\" for an array" do
10
+ hpath_result = Hpath.get([1,2,3], "/[0]")
11
+ expect(hpath_result).to eq(1)
12
+ end
13
+
14
+ it "processes \"/[m,n]\" for an array" do
15
+ hpath_result = Hpath.get([1,2,3], "/[0,1]")
16
+ expect(hpath_result).to eq([1,2])
17
+ end
18
+
19
+ it "processes \"/key1/key2\" for a nested hash" do
20
+ hpath_result = Hpath.get({ foo: { bar: 1 } }, "/foo/bar")
21
+ expect(hpath_result).to eq(1)
22
+ end
23
+
24
+ it "processes \"/*\" for an array" do
25
+ hpath_result = Hpath.get([1,2,3], "/*")
26
+ expect(hpath_result).to eq([1,2,3])
27
+ end
28
+
29
+ it "processes \"/*\" for a hash" do
30
+ hpath_result = Hpath.get({a: "b", c: "d"}, "/*")
31
+ expect(hpath_result).to eq([{a: "b"}, {c: "d"}])
32
+ end
33
+
34
+ it "processes \"/[key1, key2]\" for a hash" do
35
+ hpath_result = Hpath.get({a: 1, b: 2, "c" => 3}, "/[a,c]")
36
+ expect(hpath_result).to eq({a: 1, "c" => 3})
37
+ end
38
+
39
+ it "processes \"/[key=value]\" for a array of hashes" do
40
+ hpath_result = Hpath.get([{a: "foo"}, {a: "bar"}, { "a" => :bar }, {a: "muff"}], "/[a=bar]")
41
+ expect(hpath_result).to eq([{:a=>"bar"}, {"a"=>:bar}])
42
+ end
43
+
44
+ it "processes \"/[key1=value1,key2=value2]\" for a array of hashes" do
45
+ hpath_result = Hpath.get([{a:"1", b:"2", c:"3"}, {"a" => "1", "b" => "2", c:"3"}, {a:"2", b:"1", c:"3"}], "/[a=1,b=2]")
46
+ expect(hpath_result).to eq([{:a=>"1", :b=>"2", :c=>"3"}, {"a"=>"1", "b"=>"2", :c=>"3"}])
47
+ end
48
+
49
+ it "processes \"/[key1=value1,(key2=value2|key3=value3)]\" for a array of hashes" do
50
+ hpath_result = Hpath.get([{a:"1", b:"2", c:"3"}, {a:"1", b:"5", c:"6"}, {a:"2", b:"1", c:"3"}], "/[a=1,(b=5|c=3)]")
51
+ expect(hpath_result).to eq([{:a=>"1", :b=>"2", :c=>"3"}, {:a=>"1", :b=>"5", :c=>"6"}])
52
+ end
53
+
54
+ it "processes \"/array/key\" for an array of hashes" do
55
+ hpath_result = Hpath.get([{a:"1", b:"2", c:"3"}, {a:"1", b:"5", c:"6"}, {a:"2", b:"1", c:"3"}], "/a")
56
+ expect(hpath_result).to eq(["1", "1", "2"])
57
+ end
58
+
59
+ it "processes \"/key1/::parent\" for a hash" do
60
+ hpath_result = Hpath.get({ foo: { bar: "foobar" } }, "/foo/::parent")
61
+ expect(hpath_result).to eq({ foo: { bar: "foobar" } })
62
+ end
63
+
64
+ it "processes \"/[n]/::parent\" for an array of hashes" do
65
+ hpath_result = Hpath.get([{ foo: { bar: "foobar" } }], "/[0]/::parent")
66
+ expect(hpath_result).to eq([{ foo: { bar: "foobar" } }])
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,12 @@
1
+ require "hpath"
2
+ begin
3
+ require "pry"
4
+ rescue LoadError
5
+ end
6
+
7
+ RSpec.configure do |config|
8
+ end
9
+
10
+ def read_asset(path_to_file)
11
+ File.read(File.expand_path(File.join(File.dirname(__FILE__), "assets", path_to_file)))
12
+ end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hpath
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
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-04 00:00:00.000000000 Z
11
+ date: 2014-06-10 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
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,6 +52,26 @@ dependencies:
38
52
  - - ">="
39
53
  - !ruby/object:Gem::Version
40
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 3.0.0
62
+ - - "<"
63
+ - !ruby/object:Gem::Version
64
+ version: 4.0.0
65
+ type: :development
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: 3.0.0
72
+ - - "<"
73
+ - !ruby/object:Gem::Version
74
+ version: 4.0.0
41
75
  description:
42
76
  email:
43
77
  executables: []
@@ -45,13 +79,20 @@ extensions: []
45
79
  extra_rdoc_files: []
46
80
  files:
47
81
  - ".gitignore"
82
+ - ".rspec"
48
83
  - Gemfile
49
84
  - LICENSE.txt
50
85
  - README.md
51
86
  - Rakefile
52
87
  - hpath.gemspec
53
88
  - lib/hpath.rb
89
+ - lib/hpath/filter.rb
90
+ - lib/hpath/parser.rb
54
91
  - lib/hpath/version.rb
92
+ - spec/hpath/filter_spec.rb
93
+ - spec/hpath/parser_spec.rb
94
+ - spec/hpath_spec.rb
95
+ - spec/spec_helper.rb
55
96
  homepage: https://github.com/hpath/hpath-ruby
56
97
  licenses:
57
98
  - MIT
@@ -76,4 +117,8 @@ rubygems_version: 2.2.0
76
117
  signing_key:
77
118
  specification_version: 4
78
119
  summary: HPath for ruby
79
- test_files: []
120
+ test_files:
121
+ - spec/hpath/filter_spec.rb
122
+ - spec/hpath/parser_spec.rb
123
+ - spec/hpath_spec.rb
124
+ - spec/spec_helper.rb