sxrb 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/lib/sxrb/proxy.rb +55 -2
  2. data/spec/parser_spec.rb +168 -0
  3. metadata +24 -5
data/lib/sxrb/proxy.rb CHANGED
@@ -1,18 +1,44 @@
1
1
  module SXRB
2
2
  class Proxy
3
+ # @api private
3
4
  def initialize(callback_tree, current_path = '')
4
5
  @callback_tree = callback_tree
5
6
  @current_path = current_path
6
7
  end
7
8
 
8
- def child(*args, &block)
9
- args.each do |tag|
9
+ # Defines child (a direct descendant) of an element defined in current.
10
+ # block.
11
+ # @param [String] *tags
12
+ # names of tags that should be matched
13
+ #
14
+ # @yield [Proxy]
15
+ # block receives Proxy element representing matched elements
16
+ #
17
+ # @return [nil]
18
+ #
19
+ # @api public
20
+ #
21
+ # @todo Add Regexp and other selectors support in addition to Strings.
22
+ def child(*tags, &block)
23
+ tags.each do |tag|
10
24
  @callback_tree.add_rule(tag, @current_path, :recursive => false).tap do |new_path|
11
25
  block.call(Proxy.new(@callback_tree, new_path))
12
26
  end
13
27
  end
14
28
  end
15
29
 
30
+ # Defines descendant of an element defined in current block.
31
+ # @param [String] *tags
32
+ # names of tags that should be matched
33
+ #
34
+ # @yield [Proxy]
35
+ # block receives Proxy element representing matched elements
36
+ #
37
+ # @return [nil]
38
+ #
39
+ # @api public
40
+ #
41
+ # @todo Add Regexp and other selectors support in addition to Strings.
16
42
  def descendant(*args, &block)
17
43
  args.each do |tag|
18
44
  @callback_tree.add_rule(tag, @current_path, :recursive => true).tap do |new_path|
@@ -21,18 +47,45 @@ module SXRB
21
47
  end
22
48
  end
23
49
 
50
+ # Defines callback method invoked when matching element is completely
51
+ # parsed.
52
+ # @yield [Node] block receives whole parsed element with children.
53
+ #
54
+ # @api public
55
+ #
56
+ # @note `on_element` should not be used for items that are expected to have
57
+ # large node subtrees.
24
58
  def on_element(&block)
25
59
  @callback_tree.add_callback(:element, @current_path, &block)
26
60
  end
27
61
 
62
+ # Defines a callback that is invoked whenever start tag is encountered.
63
+ #
64
+ # @yield [Node] block receives parsed node without any nested elements. All
65
+ # inline attributes are available though.
66
+ #
67
+ # @api public
28
68
  def on_start(&block)
29
69
  @callback_tree.add_callback(:start, @current_path, &block)
30
70
  end
31
71
 
72
+ # Defines a callback that is invoked whenever anonymous text node within
73
+ # self is encountered.
74
+ #
75
+ # @yield [String] block receives raw content of parsed data in form of
76
+ # String object.
77
+ #
78
+ # @api public
32
79
  def on_characters(&block)
33
80
  @callback_tree.add_callback(:characters, @current_path, &block)
34
81
  end
35
82
 
83
+ # Defines a callback that is invoked whenever end tag is encountered.
84
+ #
85
+ # @yield [Node] block receives parsed node without any nested elements. All
86
+ # inline attributes are available though.
87
+ #
88
+ # @api public
36
89
  def on_end(&block)
37
90
  @callback_tree.add_callback(:end, @current_path, &block)
38
91
  end
