xpath 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ce787a09ca48f5c96580cbced2533d00b741a0e3
4
+ data.tar.gz: c4310006453b0029c593077b225d36e79dfd35af
5
+ SHA512:
6
+ metadata.gz: 83b64861c13aecd52661c7cbc598f90c4a17aeb71c86936f0bec36d97ffe4248fc8302cad434742b95074b6aded1de563c33a3f82df12e4baf42d10c42d132ac
7
+ data.tar.gz: bc2e7c29f1240475904601bc7f8ad2ecda2978536b97e1ab407bc855ec16b7f64b48cc49400a501833bb8ac643bcc8b1e2052d4a05974c3df7ca0355ac26fe4e
data/README.md CHANGED
@@ -3,7 +3,8 @@
3
3
  XPath is a Ruby DSL around a subset of XPath 1.0. Its primary purpose is to
4
4
  facilitate writing complex XPath queries from Ruby code.
5
5
 
6
- [![Build Status](https://secure.travis-ci.org/jnicklas/xpath.png?branch=master)](http://travis-ci.org/jnicklas/xpath)
6
+ [![Gem Version](https://badge.fury.io/rb/xpath.png)](http://badge.fury.io/rb/xpath)
7
+ [![Build Status](https://secure.travis-ci.org/teamcapybara/xpath.png?branch=master)](http://travis-ci.org/teamcapybara/xpath)
7
8
 
8
9
  ## Generating expressions
9
10
 
@@ -36,11 +37,9 @@ module MyXPaths
36
37
  end
37
38
  ```
38
39
 
39
- Both ways return an
40
- [`XPath::Expression`](http://rdoc.info/github/jnicklas/xpath/XPath/Expression)
41
- instance, which can be further modified. To convert the expression to a
42
- string, just call `#to_s` on it. All available expressions are defined in
43
- [`XPath::DSL`](http://rdoc.info/github/jnicklas/xpath/XPath/DSL).
40
+ Both ways return an `XPath::Expression` instance, which can be further
41
+ modified. To convert the expression to a string, just call `#to_s` on it. All
42
+ available expressions are defined in `XPath::DSL`.
44
43
 
45
44
  ## String, Hashes and Symbols
46
45
 
@@ -74,63 +73,6 @@ XPath.descendant(:p)[1]
74
73
  Keep in mind that XPath is 1-indexed and not 0-indexed like most other
75
74
  programming languages, including Ruby.
76
75
 
77
- Hashes are automatically converted to equality expressions, so the above
78
- example could be written as:
79
-
80
- ``` ruby
81
- XPath.descendant(:p)[:@id => 'foo']
82
- ```
83
-
84
- Which would generate the same expression:
85
-
86
- ```
87
- .//p[@id = 'foo']
88
- ```
89
-
90
- Note that the same rules apply here, both the keys and values in the hash are
91
- treated the same way as any other expression in XPath. Thus the following are
92
- not equivalent:
93
-
94
- ``` ruby
95
- XPath.descendant(:p)[:@id => 'foo'] # => .//p[@id = 'foo']
96
- XPath.descendant(:p)[:id => 'foo'] # => .//p[id = 'foo']
97
- XPath.descendant(:p)['id' => 'foo'] # => .//p['id' = 'foo']
98
- ```
99
-
100
- ## HTML
101
-
102
- XPath comes with a set of premade XPaths for use with HTML documents.
103
-
104
- You can generate these like this:
105
-
106
- ``` ruby
107
- XPath::HTML.link('Home')
108
- XPath::HTML.field('Name')
109
- ```
110
-
111
- See [`XPath::HTML`](http://rdoc.info/github/jnicklas/xpath/XPath/HTML) for all
112
- available matchers.
113
-
114
76
  ## License
115
77
 
116
- (The MIT License)
117
-
118
- Copyright © 2010 Jonas Nicklas
119
-
120
- Permission is hereby granted, free of charge, to any person obtaining a copy of
121
- this software and associated documentation files (the ‘Software’), to deal in
122
- the Software without restriction, including without limitation the rights to
123
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
124
- of the Software, and to permit persons to whom the Software is furnished to do
125
- so, subject to the following conditions:
126
-
127
- The above copyright notice and this permission notice shall be included in all
128
- copies or substantial portions of the Software.
129
-
130
- THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
131
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
132
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
133
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
134
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
135
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
136
- SOFTWARE.
78
+ See [LICENSE](LICENSE).
@@ -8,9 +8,8 @@ require 'xpath/renderer'
8
8
  require 'xpath/html'
9
9
 
10
10
  module XPath
11
-
12
- extend XPath::DSL::TopLevel
13
- include XPath::DSL::TopLevel
11
+ extend XPath::DSL
12
+ include XPath::DSL
14
13
 
15
14
  def self.generate
16
15
  yield(self)
@@ -1,112 +1,147 @@
1
1
  module XPath
2
2
  module DSL
3
- module TopLevel
4
- def current
5
- Expression.new(:this_node)
6
- end
7
-
8
- def name
9
- Expression.new(:node_name, current)
10
- end
3
+ def current
4
+ Expression.new(:this_node)
5
+ end
11
6
 
12
- def descendant(*expressions)
13
- Expression.new(:descendant, current, expressions)
14
- end
7
+ def descendant(*expressions)
8
+ Expression.new(:descendant, current, expressions)
9
+ end
15
10
 
16
- def child(*expressions)
17
- Expression.new(:child, current, expressions)
18
- end
11
+ def child(*expressions)
12
+ Expression.new(:child, current, expressions)
13
+ end
19
14
 
20
- def axis(name, tag_name=:*)
21
- Expression.new(:axis, current, name, tag_name)
22
- end
15
+ def axis(name, *element_names)
16
+ Expression.new(:axis, current, name, element_names)
17
+ end
23
18
 
24
- def next_sibling(*expressions)
25
- Expression.new(:next_sibling, current, expressions)
26
- end
19
+ def anywhere(*expressions)
20
+ Expression.new(:anywhere, expressions)
21
+ end
27
22
 
28
- def previous_sibling(*expressions)
29
- Expression.new(:previous_sibling, current, expressions)
30
- end
23
+ def attr(expression)
24
+ Expression.new(:attribute, current, expression)
25
+ end
31
26
 
32
- def anywhere(*expressions)
33
- Expression.new(:anywhere, expressions)
34
- end
27
+ def text
28
+ Expression.new(:text, current)
29
+ end
35
30
 
36
- def attr(expression)
37
- Expression.new(:attribute, current, expression)
38
- end
31
+ def css(selector)
32
+ Expression.new(:css, current, Literal.new(selector))
33
+ end
39
34
 
40
- def contains(expression)
41
- Expression.new(:contains, current, expression)
42
- end
35
+ def function(name, *arguments)
36
+ Expression.new(:function, name, *arguments)
37
+ end
43
38
 
44
- def starts_with(expression)
45
- Expression.new(:starts_with, current, expression)
46
- end
39
+ def method(name, *arguments)
40
+ Expression.new(:function, name, current, *arguments)
41
+ end
47
42
 
48
- def text
49
- Expression.new(:text, current)
50
- end
43
+ def where(expression)
44
+ Expression.new(:where, current, expression)
45
+ end
46
+ alias_method :[], :where
51
47
 
52
- def string
53
- Expression.new(:string_function, current)
54
- end
48
+ def is(expression)
49
+ Expression.new(:is, current, expression)
50
+ end
55
51
 
56
- def css(selector)
57
- Expression.new(:css, current, Literal.new(selector))
58
- end
52
+ def binary_operator(name, rhs)
53
+ Expression.new(:binary_operator, name, current, rhs)
59
54
  end
60
55
 
61
- module ExpressionLevel
62
- include XPath::DSL::TopLevel
56
+ def union(*expressions)
57
+ Union.new(*[self, expressions].flatten)
58
+ end
59
+ alias_method :+, :union
63
60
 
64
- def where(expression)
65
- Expression.new(:where, current, expression)
66
- end
67
- alias_method :[], :where
61
+ def last
62
+ function(:last)
63
+ end
68
64
 
69
- def one_of(*expressions)
70
- Expression.new(:one_of, current, expressions)
71
- end
65
+ def position
66
+ function(:position)
67
+ end
72
68
 
73
- def equals(expression)
74
- Expression.new(:equality, current, expression)
69
+ METHODS = [
70
+ # node set
71
+ :count, :id, :local_name, :namespace_uri, :name,
72
+ # string
73
+ :string, :concat, :starts_with, :contains, :substring_before,
74
+ :substring_after, :substring, :string_length, :normalize_space,
75
+ :translate,
76
+ # boolean
77
+ :boolean, :not, :true, :false, :lang,
78
+ # number
79
+ :number, :sum, :floor, :ceiling, :round,
80
+ ]
81
+
82
+ METHODS.each do |key|
83
+ name = key.to_s.gsub("_", "-").to_sym
84
+ define_method key do |*args|
85
+ method(name, *args)
75
86
  end
76
- alias_method :==, :equals
87
+ end
77
88
 
78
- def is(expression)
79
- Expression.new(:is, current, expression)
80
- end
89
+ alias_method :inverse, :not
90
+ alias_method :~, :not
91
+ alias_method :normalize, :normalize_space
92
+ alias_method :n, :normalize_space
93
+
94
+ OPERATORS = [
95
+ [:equals, :"=", :==],
96
+ [:or, :or, :|],
97
+ [:and, :and, :&],
98
+ [:lte, :<=, :<=],
99
+ [:lt, :<, :<],
100
+ [:gte, :>=, :>=],
101
+ [:gt, :>, :>],
102
+ [:plus, :+],
103
+ [:minus, :-],
104
+ [:multiply, :*, :*],
105
+ [:divide, :div, :/],
106
+ [:mod, :mod, :%],
107
+ ]
108
+
109
+ OPERATORS.each do |(name, operator, alias_name)|
110
+ define_method name do |rhs|
111
+ binary_operator(operator, rhs)
112
+ end
113
+ alias_method alias_name, name if alias_name
114
+ end
81
115
 
82
- def or(expression)
83
- Expression.new(:or, current, expression)
84
- end
85
- alias_method :|, :or
116
+ AXES = [
117
+ :ancestor, :ancestor_or_self, :attribute, :descendant_or_self,
118
+ :following, :following_sibling, :namespace, :parent, :preceding,
119
+ :preceding_sibling, :self,
120
+ ]
86
121
 
87
- def and(expression)
88
- Expression.new(:and, current, expression)
122
+ AXES.each do |key|
123
+ name = key.to_s.gsub("_", "-").to_sym
124
+ define_method key do |*element_names|
125
+ axis(name, *element_names)
89
126
  end
90
- alias_method :&, :and
127
+ end
91
128
 
92
- def union(*expressions)
93
- Union.new(*[self, expressions].flatten)
94
- end
95
- alias_method :+, :union
129
+ alias_method :self_axis, :self
96
130
 
97
- def inverse
98
- Expression.new(:inverse, current)
131
+ def one_of(*expressions)
132
+ expressions.map do |e|
133
+ current.equals(e)
134
+ end.reduce do |a, b|
135
+ a.or(b)
99
136
  end
100
- alias_method :~, :inverse
137
+ end
101
138
 
102
- def string_literal
103
- Expression.new(:string_literal, self)
104
- end
139
+ def next_sibling(*expressions)
140
+ axis(:"following-sibling")[1].axis(:self, *expressions)
141
+ end
105
142
 
106
- def normalize
107
- Expression.new(:normalized_space, current)
108
- end
109
- alias_method :n, :normalize
143
+ def previous_sibling(*expressions)
144
+ axis(:"preceding-sibling")[1].axis(:self, *expressions)
110
145
  end
111
146
  end
112
147
  end
@@ -1,7 +1,7 @@
1
1
  module XPath
2
2
  class Expression
3
3
  attr_accessor :expression, :arguments
4
- include XPath::DSL::ExpressionLevel
4
+ include XPath::DSL
5
5
 
6
6
  def initialize(expression, *arguments)
7
7
  @expression = expression
@@ -1,6 +1,6 @@
1
1
  module XPath
2
2
  module HTML
3
- include XPath::DSL::TopLevel
3
+ include XPath::DSL
4
4
  extend self
5
5
 
6
6
  # Match an `a` link element.
@@ -38,32 +38,20 @@ module XPath
38
38
  '.'
39
39
  end
40
40
 
41
- def descendant(parent, element_names)
42
- if element_names.length == 1
43
- "#{parent}//#{element_names.first}"
44
- elsif element_names.length > 1
45
- "#{parent}//*[#{element_names.map { |e| "self::#{e}" }.join(" | ")}]"
46
- else
47
- "#{parent}//*"
48
- end
41
+ def descendant(current, element_names)
42
+ with_element_conditions("#{current}//", element_names)
49
43
  end
50
44
 
51
- def child(parent, element_names)
52
- if element_names.length == 1
53
- "#{parent}/#{element_names.first}"
54
- elsif element_names.length > 1
55
- "#{parent}/*[#{element_names.map { |e| "self::#{e}" }.join(" | ")}]"
56
- else
57
- "#{parent}/*"
58
- end
45
+ def child(current, element_names)
46
+ with_element_conditions("#{current}/", element_names)
59
47
  end
60
48
 
61
- def axis(parent, name, tag_name)
62
- "#{parent}/#{name}::#{tag_name}"
49
+ def axis(current, name, element_names)
50
+ with_element_conditions("#{current}/#{name}::", element_names)
63
51
  end
64
52
 
65
- def node_name(current)
66
- "name(#{current})"
53
+ def anywhere(element_names)
54
+ with_element_conditions("//", element_names)
67
55
  end
68
56
 
69
57
  def where(on, condition)
@@ -74,15 +62,15 @@ module XPath
74
62
  "#{current}/@#{name}"
75
63
  end
76
64
 
77
- def equality(one, two)
78
- "#{one} = #{two}"
65
+ def binary_operator(name, left, right)
66
+ "(#{left} #{name} #{right})"
79
67
  end
80
68
 
81
69
  def is(one, two)
82
70
  if @type == :exact
83
- equality(one, two)
71
+ binary_operator("=", one, two)
84
72
  else
85
- contains(one, two)
73
+ function(:contains, one, two)
86
74
  end
87
75
  end
88
76
 
@@ -94,10 +82,6 @@ module XPath
94
82
  "#{current}/text()"
95
83
  end
96
84
 
97
- def normalized_space(current)
98
- "normalize-space(#{current})"
99
- end
100
-
101
85
  def literal(node)
102
86
  node
103
87
  end
@@ -113,62 +97,20 @@ module XPath
113
97
  expressions.join(' | ')
114
98
  end
115
99
 
116
- def anywhere(element_names)
117
- if element_names.length == 1
118
- "//#{element_names.first}"
119
- elsif element_names.length > 1
120
- "//*[#{element_names.map { |e| "self::#{e}" }.join(" | ")}]"
121
- else
122
- "//*"
123
- end
100
+ def function(name, *arguments)
101
+ "#{name}(#{arguments.join(", ")})"
124
102
  end
125
103
 
126
- def contains(current, value)
127
- "contains(#{current}, #{value})"
128
- end
104
+ private
129
105
 
130
- def starts_with(current, value)
131
- "starts-with(#{current}, #{value})"
132
- end
133
-
134
- def and(one, two)
135
- "(#{one} and #{two})"
136
- end
137
-
138
- def or(one, two)
139
- "(#{one} or #{two})"
140
- end
141
-
142
- def one_of(current, values)
143
- values.map { |value| "#{current} = #{value}" }.join(' or ')
144
- end
145
-
146
- def next_sibling(current, element_names)
106
+ def with_element_conditions(expression, element_names)
147
107
  if element_names.length == 1
148
- "#{current}/following-sibling::*[1]/self::#{element_names.first}"
108
+ "#{expression}#{element_names.first}"
149
109
  elsif element_names.length > 1
150
- "#{current}/following-sibling::*[1]/self::*[#{element_names.map { |e| "self::#{e}" }.join(" | ")}]"
110
+ "#{expression}*[#{element_names.map { |e| "self::#{e}" }.join(" | ")}]"
151
111
  else
152
- "#{current}/following-sibling::*[1]/self::*"
112
+ "#{expression}*"
153
113
  end
154
114
  end
155
-
156
- def previous_sibling(current, element_names)
157
- if element_names.length == 1
158
- "#{current}/preceding-sibling::*[1]/self::#{element_names.first}"
159
- elsif element_names.length > 1
160
- "#{current}/preceding-sibling::*[1]/self::*[#{element_names.map { |e| "self::#{e}" }.join(" | ")}]"
161
- else
162
- "#{current}/preceding-sibling::*[1]/self::*"
163
- end
164
- end
165
-
166
- def inverse(current)
167
- "not(#{current})"
168
- end
169
-
170
- def string_function(current)
171
- "string(#{current})"
172
- end
173
115
  end
174
116
  end
@@ -1,3 +1,3 @@
1
1
  module XPath
2
- VERSION = '2.0.0'
2
+ VERSION = '2.1.0'
3
3
  end
@@ -41,5 +41,9 @@
41
41
  <div id="elephantay">elephant</div>
42
42
  <p id="amingoflay">flamingo</p>
43
43
  </div>
44
+
45
+ <span id="substring">Hello there</span>
46
+
47
+ <span id="string-length">Hello there</span>
44
48
  </body>
45
49
  </html>
@@ -5,13 +5,13 @@ describe XPath::HTML do
5
5
  let(:template) { 'form' }
6
6
  let(:template_path) { File.read(File.expand_path("fixtures/#{template}.html", File.dirname(__FILE__))) }
7
7
  let(:doc) { Nokogiri::HTML(template_path) }
8
+ let(:type) { |example| example.metadata[:type] }
8
9
 
9
10
  def get(*args)
10
11
  all(*args).first
11
12
  end
12
13
 
13
14
  def all(*args)
14
- type = example.metadata[:type]
15
15
  doc.xpath(XPath::HTML.send(subject, *args).to_xpath(type)).map { |node| node[:data] }
16
16
  end
17
17
 
@@ -1 +1,6 @@
1
1
  require 'xpath'
2
+ require 'pry'
3
+
4
+ RSpec.configure do |config|
5
+ config.expect_with(:rspec) { |c| c.syntax = :should }
6
+ end
@@ -191,6 +191,43 @@ describe XPath do
191
191
  end
192
192
  end
193
193
 
194
+ describe '#substring' do
195
+ context "when called with one argument" do
196
+ it "should select the part of a string after the specified character" do
197
+ @results = xpath { |x| x.descendant(:span).where(x.attr(:id) == "substring").text.substring(7) }
198
+ @results.should == "there"
199
+ end
200
+ end
201
+
202
+ context "when called with two arguments" do
203
+ it "should select the part of a string after the specified character, up to the given length" do
204
+ @results = xpath { |x| x.descendant(:span).where(x.attr(:id) == "substring").text.substring(2, 4) }
205
+ @results.should == "ello"
206
+ end
207
+ end
208
+ end
209
+
210
+ describe '#function' do
211
+ it "should call the given xpath function" do
212
+ @results = xpath { |x| x.function(:boolean, x.function(:true) == x.function(:false)) }
213
+ @results.should == false
214
+ end
215
+ end
216
+
217
+ describe '#method' do
218
+ it "should call the given xpath function with the current node as the first argument" do
219
+ @results = xpath { |x| x.descendant(:span).where(x.attr(:id) == "string-length").text.method(:"string-length") }
220
+ @results.should == 11
221
+ end
222
+ end
223
+
224
+ describe '#string_length' do
225
+ it "should return the length of a string" do
226
+ @results = xpath { |x| x.descendant(:span).where(x.attr(:id) == "string-length").text.string_length }
227
+ @results.should == 11
228
+ end
229
+ end
230
+
194
231
  describe '#where' do
195
232
  it "should limit the expression to find only certain nodes" do
196
233
  xpath { |x| x.descendant(:div).where(:"@id = 'foo'") }.first[:title].should == "fooDiv"
@@ -346,4 +383,113 @@ describe XPath do
346
383
  end
347
384
  end
348
385
 
386
+ describe "#last" do
387
+ it "returns the number of elements in the context" do
388
+ @results = xpath { |x| x.descendant(:p)[XPath.position() == XPath.last()] }
389
+ @results[0].text.should == "Bax"
390
+ @results[1].text.should == "Blah"
391
+ @results[2].text.should == "llama"
392
+ end
393
+ end
394
+
395
+ describe "#position" do
396
+ it "returns the position of elements in the context" do
397
+ @results = xpath { |x| x.descendant(:p)[XPath.position() == 2] }
398
+ @results[0].text.should == "Bax"
399
+ @results[1].text.should == "Bax"
400
+ end
401
+ end
402
+
403
+ describe "#count" do
404
+ it "counts the number of occurrences" do
405
+ @results = xpath { |x| x.descendant(:div)[x.descendant(:p).count == 2] }
406
+ @results[0][:id].should == "preference"
407
+ end
408
+ end
409
+
410
+ describe "#lte" do
411
+ it "checks lesser than or equal" do
412
+ @results = xpath { |x| x.descendant(:p)[XPath.position() <= 2] }
413
+ @results[0].text.should == "Blah"
414
+ @results[1].text.should == "Bax"
415
+ @results[2][:title].should == "gorilla"
416
+ @results[3].text.should == "Bax"
417
+ end
418
+ end
419
+
420
+ describe "#lt" do
421
+ it "checks lesser than" do
422
+ @results = xpath { |x| x.descendant(:p)[XPath.position() < 2] }
423
+ @results[0].text.should == "Blah"
424
+ @results[1][:title].should == "gorilla"
425
+ end
426
+ end
427
+
428
+ describe "#gte" do
429
+ it "checks greater than or equal" do
430
+ @results = xpath { |x| x.descendant(:p)[XPath.position() >= 2] }
431
+ @results[0].text.should == "Bax"
432
+ @results[1][:title].should == "monkey"
433
+ @results[2].text.should == "Bax"
434
+ @results[3].text.should == "Blah"
435
+ end
436
+ end
437
+
438
+ describe "#gt" do
439
+ it "checks greater than" do
440
+ @results = xpath { |x| x.descendant(:p)[XPath.position() > 2] }
441
+ @results[0][:title].should == "monkey"
442
+ @results[1].text.should == "Blah"
443
+ end
444
+ end
445
+
446
+ describe "#plus" do
447
+ it "adds stuff" do
448
+ @results = xpath { |x| x.descendant(:p)[XPath.position().plus(1) == 2] }
449
+ @results[0][:id].should == "fooDiv"
450
+ @results[1][:title].should == "gorilla"
451
+ end
452
+ end
453
+
454
+ describe "#minus" do
455
+ it "subtracts stuff" do
456
+ @results = xpath { |x| x.descendant(:p)[XPath.position().minus(1) == 0] }
457
+ @results[0][:id].should == "fooDiv"
458
+ @results[1][:title].should == "gorilla"
459
+ end
460
+ end
461
+
462
+ describe "#multiply" do
463
+ it "multiplies stuff" do
464
+ @results = xpath { |x| x.descendant(:p)[XPath.position() * 3 == 3] }
465
+ @results[0][:id].should == "fooDiv"
466
+ @results[1][:title].should == "gorilla"
467
+ end
468
+ end
469
+
470
+ describe "#divide" do
471
+ it "divides stuff" do
472
+ @results = xpath { |x| x.descendant(:p)[XPath.position() / 2 == 1] }
473
+ @results[0].text.should == "Bax"
474
+ @results[1].text.should == "Bax"
475
+ end
476
+ end
477
+
478
+ describe "#mod" do
479
+ it "take modulo" do
480
+ @results = xpath { |x| x.descendant(:p)[XPath.position() % 2 == 1] }
481
+ @results[0].text.should == "Blah"
482
+ @results[1][:title].should == "monkey"
483
+ @results[2][:title].should == "gorilla"
484
+ end
485
+ end
486
+
487
+ describe "#ancestor" do
488
+ it "finds ancestor nodes" do
489
+ @results = xpath { |x| x.descendant(:p)[1].ancestor }
490
+ @results[0].node_name.should == "html"
491
+ @results[1].node_name.should == "body"
492
+ @results[2][:id].should == "foo"
493
+ end
494
+ end
349
495
  end
metadata CHANGED
@@ -1,108 +1,84 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xpath
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
5
- prerelease:
4
+ version: 2.1.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Jonas Nicklas
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain:
12
- - !binary |-
13
- LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURoVENDQW0yZ0F3SUJB
14
- Z0lCQVRBTkJna3Foa2lHOXcwQkFRVUZBREJFTVJZd0ZBWURWUVFEREExcWIy
15
- NWgKY3k1dWFXTnJiR0Z6TVJVd0V3WUtDWkltaVpQeUxHUUJHUllGWjIxaGFX
16
- d3hFekFSQmdvSmtpYUprL0lzWkFFWgpGZ05qYjIwd0hoY05NVE13TXpFMk1E
17
- RXpNVEV4V2hjTk1UUXdNekUyTURFek1URXhXakJFTVJZd0ZBWURWUVFECkRB
18
- MXFiMjVoY3k1dWFXTnJiR0Z6TVJVd0V3WUtDWkltaVpQeUxHUUJHUllGWjIx
19
- aGFXd3hFekFSQmdvSmtpYUoKay9Jc1pBRVpGZ05qYjIwd2dnRWlNQTBHQ1Nx
20
- R1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUMrQjlteAowVFZrdlhJ
21
- TjMxSkM0czROaTZtY2hKTC85OGgrZXVNSUVOdDVMb3hjZVlsaWpQMG5HZFlI
22
- QU1vQTJDVWw3RStKCi9LbTNXMXppU0MwTXIzWUlxQ3dwNGZ5Z1Axd295UktS
23
- WW1veUJSWmRXNUppUEFRell4WGFpYjArQkNCK0poU20KUmV2MitCYUhKdVJS
24
- S1dxK1MzYnpaNjFVNlJNVnAvdEFmZUluWE9RZHZtM3ljeWhPR1d4NlhwRVcy
25
- T042b1JEbAptQnVBTThiOWhqcE9BekZYaDNPTFhCQzl6cTVaNXBsMmZybGZB
26
- VkIyaEt6dHdpRWlOa0dqeC9xQlhpeHZvN2R1Ck14K08yOTZXcEx1dVd3ck9h
27
- SXNSM1EzN2FOdkxCdmllaDc0RDlRSmpjd1IzTXIwUlJRTGJYeE5Hc1NRYTZn
28
- WTQKbDlqMEV0VVZTRFpCNTRINUFnTUJBQUdqZ1lFd2Z6QUpCZ05WSFJNRUFq
29
- QUFNQXNHQTFVZER3UUVBd0lFc0RBZApCZ05WSFE0RUZnUVVmOEd0anduYVJ0
30
- U3FndkpEekNjM1RhN0xITXN3SWdZRFZSMFJCQnN3R1lFWGFtOXVZWE11CmJt
31
- bGphMnhoYzBCbmJXRnBiQzVqYjIwd0lnWURWUjBTQkJzd0dZRVhhbTl1WVhN
32
- dWJtbGphMnhoYzBCbmJXRnAKYkM1amIyMHdEUVlKS29aSWh2Y05BUUVGQlFB
33
- RGdnRUJBR2xzbnBjZXY0ZnUrRkRBeWdiT2JmYzczcGx0S25RRgpFd3k4OCtI
34
- Z0o0QWhqd0hFUjdPV0RWTXdoNnZIa21FZXAxcmhMbk5XR3p0RC95bTVpRms0
35
- RkdJejFENUo3VHFRCms0djJ3K09qZTNZVy9wU0FHZ0FWUEdDQ3JscWl3NGhL
36
- WlV6UG9iOE5XaHVTNHRLRFBXTUdCUXgzWlNSeXFJTGMKL1dRL0ZtbmJWYTl4
37
- UlVvK1JXaVA5VHB6S1FKaVIzQlA5T3BWclJ4MTNtMGV1Rnh6VGk2aWtKekM0
38
- NVEzRHE1VgppUXhVbUNDUnNKVmNzU0ZPUkpMZFdOVnF6Qk9XWlJucXJMRHVu
39
- em91Q2JjcXppTldrOEtxalpDcjVpdFJpMzE5Ci8ya1pnd2MzMkZIbENkQ0JY
40
- a2hFbEVIVC9iR0NGazIrYWpubVdSdHFacHovcG9UZ0VlaGlJVVk9Ci0tLS0t
41
- RU5EIENFUlRJRklDQVRFLS0tLS0K
42
- date: 2013-04-09 00:00:00.000000000 Z
11
+ - gem-public_cert.pem
12
+ date: 2017-05-25 00:00:00.000000000 Z
43
13
  dependencies:
44
14
  - !ruby/object:Gem::Dependency
45
15
  name: nokogiri
46
16
  requirement: !ruby/object:Gem::Requirement
47
- none: false
48
17
  requirements:
49
- - - ~>
18
+ - - "~>"
50
19
  - !ruby/object:Gem::Version
51
20
  version: '1.3'
52
21
  type: :runtime
53
22
  prerelease: false
54
23
  version_requirements: !ruby/object:Gem::Requirement
55
- none: false
56
24
  requirements:
57
- - - ~>
25
+ - - "~>"
58
26
  - !ruby/object:Gem::Version
59
27
  version: '1.3'
60
28
  - !ruby/object:Gem::Dependency
61
29
  name: rspec
62
30
  requirement: !ruby/object:Gem::Requirement
63
- none: false
64
31
  requirements:
65
- - - ~>
32
+ - - "~>"
66
33
  - !ruby/object:Gem::Version
67
- version: '2.0'
34
+ version: '3.0'
68
35
  type: :development
69
36
  prerelease: false
70
37
  version_requirements: !ruby/object:Gem::Requirement
71
- none: false
72
38
  requirements:
73
- - - ~>
39
+ - - "~>"
74
40
  - !ruby/object:Gem::Version
75
- version: '2.0'
41
+ version: '3.0'
76
42
  - !ruby/object:Gem::Dependency
77
43
  name: yard
78
44
  requirement: !ruby/object:Gem::Requirement
79
- none: false
80
45
  requirements:
81
- - - ! '>='
46
+ - - ">="
82
47
  - !ruby/object:Gem::Version
83
48
  version: 0.5.8
84
49
  type: :development
85
50
  prerelease: false
86
51
  version_requirements: !ruby/object:Gem::Requirement
87
- none: false
88
52
  requirements:
89
- - - ! '>='
53
+ - - ">="
90
54
  - !ruby/object:Gem::Version
91
55
  version: 0.5.8
92
56
  - !ruby/object:Gem::Dependency
93
57
  name: rake
94
58
  requirement: !ruby/object:Gem::Requirement
95
- none: false
96
59
  requirements:
97
- - - ! '>='
60
+ - - ">="
98
61
  - !ruby/object:Gem::Version
99
62
  version: '0'
100
63
  type: :development
101
64
  prerelease: false
102
65
  version_requirements: !ruby/object:Gem::Requirement
103
- none: false
104
66
  requirements:
105
- - - ! '>='
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: pry
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
106
82
  - !ruby/object:Gem::Version
107
83
  version: '0'
108
84
  description: XPath is a Ruby DSL for generating XPath expressions
@@ -110,9 +86,10 @@ email:
110
86
  - jonas.nicklas@gmail.com
111
87
  executables: []
112
88
  extensions: []
113
- extra_rdoc_files:
114
- - README.md
89
+ extra_rdoc_files: []
115
90
  files:
91
+ - README.md
92
+ - lib/xpath.rb
116
93
  - lib/xpath/dsl.rb
117
94
  - lib/xpath/expression.rb
118
95
  - lib/xpath/html.rb
@@ -120,7 +97,6 @@ files:
120
97
  - lib/xpath/renderer.rb
121
98
  - lib/xpath/union.rb
122
99
  - lib/xpath/version.rb
123
- - lib/xpath.rb
124
100
  - spec/fixtures/form.html
125
101
  - spec/fixtures/simple.html
126
102
  - spec/fixtures/stuff.html
@@ -128,32 +104,28 @@ files:
128
104
  - spec/spec_helper.rb
129
105
  - spec/union_spec.rb
130
106
  - spec/xpath_spec.rb
131
- - README.md
132
- homepage: http://github.com/jnicklas/xpath
133
- licenses: []
107
+ homepage: https://github.com/teamcapybara/xpath
108
+ licenses:
109
+ - MIT
110
+ metadata: {}
134
111
  post_install_message:
135
- rdoc_options:
136
- - --main
137
- - README.md
112
+ rdoc_options: []
138
113
  require_paths:
139
114
  - lib
140
115
  required_ruby_version: !ruby/object:Gem::Requirement
141
- none: false
142
116
  requirements:
143
- - - ! '>='
117
+ - - ">="
144
118
  - !ruby/object:Gem::Version
145
- version: '0'
119
+ version: 1.9.3
146
120
  required_rubygems_version: !ruby/object:Gem::Requirement
147
- none: false
148
121
  requirements:
149
- - - ! '>='
122
+ - - ">="
150
123
  - !ruby/object:Gem::Version
151
124
  version: '0'
152
125
  requirements: []
153
- rubyforge_project: xpath
154
- rubygems_version: 1.8.25
126
+ rubyforge_project:
127
+ rubygems_version: 2.5.2
155
128
  signing_key:
156
- specification_version: 3
129
+ specification_version: 4
157
130
  summary: Generate XPath expressions from Ruby
158
131
  test_files: []
159
- has_rdoc:
data.tar.gz.sig DELETED
Binary file
metadata.gz.sig DELETED
@@ -1 +0,0 @@
1
- Q�יִ.�C�����hiΑj�5hg/�Ϋ!7�z�4� <X��Yn�W�o��A��U����W�]?��5S�, �mj�/Iqp<��|�~��Q�ݺS���ޟD-��@�x�oɶT� K~o{���qΣT���J ���F{� �za�=�չ��36���+;SC������1�S&�/I�d���O�8�Nz�`F�4��Y�c�X��G�S�rj4�U�7D�(�{���AO�k�k�u���xa���;��vG