sxrb 0.2.2 → 0.3.0

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.
@@ -0,0 +1,14 @@
1
+ 08 Aug 2012 (ver. 0.3.0)
2
+ * New constructors are available
3
+ * Parsing rules can be now reused
4
+ * YARD Documentation
5
+
6
+ 07 Aug 2012 (ver. 0.2.2)
7
+ * Fixed gem dependencies
8
+
9
+ 06 Aug 2012 (ver. 0.2.0)
10
+ * Added file and IO inputs support
11
+ * Project is now continously tested with Travis
12
+
13
+ 05 Aug 2012 (ver. 0.1.0)
14
+ * Release!
@@ -1,4 +1,5 @@
1
1
  require 'sxrb/parser'
2
2
  require 'sxrb/errors'
3
3
 
4
+ # Main module of gem.
4
5
  module SXRB; end
@@ -2,17 +2,25 @@ require 'libxml'
2
2
  require 'sxrb/node'
3
3
  require 'sxrb/text_node'
4
4
 
5
- # This class provides callbacks for SAX API which are configured with sxrb DSL.
6
5
 
7
6
  module SXRB
7
+
8
+ # This class provides callbacks for SAX API which are configured with sxrb
9
+ # DSL. It's behavior is configured by DSL via Proxy class objects, and should
10
+ # not be used outside of this scope. Currently it has only been tested with
11
+ # LibXML implementation of SAX, but set of method that object needs to
12
+ # provide is defined by standard, so using it with different backend should
13
+ # be automatic.
8
14
  class Callbacks
9
15
  #include LibXML::XML::SaxParser::VerboseCallbacks
10
16
  include LibXML::XML::SaxParser::Callbacks
17
+ # @api private
11
18
  def initialize
12
19
  @stack = []
13
20
  @rules_map = Hash.new {|h,k| h[k] = Rules.new}
14
21
  end
15
22
 
23
+ # @api private
16
24
  def on_start_element_ns(name, attributes, prefix, uri, namespaces)
17
25
  Node.new(name, attributes, prefix, uri, namespaces).tap do |node|
18
26
  @stack.push(node)
@@ -22,6 +30,7 @@ module SXRB
22
30
  end
23
31
  end
24
32
 
33
+ # @api private
25
34
  def on_characters(chars)
26
35
  if @stack.last.is_a? TextNode
27
36
  @stack.last.append_text chars
@@ -34,6 +43,7 @@ module SXRB
34
43
  end
35
44
  end
36
45
 
46
+ # @api private
37
47
  def on_end_element_ns(name, prefix, uri)
38
48
  @stack.pop if @stack.last.is_a? TextNode
39
49
 
@@ -48,6 +58,7 @@ module SXRB
48
58
  end
49
59
  end
50
60
 
61
+ # @api private
51
62
  def add_callback(type, rule_path, &block)
52
63
  @rules_map[Regexp.new "^#{rule_path}$"].tap do |rules|
53
64
  rules.rules[type] = block
@@ -55,9 +66,7 @@ module SXRB
55
66
  end
56
67
  end
57
68
 
58
- # options:
59
- # recursive
60
- #
69
+ # @api private
61
70
  def add_rule(rule, rule_path, options)
62
71
  operator = options[:recursive] ? '.*' : ' '
63
72
  new_rule = rule_path + operator + rule
@@ -66,23 +75,28 @@ module SXRB
66
75
 
67
76
  private
68
77
 
78
+ # @api private
69
79
  def invoke_callback(type, *args)
70
80
  current_matching_rules.
71
81
  map {|value| value.rules[type]}.
72
82
  compact.each {|callback| callback.call(*args)}
73
83
  end
74
84
 
85
+ # @api private
75
86
  def current_matching_rules
76
87
  @rules_map.each_pair.
77
88
  select {|rule, value| current_rule_path =~ rule}.
78
89
  map {|rule, value| value}
79
90
  end
80
91
 
92
+ # @api private
81
93
  def current_rule_path
82
94
  @stack.map(&:name).join(' ')
83
95
  end
84
96
  end
85
97
 
98
+ # Internal class that is designed to keep rules of matching XML elements.
99
+ # @api private
86
100
  class Rules
