hpath 0.0.1 → 0.0.2

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: 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