From 97e59fe449ed864bcf5e053b0198e8f33118196c Mon Sep 17 00:00:00 2001
From: Yorick Peterse
Date: Thu, 7 Aug 2014 20:03:26 +0200
Subject: [PATCH] Use the Namespace class for namespaces vs Strings.
---
lib/oga/xml/attribute.rb | 13 +++--
lib/oga/xml/element.rb | 24 +++++++---
lib/oga/xml/parser.y | 9 +++-
lib/oga/xpath/evaluator.rb | 2 +-
spec/oga/xml/attribute_spec.rb | 21 ++++++--
spec/oga/xml/element_spec.rb | 58 ++++++++++++++++++-----
spec/oga/xml/parser/elements_spec.rb | 6 +--
spec/oga/xpath/evaluator/general_spec.rb | 4 +-
spec/oga/xpath/evaluator/wildcard_spec.rb | 8 ++--
9 files changed, 110 insertions(+), 35 deletions(-)
diff --git a/lib/oga/xml/attribute.rb b/lib/oga/xml/attribute.rb
index ae1af3f..7b940bb 100644
--- a/lib/oga/xml/attribute.rb
+++ b/lib/oga/xml/attribute.rb
@@ -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
diff --git a/lib/oga/xml/element.rb b/lib/oga/xml/element.rb
index 6fedff4..78c80f3 100644
--- a/lib/oga/xml/element.rb
+++ b/lib/oga/xml/element.rb
@@ -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] :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
diff --git a/lib/oga/xml/parser.y b/lib/oga/xml/parser.y
index 52c1f2f..f7de1c7 100644
--- a/lib/oga/xml/parser.y
+++ b/lib/oga/xml/parser.y
@@ -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
)
diff --git a/lib/oga/xpath/evaluator.rb b/lib/oga/xpath/evaluator.rb
index ee34e32..02206e3 100644
--- a/lib/oga/xpath/evaluator.rb
+++ b/lib/oga/xpath/evaluator.rb
@@ -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.
diff --git a/spec/oga/xml/attribute_spec.rb b/spec/oga/xml/attribute_spec.rb
index 59faadc..8b940fb 100644
--- a/spec/oga/xml/attribute_spec.rb
+++ b/spec/oga/xml/attribute_spec.rb
@@ -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
diff --git a/spec/oga/xml/element_spec.rb b/spec/oga/xml/element_spec.rb
index 71a6876..b117152 100644
--- a/spec/oga/xml/element_spec.rb
+++ b/spec/oga/xml/element_spec.rb
@@ -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 == '
'
+ instance.to_xml.should == ''
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
diff --git a/spec/oga/xml/parser/elements_spec.rb b/spec/oga/xml/parser/elements_spec.rb
index d751531..61c5285 100644
--- a/spec/oga/xml/parser/elements_spec.rb
+++ b/spec/oga/xml/parser/elements_spec.rb
@@ -17,7 +17,7 @@ describe Oga::XML::Parser do
context 'elements with namespaces' do
before :all do
- @element = parse('').children[0]
+ @element = parse('').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
diff --git a/spec/oga/xpath/evaluator/general_spec.rb b/spec/oga/xpath/evaluator/general_spec.rb
index 5424def..fca0a91 100644
--- a/spec/oga/xpath/evaluator/general_spec.rb
+++ b/spec/oga/xpath/evaluator/general_spec.rb
@@ -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
diff --git a/spec/oga/xpath/evaluator/wildcard_spec.rb b/spec/oga/xpath/evaluator/wildcard_spec.rb
index a30191f..c096156 100644
--- a/spec/oga/xpath/evaluator/wildcard_spec.rb
+++ b/spec/oga/xpath/evaluator/wildcard_spec.rb
@@ -22,8 +22,8 @@ describe Oga::XPath::Evaluator do
end
example 'include the 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 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