87
101
  attr_accessor :rules, :recursive
88
102
  def initialize
@@ -1,3 +1,5 @@
1
1
  module SXRB
2
+ # SXRB::TagMismatchError is raised whenever parser encounters closing tag of
3
+ # never opened element.
2
4
  class TagMismatchError < StandardError; end
3
5
  end
@@ -1,16 +1,27 @@
1
1
  module SXRB
2
+ # Node class is simple DOM-like element, which allows easy travesing through
3
+ # restricted part of document structure with #children and #parent methods.
2
4
  class Node < Struct.new(:name, :attributes, :prefix, :uri, :namespaces, :parent)
3
5
  attr_accessor :children
6
+ # Internal method used to build DOM-like structure.
7
+ # @api private
4
8
  def initialize(*args, &block)
5
9
  super(*args, &block)
6
10
  @children = []
7
11
  end
8
12
 
13
+ # Internal method used to build DOM-like structure.
14
+ # @api private
9
15
  def append(node)
10
16
  node.parent = self
11
17
  @children << node
12
18
  end
13
19
 
20
+
21
+ # Returns text content of a node (recursively), skipping all markup.
22
+ # @return [String]
23
+ # Text content of this node and all it's descendants is returned,
24
+ # concatenated.
14
25
  def content
15
26
  children.map {|child| child.is_a?(TextNode)? child.text : child.content}.flatten.join('')
16
27
  end
@@ -2,28 +2,90 @@ require 'sxrb/callbacks'
2
2
  require 'sxrb/proxy'
3
3
 
4
4
  module SXRB
5
+ # Main class of gem, which allows parsing XML data.
5
6
  class Parser
7
+ # Create parser object and parse provided input.
8
+ # @param [Filename, IO, String] input
9
+ # Data stream to be parsed.
10
+ # @option opts [Symbol] :mode (:string)
11
+ # Instructs SXRB how to treat input parameter. Possible values are:
12
+ # :string, :file, :io. Please note, that in case of :file mode
13
+ # input should be filename.
14
+ # @deprecated
15
+ # This method should not be used anymore. In version 1.0 it will work
16
+ # completely different so it is preferable to migrate to use parse_*
17
+ # methods right now.
6
18
  def initialize(input, opts = {}, &block)
7
19
  raise ArgumentError.new("Block expected") if block.nil?
8
- options = {:mode => :string}.merge(opts)
20
+ case opts[:mode]
21
+ when :file
22
+ self.class.parse_file(input, &block)
23
+ when :io
24
+ self.class.parse_io(input, &block)
25
+ else
26
+ self.class.parse_string(input, &block)
27
+ end
28
+ end
9
29
 
10
- # Create parser according to options
30
+ # Define set of reusable rules for SXRB parser.
31
+ # @yield Proxy
32
+ # See Proxy documentation for details on available methods and defining
33
+ # rules.
34
+ # @return [Callbacks]
35
+ # Set of rules which can be feeded to parse_* methods.
36
+ def self.define_rules(&block)
37
+ Callbacks.new.tap do |cb|
38
+ yield Proxy.new(cb)
39
+ end
40
+ end
11
41
 
12
- parser = case options[:mode]
13
- when :string
14
- LibXML::XML::SaxParser.string(input)
15
- when :file
16
- LibXML::XML::SaxParser.file(input)
17
- when :io
18
- LibXML::XML::SaxParser.io(input)
19
- end
42
+ # Parse string containing XML.
43
+ # @param [String] string
44
+ # Input string
45
+ # @param [optional, Callbacks] callbacks
46
+ # Set of rules generated by define_rules.
47
+ # @yield [Proxy]
48
+ # If callbacks parameter is not provided rules have to be defined directly in provided block.
49
+ # @return [nil]
50
+ def self.parse_string(string, callbacks = nil, &block)
51
+ raise ArgumentError unless !!callbacks ^ !!block
52
+ LibXML::XML::SaxParser.string(string).tap do |parser|
53
+ parser.callbacks = callbacks || define_rules(&block)
54
+ parser.parse
55
+ end
56
+ nil
57
+ end
20
58
 
