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
# The namespace of the attribute.
# @return [String]
# @return [Oga::XML::Namespace]
#
# @!attribute [rw] value
# The value of the attribute.
@ -22,10 +22,17 @@ module Oga
# @param [Hash] options
#
# @option options [String] :name
# @option options [String] :namespace
# @option options [Oga::XML::Namespace] :namespace
# @option options [String] :value
#
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]
@namespace = options[:namespace]
@value = options[:value]
@ -54,7 +61,7 @@ module Oga
[:name, :namespace, :value].each do |attr|
value = send(attr)
if value and !value.empty?
if value
segments << "#{attr}: #{value.inspect}"
end
end

View File

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

View File

@ -148,7 +148,12 @@ rule
: T_ATTR { Attribute.new(:name => val[0]) }
# 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
@ -334,7 +339,7 @@ Unexpected #{name} with value #{value.inspect} on line #{@line}:
#
def on_element(namespace, name, attributes = {})
element = Element.new(
:namespace => namespace,
:namespace => Namespace.new(:name => namespace),
:name => name,
:attributes => attributes
)

View File

@ -439,7 +439,7 @@ module Oga
ns_matches = false
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
# the namespace as matching.

View File

@ -7,7 +7,16 @@ describe Oga::XML::Attribute do
end
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
example 'set the value' do
@ -35,9 +44,15 @@ describe Oga::XML::Attribute do
context '#inspect' 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

View File

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

View File

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

View File

@ -26,8 +26,10 @@ describe Oga::XPath::Evaluator do
context '#node_matches?' do
before do
ns = Oga::XML::Namespace.new(:name => 'x')
@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
example 'return true if a node is matched by its name' do

View File

@ -22,8 +22,8 @@ describe Oga::XPath::Evaluator do
end
example 'include the <ns1:c> node' do
@set[2].name.should == 'c'
@set[2].namespace.should == 'ns1'
@set[2].name.should == 'c'
@set[2].namespace.name.should == 'ns1'
end
end
@ -55,8 +55,8 @@ describe Oga::XPath::Evaluator do
it_behaves_like :node_set, :length => 1
example 'include the correct <c> node' do
@set[0].name.should == 'c'
@set[0].namespace.should == 'ns1'
@set[0].name.should == 'c'
@set[0].namespace.name.should == 'ns1'
end
end