@@ -0,0 +1,168 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe SXRB::Parser do
4
+ it 'should fail when created without block' do
5
+ expect {
6
+ SXRB::Parser.new("<xmlstring/>")
7
+ }.to raise_error(ArgumentError)
8
+ end
9
+
10
+ context 'callbacks' do
11
+ it 'should call defined start callback for child element' do
12
+ handler = double('handler')
13
+ handler.should_receive(:msg).once
14
+
15
+ SXRB::Parser.new("<testelement>content</testelement>") do |xml|
16
+ xml.child 'testelement' do |test_element|
17
+ test_element.on_start do |element|
18
+ handler.msg
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ it 'should call defined end callback for child element' do
25
+ handler = double('handler')
26
+ handler.should_receive(:msg).once
27
+
28
+ SXRB::Parser.new("<testelement>content</testelement>") do |xml|
29
+ xml.child 'testelement' do |test_element|
30
+ test_element.on_end do |element|
31
+ handler.msg
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ it 'should call defined characters callback for child element' do
38
+ handler = double('handler')
39
+ handler.should_receive(:msg).once
40
+
41
+ SXRB::Parser.new("<testelement>content</testelement>") do |xml|
42
+ xml.child 'testelement' do |test_element|
43
+ test_element.on_characters do |element|
44
+ handler.msg
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+
51
+ it 'should call defined element callback for child element' do
52
+ handler = double('handler')
53
+ handler.should_receive(:msg).once
54
+
55
+ SXRB::Parser.new("<testelement>content</testelement>") do |xml|
56
+ xml.child 'testelement' do |test_element|
57
+ test_element.on_element do |element|
58
+ handler.msg
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ it 'should call defined element callback for child element only' do
65
+ handler = double('handler')
66
+ handler.should_receive(:msg).once
67
+
68
+ SXRB::Parser.new("<testelement><testelement>content</testelement></testelement>") do |xml|
69
+ xml.child 'testelement' do |test_element|
70
+ test_element.on_element do |element|
71
+ handler.msg
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ it 'should call defined element callback for all descendants' do
78
+ handler = double('handler')
79
+ handler.should_receive(:msg).twice
80
+
81
+ SXRB::Parser.new("<testelement><testelement>content</testelement></testelement>") do |xml|
82
+ xml.descendant 'testelement' do |test_element|
83
+ test_element.on_element do |element|
84
+ handler.msg
85
+ end
86
+ end
87
+ end
88
+ end
89
+
90
+ it 'should pass empty hash to callback when no attributes are given' do
91
+ SXRB::Parser.new("<testelement>content</testelement>") do |xml|
92
+ xml.child 'testelement' do |test_element|
93
+ test_element.on_element do |element|
94
+ element.attributes.should == {}
95
+ end
96
+ end
97
+ end
98
+ end
99
+
100
+ it 'should pass value properly to callback to on_element' do
101
+ SXRB::Parser.new("<testelement>content</testelement>") do |xml|
102
+ xml.child 'testelement' do |test_element|
103
+ test_element.on_element do |element|
104
+ element.children.first.text == 'content'
105
+ end
106
+ end
107
+ end
108
+ end
109
+
110
+ it 'should not find element with non-matching name' do
111
+ SXRB::Parser.new("<testelement>content</testelement>") do |xml|
112
+ xml.child 'othername' do |test_element|
113
+ test_element.on_element do |attrs, value|
114
+ value.should == 'content'
115
+ end
116
+ end
117
+ end
118
+ end
119
+
120
+ it 'should find element by regexp' do
121
+ pending "feature not ready yet"
122
+ SXRB::Parser.new("<testelement>content</testelement>") do |xml|
123
+ xml.child /testel/ do |test_element|
124
+ test_element.on_element do |attrs, value|
125
+ value.should == 'content'
126
+ end
127
+ end
128
+ end
129
+ end
130
+
131
+ it 'should find nested element' do
132
+ SXRB::Parser.new("<testelement><a>a-content</a></testelement>") do |xml|
133
+ xml.child 'testelement' do |test_element|
134
+ test_element.child 'a' do |a|
135
+ a.on_element do |element|
136
+ element.children.first.text == 'a-content'
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
142
+
143
+ it 'should call callback for element regardless of nested elements' do
144
+ handler = double('handler')
145
+ handler.should_receive(:msg).once
146
+ SXRB::Parser.new("<testelement><a>a-content</a></testelement>") do |xml|
147
+ xml.child 'testelement' do |test_element|
148
+ test_element.on_element do |element|
149
+ handler.msg
150
+ end
151
+ end
152
+ end
153
+ end
154
+
155
+ it 'should pass nested elements to on_element callback' do
156
+ SXRB::Parser.new("<testelement><a>a-content</a></testelement>") do |xml|
157
+ xml.child 'testelement' do |test_element|
158
+ test_element.on_element do |element|
159
+ element.children.first.tap do |a|
160
+ a.name.should == 'a'
161
+ a.children.first.text.should == 'a-content'
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sxrb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,24 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-06 00:00:00.000000000 Z
13
- dependencies: []
12
+ date: 2012-08-07 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: libxml-ruby
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.3.3
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 2.3.3
14
30
  description: Robust XML parser that allows defining desired behavior with fancy DSL
15
31
  email:
16
32
  executables: []
@@ -24,8 +40,10 @@ files:
24
40
  - lib/sxrb/errors.rb
25
41
  - lib/sxrb/proxy.rb
26
42
  - lib/sxrb.rb
43
+ - spec/parser_spec.rb
27
44
  homepage: http://rubygems.org/gems/sxrb
28
- licenses: []
45
+ licenses:
46
+ - MIT
29
47
  post_install_message:
30
48
  rdoc_options: []
31
49
  require_paths:
@@ -48,5 +66,6 @@ rubygems_version: 1.8.21
48
66
  signing_key:
49
67
  specification_version: 3
50
68
  summary: Smart XML parser
51
- test_files: []
69
+ test_files:
70
+ - spec/parser_spec.rb
52
71
  has_rdoc: