Use the Namespace class for namespaces vs Strings.

This commit is contained in:
Yorick Peterse 2014-08-07 20:03:26 +02:00
parent f653203220
commit 97e59fe449
9 changed files with 110 additions and 35 deletions

View File

@ -9,7 +9,7 @@ module Oga
# #
# @!attribute [rw] namespace # @!attribute [rw] namespace
# The namespace of the attribute. # The namespace of the attribute.
# @return [String] # @return [Oga::XML::Namespace]
# #
# @!attribute [rw] value # @!attribute [rw] value
# The value of the attribute. # The value of the attribute.
@ -22,10 +22,17 @@ module Oga
# @param [Hash] options # @param [Hash] options
# #
# @option options [String] :name # @option options [String] :name
# @option options [String] :namespace # @option options [Oga::XML::Namespace] :namespace
# @option options [String] :value # @option options [String] :value
# #
def initialize(options = {}) def initialize(options = {})
if options[:namespace] and !options[:namespace].is_a?(Namespace)
raise(
TypeError,
':namespace must be an instance of Oga::XML::Namespace'
)
end
@name = options[:name] @name = options[:name]
@namespace = options[:namespace] @namespace = options[:namespace]
@value = options[:value] @value = options[:value]
@ -54,7 +61,7 @@ module Oga
[:name, :namespace, :value].each do |attr| [:name, :namespace, :value].each do |attr|
value = send(attr) value = send(attr)
if value and !value.empty? if value
segments << "#{attr}: #{value.inspect}" segments << "#{attr}: #{value.inspect}"
end end
end end

View File

@ -10,7 +10,7 @@ module Oga
# #
# @!attribute [rw] namespace # @!attribute [rw] namespace
# The namespace of the element, if any. # The namespace of the element, if any.
# @return [String] # @return [Oga::XML::Namespace]
# #
# @!attribute [rw] attributes # @!attribute [rw] attributes
# The attributes of the element. # The attributes of the element.
@ -23,11 +23,21 @@ module Oga
# @param [Hash] options # @param [Hash] options
# #
# @option options [String] :name The name of the element. # @option options [String] :name The name of the element.
# @option options [String] :namespace The namespace of the element. #
# @option options [Oga::XML::Namespace] :namespace The namespace of the
# element.
#
# @option options [Array<Oga::XML::Attribute>] :attributes The attributes # @option options [Array<Oga::XML::Attribute>] :attributes The attributes
# of the element as an Array. # of the element as an Array.
# #
def initialize(options = {}) def initialize(options = {})
if options[:namespace] and !options[:namespace].is_a?(Namespace)
raise(
TypeError,
':namespace must be an instance of Oga::XML::Namespace'
)
end
super super
@name = options[:name] @name = options[:name]
@ -100,7 +110,7 @@ module Oga
attrs = " #{attrs}" unless attrs.empty? attrs = " #{attrs}" unless attrs.empty?
return "<#{ns}#{name}#{attrs}>#{body}</#{name}>" return "<#{ns}#{name}#{attrs}>#{body}</#{ns}#{name}>"
end end
## ##
@ -119,9 +129,11 @@ module Oga
[:name, :namespace, :attributes].each do |attr| [:name, :namespace, :attributes].each do |attr|
value = send(attr) value = send(attr)
if value and !value.empty? if !value or (value.respond_to?(:empty?) and value.empty?)
segments << "#{attr}: #{value.inspect}" next
end end
segments << "#{attr}: #{value.inspect}"
end end
return <<-EOF.chomp return <<-EOF.chomp
@ -163,7 +175,7 @@ module Oga
ns_matches = false ns_matches = false
if ns if ns
ns_matches = attr.namespace == ns ns_matches = attr.namespace.to_s == ns
elsif name_matches elsif name_matches
ns_matches = true ns_matches = true

View File

@ -148,7 +148,12 @@ rule
: T_ATTR { Attribute.new(:name => val[0]) } : T_ATTR { Attribute.new(:name => val[0]) }
# foo:bar # foo:bar
| T_ATTR_NS T_ATTR { Attribute.new(:namespace => val[0], :name => val[1]) } | T_ATTR_NS T_ATTR
{
ns = Namespace.new(:name => val[0])
Attribute.new(:namespace => ns, :name => val[1])
}
; ;
# XML declarations # XML declarations
@ -334,7 +339,7 @@ Unexpected #{name} with value #{value.inspect} on line #{@line}:
# #
def on_element(namespace, name, attributes = {}) def on_element(namespace, name, attributes = {})
element = Element.new( element = Element.new(
:namespace => namespace, :namespace => Namespace.new(:name => namespace),
:name => name, :name => name,
:attributes => attributes :attributes => attributes
) )

View File

@ -439,7 +439,7 @@ module Oga
ns_matches = false ns_matches = false
if ns if ns
ns_matches = xml_node.namespace == ns || ns == '*' ns_matches = xml_node.namespace.to_s == ns || ns == '*'
# If there's no namespace given but the name matches we'll also mark # If there's no namespace given but the name matches we'll also mark
# the namespace as matching. # the namespace as matching.

View File

@ -7,7 +7,16 @@ describe Oga::XML::Attribute do
end end
example 'set the namespace' do example 'set the namespace' do
described_class.new(:namespace => 'a').namespace.should == 'a' ns = Oga::XML::Namespace.new(:name => 'foo')
attr = described_class.new(:namespace => ns)
attr.namespace.should == ns
end
example 'raise TypeError when using a String for the namespace' do
block = lambda { described_class.new(:namespace => 'x') }
block.should raise_error(TypeError)
end end
example 'set the value' do example 'set the value' do
@ -35,9 +44,15 @@ describe Oga::XML::Attribute do
context '#inspect' do context '#inspect' do
example 'return the inspect value' do example 'return the inspect value' do
obj = described_class.new(:name => 'a', :namespace => 'b', :value => 'c') obj = described_class.new(
:name => 'a',
:namespace => Oga::XML::Namespace.new(:name => 'b'),
:value => 'c'
)
obj.inspect.should == 'Attribute(name: "a" namespace: "b" value: "c")' obj.inspect.should == <<-EOF.strip
Attribute(name: "a" namespace: Namespace(name: "b") value: "c")
EOF
end end
end end
end end

View File

@ -6,6 +6,12 @@ describe Oga::XML::Element do
described_class.new(:name => 'p').name.should == 'p' described_class.new(:name => 'p').name.should == 'p'
end end
example 'raise TypeError when the namespace is a String' do
block = lambda { described_class.new(:namespace => 'x') }
block.should raise_error(TypeError)
end
example 'set the name via a setter' do example 'set the name via a setter' do
instance = described_class.new instance = described_class.new
instance.name = 'p' instance.name = 'p'
@ -25,7 +31,7 @@ describe Oga::XML::Element do
Oga::XML::Attribute.new( Oga::XML::Attribute.new(
:name => 'key', :name => 'key',
:value => 'foo', :value => 'foo',
:namespace => 'x' :namespace => Oga::XML::Namespace.new(:name => 'x')
) )
] ]
@ -103,9 +109,12 @@ describe Oga::XML::Element do
end end
example 'include the namespace if present' do example 'include the namespace if present' do
instance = described_class.new(:name => 'p', :namespace => 'foo') instance = described_class.new(
:name => 'p',
:namespace => Oga::XML::Namespace.new(:name => 'foo')
)
instance.to_xml.should == '<foo:p></p>' instance.to_xml.should == '<foo:p></foo:p>'
end end
example 'include the attributes if present' do example 'include the attributes if present' do
@ -130,22 +139,47 @@ describe Oga::XML::Element do
end end
context '#inspect' do context '#inspect' do
before do example 'inspect a node with a name' do
children = [Oga::XML::Comment.new(:text => 'foo')] node = described_class.new(:name => 'a')
@instance = described_class.new(
:name => 'p', node.inspect.should == <<-EOF.strip
:children => children, Element(
:attributes => {'class' => 'foo'} name: "a"
) children: [
])
EOF
end end
example 'pretty-print the node' do example 'inspect a node with attributes and children' do
@instance.inspect.should == <<-EOF.strip node = described_class.new(
:name => 'p',
:children => [Oga::XML::Comment.new(:text => 'foo')],
:attributes => {'class' => 'foo'}
)
node.inspect.should == <<-EOF.strip
Element( Element(
name: "p" name: "p"
attributes: {"class"=>"foo"} attributes: {"class"=>"foo"}
children: [ children: [
Comment(text: "foo") Comment(text: "foo")
])
EOF
end
example 'inspect a node with a namespace' do
node = described_class.new(
:name => 'p',
:namespace => Oga::XML::Namespace.new(:name => 'x')
)
node.inspect.should == <<-EOF.strip
Element(
name: "p"
namespace: Namespace(name: "x")
children: [
]) ])
EOF EOF
end end

View File

@ -17,7 +17,7 @@ describe Oga::XML::Parser do
context 'elements with namespaces' do context 'elements with namespaces' do
before :all do before :all do
@element = parse('<foo:p></p>').children[0] @element = parse('<foo:p></foo:p>').children[0]
end end
example 'return an Element instance' do example 'return an Element instance' do
@ -29,7 +29,7 @@ describe Oga::XML::Parser do
end end
example 'set the namespace of the element' do example 'set the namespace of the element' do
@element.namespace.should == 'foo' @element.namespace.name.should == 'foo'
end end
end end
@ -57,7 +57,7 @@ describe Oga::XML::Parser do
end end
example 'include the namespace of the attribute' do example 'include the namespace of the attribute' do
@element.attribute('x:bar').namespace.should == 'x' @element.attribute('x:bar').namespace.name.should == 'x'
end end
example 'include the name of the attribute' do example 'include the name of the attribute' do

View File

@ -26,8 +26,10 @@ describe Oga::XPath::Evaluator do
context '#node_matches?' do context '#node_matches?' do
before do before do
ns = Oga::XML::Namespace.new(:name => 'x')
@name_node = Oga::XML::Element.new(:name => 'a') @name_node = Oga::XML::Element.new(:name => 'a')
@name_ns_node = Oga::XML::Element.new(:name => 'b', :namespace => 'x') @name_ns_node = Oga::XML::Element.new(:name => 'b', :namespace => ns)
end end
example 'return true if a node is matched by its name' do example 'return true if a node is matched by its name' do

View File

@ -23,7 +23,7 @@ describe Oga::XPath::Evaluator do
example 'include the <ns1:c> node' do example 'include the <ns1:c> node' do
@set[2].name.should == 'c' @set[2].name.should == 'c'
@set[2].namespace.should == 'ns1' @set[2].namespace.name.should == 'ns1'
end end
end end
@ -56,7 +56,7 @@ describe Oga::XPath::Evaluator do
example 'include the correct <c> node' do example 'include the correct <c> node' do
@set[0].name.should == 'c' @set[0].name.should == 'c'
@set[0].namespace.should == 'ns1' @set[0].namespace.name.should == 'ns1'
end end
end end