21
- callbacks = Callbacks.new.tap do |cb|
22
- yield Proxy.new(cb)
59
+ # Parse file containing XML.
60
+ # @param [String] filename
61
+ # Path to file to be parsed.
62
+ # @param [optional, Callbacks] callbacks
63
+ # Set of rules generated by define_rules.
64
+ # @yield [Proxy]
65
+ # If callbacks parameter is not provided rules have to be defined directly in provided block.
66
+ # @return [nil]
67
+ def self.parse_file(filename, callbacks = nil, &block)
68
+ raise ArgumentError unless !!callbacks ^ !!block
69
+ LibXML::XML::SaxParser.file(filename).tap do |parser|
70
+ parser.callbacks = callbacks || define_rules(&block)
71
+ parser.parse
23
72
  end
73
+ end
24
74
 
25
- parser.callbacks = callbacks
26
- parser.parse
75
+ # Parse IO containing XML.
76
+ # @param [IO] io
77
+ # Path to stream to be parsed.
78
+ # @param [optional, Callbacks] callbacks
79
+ # Set of rules generated by define_rules.
80
+ # @yield [Proxy]
81
+ # If callbacks parameter is not provided rules have to be defined directly in provided block.
82
+ # @return [nil]
83
+ def self.parse_io(io, callbacks = nil, &block)
84
+ raise ArgumentError unless !!callbacks ^ !!block
85
+ LibXML::XML::SaxParser.io(io).tap do |parser|
86
+ parser.callbacks = callbacks || define_rules(&block)
87
+ parser.parse
88
+ end
27
89
  end
28
90
  end
29
91
  end
@@ -1,18 +1,25 @@
1
1
  module SXRB
2
+ # Objects of Proxy class are part of SXRB DSL and their methods are meant to
3
+ # be used to define set of rules needed to parse XML document. They have no
4
+ # other meaning and should not be used outside of that scope.
5
+ # @api public
2
6
  class Proxy
7
+ # Proxy objects are generated by the SXRB itself, and are passed to blocks
8
+ # to be used as DSL. They should not be created in any other context.
9
+ # Implementation might change without prior notice.
10
+ #
3
11
  # @api private
4
12
  def initialize(callback_tree, current_path = '')
5
13
  @callback_tree = callback_tree
6
14
  @current_path = current_path
7
15
  end
8
16
 
9
- # Defines child (a direct descendant) of an element defined in current.
10
- # block.
11
- # @param [String] *tags
17
+ # Defines child (a direct descendant) of an element defined in current block.
18
+ # @param [String] tags
12
19
  # names of tags that should be matched
13
20
  #
14
21
  # @yield [Proxy]
15
- # block receives Proxy element representing matched elements
22
+ # block receives Proxy element representing matched elements.
16
23
  #
17
24
  # @return [nil]
18
25
  #
@@ -28,19 +35,19 @@ module SXRB
28
35
  end
29
36
 
30
37
  # Defines descendant of an element defined in current block.
31
- # @param [String] *tags
38
+ # @param [String] tags
32
39
  # names of tags that should be matched
33
40
  #
34
41
  # @yield [Proxy]
35
- # block receives Proxy element representing matched elements
42
+ # block receives Proxy element representing matched elements.
36
43
  #
37
44
  # @return [nil]
38
45
  #
39
46
  # @api public
40
47
  #
41
- # @todo Add Regexp and other selectors support in addition to Strings.
42
- def descendant(*args, &block)
43
- args.each do |tag|
48
+ # @todo Add Regexp and other selectors support in addition to strings.
49
+ def descendant(*tags, &block)
50
+ tags.each do |tag|
44
51
  @callback_tree.add_rule(tag, @current_path, :recursive => true).tap do |new_path|
45
52
  block.call(Proxy.new(@callback_tree, new_path))
46
53
  end
@@ -49,21 +56,28 @@ module SXRB
49
56
 
50
57
  # Defines callback method invoked when matching element is completely
51
58
  # parsed.
52
- # @yield [Node] block receives whole parsed element with children.
59
+ #
60
+ # @yield [Node]
61
+ # block receives whole parsed element with children.
53
62
  #
54
63
  # @api public
55
64
  #
56
- # @note `on_element` should not be used for items that are expected to have
57
- # large node subtrees.
65
+ # @return [nil]
66
+ #
67
+ # @note
68
+ # `on_element` should not be used for items that are expected to have
69
+ # large node subtrees.
58
70
  def on_element(&block)
59
71
  @callback_tree.add_callback(:element, @current_path, &block)
60
72
  end
61
73
 
62
74
  # Defines a callback that is invoked whenever start tag is encountered.
63
75
  #
64
- # @yield [Node] block receives parsed node without any nested elements. All
65
- # inline attributes are available though.
76
+ # @yield [Node]
77
+ # block receives parsed node without any nested elements. All inline
78
+ # attributes are available though.
66
79
  #
80
+ # @return [nil]
67
81
  # @api public
68
82
  def on_start(&block)
69
83
  @callback_tree.add_callback(:start, @current_path, &block)
@@ -72,8 +86,10 @@ module SXRB
72
86
  # Defines a callback that is invoked whenever anonymous text node within
73
87
  # self is encountered.
74
88
  #
75
- # @yield [String] block receives raw content of parsed data in form of
76
- # String object.
89
+ # @yield [String]
90
+ # block receives raw content of parsed data in form of string object.
91
+ #
92
+ # @return [nil]
77
93
  #
78
94
  # @api public
79
95
  def on_characters(&block)
@@ -82,9 +98,11 @@ module SXRB
82
98
 
83
99
  # Defines a callback that is invoked whenever end tag is encountered.
84
100
  #
85
- # @yield [Node] block receives parsed node without any nested elements. All
86
- # inline attributes are available though.
101
+ # @yield [Node]
102
+ # block receives parsed node without any nested elements. All inline
103
+ # attributes are available though.
87
104
  #
105
+ # @return [nil]
88
106
  # @api public
89
107
  def on_end(&block)
90
108
  @callback_tree.add_callback(:end, @current_path, &block)
@@ -1,13 +1,19 @@
1
1
  module SXRB
2
+ # Class representing special case of DOM nodes which contain only text, and
3
+ # don't represent any particular element.
2
4
  class TextNode < Node
5
+ # @api private
3
6
  def initialize(text)
4
7
  @text = text || ""
5
8
  end
6
9
 
10
+ # @api private
7
11
  def append_text(text)
8
12
  @text << text
9
13
  end
10
14
 
15
+ # Accessor for text data kept in TextNode object.
16
+ # @return [String]
11
17
  def text
12
18
  @text
13
19
  end
@@ -1,92 +1,125 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
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)
4
+ context 'constructors' do
5
+ it 'should fail when created without block' do
6
+ expect {
7
+ SXRB::Parser.new("<xmlstring/>")
8
+ }.to raise_error(ArgumentError)
9
+ end
10
+
11
+ it 'defined rules should be reusable' do
12
+ @handler = double('handler')
13
+ @handler.should_receive(:msg).twice
14
+ rules = SXRB::Parser.define_rules do |root|
15
+ root.child("el") do |el|
16
+ el.on_element {@handler.msg}
17
+ end
18
+ end
19
+ SXRB::Parser.parse_string('<el></el>', rules)
20
+ SXRB::Parser.parse_string('<el></el>', rules)
21
+ end
8
22
  end
9
23
 
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
24
+ context 'matchers' do
25
+ before(:each) do
26
+ @handler = double('handler')
27
+ end
14
28
 
29
+ it 'should call defined start callback for child element' do
30
+ @handler.should_receive(:msg).once
15
31
  SXRB::Parser.new("<testelement>content</testelement>") do |xml|
16
32
  xml.child 'testelement' do |test_element|
17
- test_element.on_start do |element|
18
- handler.msg
19
- end
33
+ test_element.on_start {@handler.msg}
20
34
  end
21
35
  end
22
36
  end
23
37
 
24
38
  it 'should call defined end callback for child element' do
25
- handler = double('handler')
26
- handler.should_receive(:msg).once
27
-
39
+ @handler.should_receive(:msg).once
28
40
  SXRB::Parser.new("<testelement>content</testelement>") do |xml|
29
41
  xml.child 'testelement' do |test_element|
30
- test_element.on_end do |element|
31
- handler.msg
32
- end
42
+ test_element.on_end {@handler.msg}
33
43
  end
34
44
  end
35
45
  end
36
46
 
37
47
  it 'should call defined characters callback for child element' do
38
- handler = double('handler')
39
- handler.should_receive(:msg).once
40
-
48
+ @handler.should_receive(:msg).once
41
49
  SXRB::Parser.new("<testelement>content</testelement>") do |xml|
42
50
  xml.child 'testelement' do |test_element|
43
- test_element.on_characters do |element|
44
- handler.msg
45
- end
51
+ test_element.on_characters {@handler.msg}
46
52
  end
47
53
  end
48
54
  end
49
55
 
50
56
 
51
57
  it 'should call defined element callback for child element' do
52
- handler = double('handler')
53
- handler.should_receive(:msg).once
54
-
58
+ @handler.should_receive(:msg).once
55
59
  SXRB::Parser.new("<testelement>content</testelement>") do |xml|
56
60
  xml.child 'testelement' do |test_element|
57
- test_element.on_element do |element|
58
- handler.msg
59
- end
61
+ test_element.on_element {@handler.msg}
60
62
  end
61
63
  end
62
64
  end
63
65
 
64
66
  it 'should call defined element callback for child element only' do
65
- handler = double('handler')
66
- handler.should_receive(:msg).once
67
-
67
+ @handler.should_receive(:msg).once
68
68
  SXRB::Parser.new("<testelement><testelement>content</testelement></testelement>") do |xml|
69
69
  xml.child 'testelement' do |test_element|
70
- test_element.on_element do |element|
71
- handler.msg
72
- end
70
+ test_element.on_element {@handler.msg}
73
71
  end
74
72
  end
75
73
  end
76
74
 
77
75
  it 'should call defined element callback for all descendants' do
78
- handler = double('handler')
79
- handler.should_receive(:msg).twice
80
-
76
+ @handler.should_receive(:msg).twice
81
77
  SXRB::Parser.new("<testelement><testelement>content</testelement></testelement>") do |xml|
82
78
  xml.descendant 'testelement' do |test_element|
83
- test_element.on_element do |element|
84
- handler.msg
85
- end
79
+ test_element.on_element {@handler.msg}
80
+ end
81
+ end
82
+ end
83
+
84
+ it 'should call callback for element regardless of nested elements' do
85
+ @handler.should_receive(:msg).once
86
+ SXRB::Parser.new("<testelement><a>a-content</a></testelement>") do |xml|
87
+ xml.child 'testelement' do |test_element|
88
+ test_element.on_element {@handler.msg}
89
+ end
90
+ end
91
+ end
92
+
93
+ it 'should not invoke callback for child which isn\'t direct descendant' do
94
+ @handler.should_not_receive(:msg)
95
+ SXRB::Parser.new("<testelement><a>a-content</a></testelement>") do |xml|
96
+ xml.child 'a' do |a|
97
+ a.on_element {@handler.msg}
86
98
  end
87
99
  end
88
100
  end
89
101
 
102
+ it 'should not find element with non-matching name' do
103
+ @handler.should_not_receive(:msg)
104
+ SXRB::Parser.new("<testelement>content</testelement>") do |xml|
105
+ xml.child 'othername' do |test_element|
106
+ test_element.on_element {@handler.msg}
107
+ end
108
+ end
109
+ end
110
+
111
+ it 'should find element by regexp' do
112
+ pending "feature not ready yet"
113
+ SXRB::Parser.new("<testelement>content</testelement>") do |xml|
114
+ xml.child /testel/ do |test_element|
115
+ test_element.on_element {@handler.msg}
116
+ end
117
+ end
118
+ end
119
+ end
120
+
121
+ context 'passed values' do
122
+
90
123
  it 'should pass empty hash to callback when no attributes are given' do
91
124
  SXRB::Parser.new("<testelement>content</testelement>") do |xml|
92
125
  xml.child 'testelement' do |test_element|
@@ -97,32 +130,51 @@ describe SXRB::Parser do
97
130
  end
98
131
  end
99
132
 
