rind 0.1.3 → 0.1.4

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.
data/CHANGELOG.rdoc CHANGED
@@ -1,9 +1,13 @@
1
+ == 0.1.4 - 2010.06.26
2
+ * Xpath searches with attribute values containing a <tt>/</tt>, like <tt>style[@type="text/css"]</tt>, broke the query parser.
3
+ * The Manipulate::insert_after and Manipulate::insert_before functions and Xpath positions were not returning the correct nodes when other available nodes matched <tt>==</tt>.
4
+
1
5
  == 0.1.3 - 2010.06.20
2
6
  * The Xpath function 's' will return an empty Rind::Node rather than +nil+.
3
7
  * Processing instructions were not being treated as nodes.
4
8
  * DocType nodes were lacking proper equality checks.
5
- * The +next+, +next_sibling+, +prev+ and +prev_sibling+ functions were not returning the correct nodes when other available nodes matched <tt>==</tt>.
6
- * Adding +exact_index+ function to Rind::Nodes. (used in previous bug fix)
9
+ * The Traverse::next, Traverse::next_sibling, Traverse::prev and Traverse::prev_sibling functions were not returning the correct nodes when other available nodes matched <tt>==</tt>.
10
+ * Adding exact_index function to Rind::Nodes. (used in previous bug fix)
7
11
 
8
12
  == 0.1.2 - 2010.06.17
9
13
  * When parsing HTML, script and style tags will not break because of a "<" in their content.
@@ -1,27 +1,24 @@
1
1
  # Note: These functions are not available for the root node in a tree.
2
2
  module Manipulate
3
- # Calls {Rind::Children::insert}[link:classes/Rind/Children.html#insert]
4
- # to add nodes after <tt>self</tt>.
3
+ # Calls Rind::Children::insert to add nodes after <tt>self</tt>.
5
4
  # === Example
6
5
  # nodes = ['a', 'b', 'c']
7
6
  # nodes[0].insert_after('d', 'e') => ['a', 'd', 'e', 'b', 'c']
8
7
  def insert_after(*nodes)
9
8
  children = self.parent.children
10
- children.insert(children.index(self)+1, *nodes)
9
+ children.insert(children.exact_index(self)+1, *nodes)
11
10
  end
12
11
 
13
- # Calls {Rind::Children::insert}[link:classes/Rind/Children.html#insert]
14
- # to add nodes before <tt>self</tt>.
12
+ # Calls Rind::Children::insert to add nodes before <tt>self</tt>.
15
13
  # === Example
16
14
  # nodes = ['a', 'b', 'c']
17
15
  # nodes[2].insert_after('d', 'e') => ['a', 'b', 'd', 'e', 'c']
18
16
  def insert_before(*nodes)
19
17
  children = self.parent.children
20
- children.insert(children.index(self), *nodes)
18
+ children.insert(children.exact_index(self), *nodes)
21
19
  end
22
20
 
23
- # Calls {Rind::Children::delete}[link:classes/Rind/Children.html#delete]
24
- # on <tt>self</tt>.
21
+ # Calls Rind::Children::delete on <tt>self</tt>.
25
22
  # === Example
26
23
  # nodes = ['a', 'b', 'c']
27
24
  # nodes[1].delete => 'b'
data/lib/rind/xpath.rb CHANGED
@@ -4,38 +4,42 @@
4
4
  module Xpath
5
5
  # Xpath search of a node that returns a list of matching nodes.
6
6
  def s(path)
7
- node = self;
7
+ node = self
8
8
 
9
9
  # absolute paths to the top
10
10
  if '/' == path[0,1]
11
11
  while not node.parent.nil?
12
12
  node = node.parent
13
13
  end
14
- if 1 < path.length and '/' == path[1,1]
15
- path[0] = ''
16
- else
14
+ if '/' != path[1,1]
17
15
  path[0] = 'self::'
18
16
  end
19
17
  end
20
18
 
21
19
  # node check
22
20
  nodes = [node]
23
- path.split('/').each do |step|
24
- case step
25
- when ''
26
- step = 'descendant-or-self::node()'
21
+ path.scan(%r{(?:^\/?|\/)
22
+ (?:(.*?)::)? # axis
23
+ ([^\/\[]+)? # node test
24
+ ((?:\[.+?\])*) # predicates
25
+ }x) do |axis, node_test, predicates|
26
+ case node_test
27
+ when nil
28
+ axis = 'descendant-or-self'
29
+ node_test = 'node()'
27
30
  when '.'
28
- step = 'self::node()'
31
+ axis = 'self'
32
+ node_test = 'node()'
29
33
  when '..'
30
- step = 'parent::node()'
34
+ axis = 'parent'
35
+ node_test = 'node()'
31
36
  end
32
37
 
33
- step.gsub!(/^@/, 'attribute::')
34
-
35
- step =~ /^(?:(.*?)::)?(.+?)(\[.*?)?$/
36
- axis, node_test, predicates = $1, $2, $3
37
38
  axis = 'child' if axis.nil?
38
39
 
40
+ node_test.gsub!(/^@/, 'attribute::')
41
+ predicates.gsub!(/^@/, 'attribute::')
42
+
39
43
  # find matching nodes
40
44
  nodes = nodes.collect{|node| node.find_matching_nodes(axis, node_test)}.flatten.compact
41
45
 
@@ -51,7 +55,9 @@ module Xpath
51
55
  # last()
52
56
  predicate.gsub!(/last\(\)/, nodes.length.to_s)
53
57
 
54
- nodes = nodes.find_all{|node| node.validate_predicate(predicate.clone, nodes.index(node)+1)}
58
+ nodes = nodes.find_all do |node|
59
+ node.validate_predicate(predicate.clone, Rind::Nodes[*nodes].exact_index(node)+1)
60
+ end
55
61
  break if nodes.empty?
56
62
  end
57
63
  end
@@ -3,21 +3,22 @@ require 'rind'
3
3
 
4
4
  class ManipulateTest < Test::Unit::TestCase
5
5
  def setup
6
- @p = Rind::Html::P.new(:children => ['This is some text!'])
7
- @br = Rind::Html::Br.new()
8
- @hr = Rind::Html::Hr.new()
6
+ @a = Rind::Html::A.new()
7
+ @b1 = Rind::Html::B.new()
8
+ @b2 = Rind::Html::B.new()
9
+ @a.children.push(@b1, @b2)
9
10
  end
10
11
 
11
12
  def test_insert_after
12
- assert_equal(@p.children.first.insert_after(@br, @hr), ['This is some text!', @br, @hr])
13
+ assert_equal(@a.children[1].insert_after('foo'), [@b1, @b2, 'foo'])
13
14
  end
14
15
 
15
16
  def test_insert_before
16
- assert_equal(@p.children.first.insert_before(@br, @hr), [@br, @hr, 'This is some text!'])
17
+ assert_equal(@a.children[1].insert_before('foo'), [@b1, 'foo', @b2])
17
18
  end
18
19
 
19
20
  def test_remove
20
- assert_equal(@p.children.first.remove, 'This is some text!')
21
- assert(@p.children.empty?)
21
+ assert_equal(@a.children[1].remove, @b2)
22
+ assert(@a.children.empty?)
22
23
  end
23
24
  end
data/test/xml_test.rb CHANGED
@@ -4,11 +4,11 @@ require 'rind'
4
4
  class XmlTest < Test::Unit::TestCase
5
5
  def test_to_s
6
6
  # no children
7
- a_tag = Rind::Xml::A.new();
7
+ a_tag = Rind::Xml::A.new()
8
8
  assert_equal(a_tag.to_s, '<a />')
9
9
 
10
10
  # with children
11
- b_tag = Rind::Xml::B.new(:children => a_tag);
11
+ b_tag = Rind::Xml::B.new(:children => a_tag)
12
12
  assert_equal(b_tag.to_s, '<b><a /></b>')
13
13
  end
14
14
  end
data/test/xpath_test.rb CHANGED
@@ -3,28 +3,84 @@ require 'rind'
3
3
 
4
4
  class XpathTest < Test::Unit::TestCase
5
5
  def setup
6
- @br_one = Rind::Html::Br.new(:attributes => {:id => 'br_one', :class => '1'})
7
- @br_two = Rind::Html::Br.new(:attributes => {:id => 'br_two', :class => '2'})
8
- @br_three = Rind::Html::Br.new()
9
- @p_one = Rind::Html::P.new(:attributes => {:class => '1'}, :children => [@br_one, @br_two, @br_three])
6
+ @a = Rind::Html::A.new
7
+ @b1 = Rind::Html::B.new(:attributes => {:id => '1', :class => '1'})
8
+ @b2 = Rind::Html::B.new(:attributes => {:id => '2', :class => '2'})
9
+ @b3 = Rind::Html::B.new(:attributes => {:id => '3', :type => 'text/css'})
10
+ @c1 = Rind::Html::C.new()
11
+ @c2 = Rind::Html::C.new()
12
+ @c3 = Rind::Html::C.new()
13
+ @comment = Rind::Comment.new('comment')
14
+ @pi = Rind::ProcessingInstruction.new('pi')
15
+ @text = Rind::Text.new('text')
16
+ @b1.children.push(@c1)
17
+ @b2.children.push(@c2, @c3)
18
+ @b3.children.push(@comment, @pi, @text)
19
+ @a.children.push(@b1, @b2, @b3)
10
20
  end
11
21
 
12
22
  def test_s
13
- assert_equal(@p_one.s('br'), [@br_one, @br_two, @br_three])
23
+ assert_equal(@c1.s('/a'), [@a])
14
24
 
15
- # attribute tests
16
- assert_equal(@p_one.s('br[@class="1"]'), [@br_one])
25
+ assert_equal(@a.s('//c'), [@c1, @c2, @c3])
17
26
 
18
- # position tests
19
- assert_equal(@p_one.s('br[2]'), [@br_two])
20
- assert_equal(@p_one.s('br[position()=1]'), [@br_one])
21
- assert_equal(@p_one.s('br[last()]'), [@br_three])
27
+ assert_equal(@c2.s('..'), [@b2] )
22
28
 
23
- assert_equal(@p_one.s('a'), [])
29
+ assert_equal(@c2.s('.'), [@c2] )
30
+
31
+ assert_equal(@a.s('foo'), [])
24
32
  end
25
33
 
34
+ def test_s_axis
35
+ assert_equal(@c1.s('ancestor::*'), [@b1, @a])
36
+
37
+ assert_equal(@c1.s('ancestor-or-self::*'), [@c1, @b1, @a])
38
+
39
+ assert_equal(@a.s('child::*'), [@b1, @b2, @b3])
40
+
41
+ assert_equal(@a.s('descendant::*'), [@b1, @b2, @b3, @c1, @c2, @c3, @comment, @pi])
42
+
43
+ assert_equal(@a.s('descendant-or-self::*'), [@a, @b1, @b2, @b3, @c1, @c2, @c3, @comment, @pi])
44
+
45
+ assert_equal(@b2.s('following-sibling::*'), [@b3])
46
+
47
+ assert_equal(@b3.s('parent::*'), [@a])
48
+
49
+ assert_equal(@b2.s('preceding-sibling::*'), [@b1])
50
+
51
+ assert_equal(@a.s('self::*'), [@a])
52
+ end
53
+
54
+ def test_s_node_test
55
+ assert_equal(@a.s('//*'), [@b1, @b2, @b3, @c1, @c2, @c3, @comment, @pi])
56
+
57
+ assert_equal(@a.s('//comment()'), [@comment])
58
+
59
+ assert_equal(@a.s('//node()'), [@b1, @b2, @b3, @c1, @c2, @c3, @comment, @pi, @text])
60
+
61
+ assert_equal(@a.s('//processing-instruction()'), [@pi])
62
+
63
+ assert_equal(@a.s('//text()'), [@text])
64
+
65
+ assert_equal(@a.s('b'), [@b1, @b2, @b3])
66
+ end
67
+
68
+ def test_s_attribute
69
+ assert_equal(@a.s('b[@class="1"]'), [@b1])
70
+
71
+ assert_equal(@a.s('//b[@type="text/css"]'), [@b3])
72
+ end
73
+
74
+ def test_s_position
75
+ assert_equal(@b2.s('c[2]'), [@c3])
76
+
77
+ assert_equal(@a.s('b[position()=1]'), [@b1])
78
+
79
+ assert_equal(@a.s('b[last()]'), [@b3])
80
+ end
81
+
26
82
  def test_sf
27
- assert_same(@p_one.sf('br'), @br_one)
28
- assert_nil(@p_one.sf('a'))
83
+ assert_same(@a.sf('b'), @b1)
84
+ assert_nil(@a.sf('foo'))
29
85
  end
30
86
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rind
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 3
10
- version: 0.1.3
9
+ - 4
10
+ version: 0.1.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - Aaron Lasseigne
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-06-20 00:00:00 -05:00
18
+ date: 2010-06-26 00:00:00 -05:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -25,8 +25,9 @@ executables: []
25
25
 
26
26
  extensions: []
27
27
 
28
- extra_rdoc_files: []
29
-
28
+ extra_rdoc_files:
29
+ - LICENSE
30
+ - CHANGELOG.rdoc
30
31
  files:
31
32
  - lib/rind/document.rb
32
33
  - lib/rind/html.rb