100
- it 'should pass value properly to callback to on_element' do
101
- SXRB::Parser.new("<testelement>content</testelement>") do |xml|
133
+ it 'should pass attributes properly to on_start callback' do
134
+ SXRB::Parser.new('<testelement foo="bar">content</testelement>') do |xml|
135
+ xml.child 'testelement' do |test_element|
136
+ test_element.on_start do |element|
137
+ element.attributes.should == {'foo' => 'bar'}
138
+ end
139
+ end
140
+ end
141
+ end
142
+
143
+ it 'should pass attributes properly to on_element callback' do
144
+ SXRB::Parser.new('<testelement foo="bar">content</testelement>') do |xml|
102
145
  xml.child 'testelement' do |test_element|
103
146
  test_element.on_element do |element|
104
- element.children.first.text == 'content'
147
+ element.attributes.should == {'foo' => 'bar'}
105
148
  end
106
149
  end
107
150
  end
108
151
  end
109
152
 
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'
153
+ it 'should pass attributes properly to on_end callback' do
154
+ SXRB::Parser.new('<testelement foo="bar">content</testelement>') do |xml|
155
+ xml.child 'testelement' do |test_element|
156
+ test_element.on_end do |element|
157
+ element.attributes.should == {'foo' => 'bar'}
115
158
  end
116
159
  end
117
160
  end
118
161
  end
119
162
 
120
- it 'should find element by regexp' do
121
- pending "feature not ready yet"
163
+ it 'should pass concatenated content' do
164
+ SXRB::Parser.new("<testelement><a>con</a>tent</testelement>") do |xml|
165
+ xml.child 'testelement' do |test_element|
166
+ test_element.on_element do |element|
167
+ element.content == 'content'
168
+ end
169
+ end
170
+ end
171
+ end
172
+
173
+ it 'should pass value properly to callback to on_element' do
122
174
  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'
175
+ xml.child 'testelement' do |test_element|
176
+ test_element.on_element do |element|
177
+ element.content == 'content'
126
178
  end
127
179
  end
128
180
  end
@@ -133,20 +185,18 @@ describe SXRB::Parser do
133
185
  xml.child 'testelement' do |test_element|
134
186
  test_element.child 'a' do |a|
135
187
  a.on_element do |element|
136
- element.children.first.text == 'a-content'
188
+ element.content == 'a-content'
137
189
  end
138
190
  end
139
191
  end
140
192
  end
141
193
  end
142
194
 
143
- it 'should call callback for element regardless of nested elements' do
144
- handler = double('handler')
145
- handler.should_receive(:msg).once
195
+ it 'should pass nested elements content on_element callback' do
146
196
  SXRB::Parser.new("<testelement><a>a-content</a></testelement>") do |xml|
147
197
  xml.child 'testelement' do |test_element|
148
- test_element.on_element do |element|
149
- handler.msg
198
+ test_element.on_element do |node|
199
+ node.content.should == 'a-content'
150
200
  end
151
201
  end
152
202
  end
@@ -158,7 +208,7 @@ describe SXRB::Parser do
158
208
  test_element.on_element do |element|
159
209
  element.children.first.tap do |a|
160
210
  a.name.should == 'a'
161
- a.children.first.text.should == 'a-content'
211
+ a.content.should == 'a-content'
162
212
  end
163
213
  end
164
214
  end
@@ -0,0 +1,8 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'sxrb'
4
+ require 'rspec'
5
+ require 'rspec/autorun'
6
+
7
+ RSpec.configure do |config|
8
+ 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.2
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-07 00:00:00.000000000 Z
12
+ date: 2012-08-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: libxml-ruby
@@ -40,7 +40,9 @@ files:
40
40
  - lib/sxrb/errors.rb
41
41
  - lib/sxrb/proxy.rb
42
42
  - lib/sxrb.rb
43
+ - CHANGELOG
43
44
  - spec/parser_spec.rb
45
+ - spec/spec_helper.rb
44
46
  homepage: http://rubygems.org/gems/sxrb
45
47
  licenses:
46
48
  - MIT
@@ -68,4 +70,5 @@ specification_version: 3
68
70
  summary: Smart XML parser
69
71
  test_files:
70
72
  - spec/parser_spec.rb
73
+ - spec/spec_helper.rb
71
74
  has_rdoc: