612 lines
17 KiB
Ruby
612 lines
17 KiB
Ruby
require 'spec_helper'
|
|
|
|
describe Oga::XML::Element do
|
|
describe '#initialize' do
|
|
it 'sets the name via the constructor' do
|
|
described_class.new(:name => 'p').name.should == 'p'
|
|
end
|
|
|
|
it 'sets the default attributes' do
|
|
described_class.new.attributes.should == []
|
|
end
|
|
|
|
describe 'with a namespace' do
|
|
before do
|
|
attr = Oga::XML::Attribute.new(
|
|
:name => 'foo',
|
|
:namespace_name => 'xmlns'
|
|
)
|
|
|
|
@element = described_class.new(:attributes => [attr])
|
|
end
|
|
|
|
it 'registers the "foo" namespace' do
|
|
@element.namespaces['foo'].is_a?(Oga::XML::Namespace).should == true
|
|
end
|
|
|
|
it 'keeps the attributes after registering the namespaces' do
|
|
@element.attributes.empty?.should == false
|
|
end
|
|
end
|
|
|
|
describe 'with a default namespace' do
|
|
before do
|
|
attr = Oga::XML::Attribute.new(:name => 'xmlns', :value => 'foo')
|
|
|
|
@element = described_class.new(:attributes => [attr])
|
|
end
|
|
|
|
it 'registers the default namespace' do
|
|
@element.namespaces['xmlns'].is_a?(Oga::XML::Namespace).should == true
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#namespace_name=' do
|
|
it 'sets the namepace name' do
|
|
element = described_class.new(:name => 'a')
|
|
|
|
element.namespace_name = 'foo'
|
|
|
|
element.namespace_name.should == 'foo'
|
|
end
|
|
end
|
|
|
|
describe '#attribute' do
|
|
before do
|
|
attributes = [
|
|
Oga::XML::Attribute.new(:name => 'key', :value => 'value'),
|
|
Oga::XML::Attribute.new(
|
|
:name => 'bar',
|
|
:value => 'baz',
|
|
:namespace_name => 'x'
|
|
),
|
|
Oga::XML::Attribute.new(
|
|
:name => 'key',
|
|
:value => 'foo',
|
|
:namespace_name => 'x'
|
|
)
|
|
]
|
|
|
|
@instance = described_class.new(
|
|
:attributes => attributes,
|
|
:namespaces => {'x' => Oga::XML::Namespace.new(:name => 'x')}
|
|
)
|
|
end
|
|
|
|
it 'returns an attribute with only a name' do
|
|
@instance.attribute('key').value.should == 'value'
|
|
end
|
|
|
|
it 'returns an attribute with only a name when using a Symbol' do
|
|
@instance.attribute(:key).value.should == 'value'
|
|
end
|
|
|
|
it 'returns an attribute with a name and namespace' do
|
|
@instance.attribute('x:key').value.should == 'foo'
|
|
end
|
|
|
|
it 'returns an attribute with a name and namespace when using a Symbol' do
|
|
@instance.attribute(:'x:key').value.should == 'foo'
|
|
end
|
|
|
|
it 'returns nil when the name matches but the namespace does not' do
|
|
@instance.attribute('y:key').nil?.should == true
|
|
end
|
|
|
|
it 'returns nil when the namespace matches but the name does not' do
|
|
@instance.attribute('x:foobar').nil?.should == true
|
|
end
|
|
|
|
it 'returns nil for a non existing attribute' do
|
|
@instance.attribute('foobar').nil?.should == true
|
|
end
|
|
|
|
it 'returns nil if an attribute has a namespace that is not given' do
|
|
@instance.attribute('bar').nil?.should == true
|
|
end
|
|
end
|
|
|
|
describe '#get' do
|
|
before do
|
|
attr = Oga::XML::Attribute.new(:name => 'foo', :value => 'bar')
|
|
|
|
@element = described_class.new(:attributes => [attr])
|
|
end
|
|
|
|
it 'returns the value of an attribute' do
|
|
@element.get('foo').should == 'bar'
|
|
end
|
|
end
|
|
|
|
describe '#add_attribute' do
|
|
before do
|
|
@element = described_class.new
|
|
@attribute = Oga::XML::Attribute.new(:name => 'foo', :value => 'bar')
|
|
end
|
|
|
|
it 'adds an Attribute to the element' do
|
|
@element.add_attribute(@attribute)
|
|
|
|
@element.attribute('foo').should == @attribute
|
|
end
|
|
|
|
it 'sets the element of the attribute when adding it' do
|
|
@element.add_attribute(@attribute)
|
|
|
|
@attribute.element.should == @element
|
|
end
|
|
end
|
|
|
|
describe '#set' do
|
|
before do
|
|
@element = described_class.new
|
|
|
|
@element.register_namespace('x', 'test')
|
|
end
|
|
|
|
it 'adds a new attribute' do
|
|
@element.set('class', 'foo')
|
|
|
|
@element.get('class').should == 'foo'
|
|
end
|
|
|
|
it 'adds a new attribute with a namespace' do
|
|
@element.set('x:bar', 'foo')
|
|
|
|
@element.get('x:bar').should == 'foo'
|
|
end
|
|
|
|
it 'sets the namespace of an attribute' do
|
|
@element.set('x:bar', 'foo')
|
|
|
|
attr = @element.attribute('x:bar')
|
|
|
|
attr.namespace.is_a?(Oga::XML::Namespace).should == true
|
|
end
|
|
|
|
it 'overwrites the value of an existing attribute' do
|
|
attr = Oga::XML::Attribute.new(:name => 'foo', :value => 'bar')
|
|
|
|
@element.add_attribute(attr)
|
|
|
|
@element.set('foo', 'baz')
|
|
|
|
@element.get('foo').should == 'baz'
|
|
end
|
|
end
|
|
|
|
describe '#unset' do
|
|
before do
|
|
@element = described_class.new
|
|
|
|
@element.register_namespace('x', 'test')
|
|
|
|
@element.set('foo', 'bar')
|
|
@element.set('x:foo', 'bar')
|
|
end
|
|
|
|
it 'removes an attribute by its name' do
|
|
@element.unset('foo')
|
|
|
|
@element.get('foo').should be_nil
|
|
end
|
|
|
|
it 'removes an attribute using a namespace' do
|
|
@element.unset('x:foo')
|
|
|
|
@element.get('x:foo').should be_nil
|
|
end
|
|
end
|
|
|
|
describe '#namespace' do
|
|
it 'returns the namespace' do
|
|
namespace = Oga::XML::Namespace.new(:name => 'x')
|
|
element = described_class.new(
|
|
:namespace_name => 'x',
|
|
:namespaces => {'x' => namespace}
|
|
)
|
|
|
|
element.namespace.should == namespace
|
|
end
|
|
|
|
it 'returns the default namespace if available' do
|
|
namespace = Oga::XML::Namespace.new(:name => 'xmlns')
|
|
element = described_class.new(
|
|
:namespaces => {'xmlns' => namespace}
|
|
)
|
|
|
|
element.namespace.should == namespace
|
|
end
|
|
|
|
it 'flushes the cache when changing the namespace name' do
|
|
namespace = Oga::XML::Namespace.new(:name => 'bar')
|
|
element = described_class.new(
|
|
:namespaces => {'bar' => namespace}
|
|
)
|
|
|
|
element.namespace_name = 'foo'
|
|
|
|
element.namespace.should be_nil
|
|
end
|
|
|
|
describe 'in an HTML document' do
|
|
it 'returns nil' do
|
|
ns = Oga::XML::Namespace.new(:name => 'xmlns')
|
|
el = described_class.new(:namespaces => {'xmlns' => ns})
|
|
doc = Oga::XML::Document.new(:type => :html, :children => [el])
|
|
|
|
el.namespace.should be_nil
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#namespaces' do
|
|
it 'returns the registered namespaces as a Hash' do
|
|
namespace = Oga::XML::Namespace.new(:name => 'x')
|
|
element = described_class.new(
|
|
:namespace_name => 'x',
|
|
:namespaces => {'x' => namespace}
|
|
)
|
|
|
|
element.namespaces.should == {'x' => namespace}
|
|
end
|
|
|
|
describe 'in an HTML document' do
|
|
it 'returns an empty Hash' do
|
|
ns = Oga::XML::Namespace.new(:name => 'xmlns')
|
|
el = described_class.new(:namespaces => {'xmlns' => ns})
|
|
doc = Oga::XML::Document.new(:type => :html, :children => [el])
|
|
|
|
el.namespaces.should == {}
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#default_namespace?' do
|
|
it 'returns true when an element has no explicit namespace' do
|
|
described_class.new(:name => 'a').default_namespace?.should == true
|
|
end
|
|
|
|
it 'returns true when an element has an explicit default namespace' do
|
|
element = described_class.new(:name => 'a')
|
|
namespace = Oga::XML::DEFAULT_NAMESPACE
|
|
|
|
element.register_namespace(namespace.name, namespace.uri)
|
|
|
|
element.default_namespace?.should == true
|
|
end
|
|
|
|
it 'returns false when an element resides in a custom namespace' do
|
|
element = described_class.new(:name => 'a')
|
|
|
|
element.register_namespace('xmlns', 'foo')
|
|
|
|
element.default_namespace?.should == false
|
|
end
|
|
end
|
|
|
|
describe '#text' do
|
|
before do
|
|
t1 = Oga::XML::Text.new(:text => 'Foo')
|
|
t2 = Oga::XML::Text.new(:text => 'Bar')
|
|
|
|
@n1 = described_class.new(:children => [t1])
|
|
@n2 = described_class.new(:children => [@n1, t2])
|
|
end
|
|
|
|
it 'returns the text of the parent node and its child nodes' do
|
|
@n2.text.should == 'FooBar'
|
|
end
|
|
|
|
it 'returns the text of the child node' do
|
|
@n1.text.should == 'Foo'
|
|
end
|
|
end
|
|
|
|
describe '#inner_text' do
|
|
before do
|
|
t1 = Oga::XML::Text.new(:text => 'Foo')
|
|
t2 = Oga::XML::Text.new(:text => 'Bar')
|
|
|
|
@n1 = described_class.new(:children => [t1])
|
|
@n2 = described_class.new(:children => [@n1, t2])
|
|
end
|
|
|
|
it 'returns the inner text of the parent node' do
|
|
@n2.inner_text.should == 'Bar'
|
|
end
|
|
|
|
it 'returns the inner text of the child node' do
|
|
@n1.inner_text.should == 'Foo'
|
|
end
|
|
end
|
|
|
|
describe '#inner_text=' do
|
|
before do
|
|
@element = described_class.new
|
|
end
|
|
|
|
it 'sets the inner text of an element' do
|
|
@element.inner_text = 'foo'
|
|
@element.inner_text.should == 'foo'
|
|
end
|
|
|
|
it 'removes all existing nodes before inserting a new text node' do
|
|
@element.children << Oga::XML::Text.new(:text => 'foo')
|
|
@element.children << Oga::XML::Element.new(:name => 'x')
|
|
|
|
@element.inner_text = 'bar'
|
|
|
|
@element.children.length.should == 1
|
|
end
|
|
|
|
it 'sets the parent node of the newly inserted text node' do
|
|
@element.inner_text = 'foo'
|
|
|
|
@element.children[0].parent.should == @element
|
|
end
|
|
end
|
|
|
|
describe '#text_nodes' do
|
|
before do
|
|
@t1 = Oga::XML::Text.new(:text => 'Foo')
|
|
@t2 = Oga::XML::Text.new(:text => 'Bar')
|
|
|
|
@element = described_class.new(:children => [@t1, @t2])
|
|
end
|
|
|
|
it 'returns a node set containing the text nodes' do
|
|
@element.text_nodes.should == node_set(@t1, @t2)
|
|
end
|
|
end
|
|
|
|
describe '#to_xml' do
|
|
it 'generates the corresponding XML' do
|
|
described_class.new(:name => 'p').to_xml.should == '<p />'
|
|
end
|
|
|
|
it 'includes the namespace if present' do
|
|
instance = described_class.new(
|
|
:name => 'p',
|
|
:namespace_name => 'foo',
|
|
:namespaces => {'foo' => Oga::XML::Namespace.new(:name => 'foo')},
|
|
:children => [Oga::XML::Text.new(:text => 'Foo')]
|
|
)
|
|
|
|
instance.to_xml.should == '<foo:p>Foo</foo:p>'
|
|
end
|
|
|
|
it 'includes a single attribute if present' do
|
|
instance = described_class.new(
|
|
:name => 'p',
|
|
:attributes => [
|
|
Oga::XML::Attribute.new(:name => 'key', :value => 'value')
|
|
]
|
|
)
|
|
|
|
instance.to_xml.should == '<p key="value" />'
|
|
end
|
|
|
|
it 'includes multiple attributes if present' do
|
|
instance = described_class.new(
|
|
:name => 'p',
|
|
:attributes => [
|
|
Oga::XML::Attribute.new(:name => 'key1', :value => 'value1'),
|
|
Oga::XML::Attribute.new(:name => 'key2', :value => 'value2'),
|
|
]
|
|
)
|
|
|
|
instance.to_xml.should == '<p key1="value1" key2="value2" />'
|
|
end
|
|
|
|
it 'includes the child nodes if present' do
|
|
instance = described_class.new(
|
|
:name => 'p',
|
|
:children => [Oga::XML::Comment.new(:text => 'foo')]
|
|
)
|
|
|
|
instance.to_xml.should == '<p><!--foo--></p>'
|
|
end
|
|
|
|
it 'generates the corresponding XML when using a default namespace' do
|
|
namespace = Oga::XML::Namespace.new(:name => 'xmlns', :uri => 'foo')
|
|
instance = described_class.new(
|
|
:name => 'foo',
|
|
:namespaces => {'xmlns' => namespace}
|
|
)
|
|
|
|
instance.to_xml.should == '<foo />'
|
|
end
|
|
|
|
it 'generates the XML for the HTML <script> element' do
|
|
element = described_class.new(:name => 'script')
|
|
document = Oga::XML::Document.new(:type => :html, :children => [element])
|
|
|
|
element.to_xml.should == '<script></script>'
|
|
end
|
|
|
|
it 'generates the XML for the HTML <link> element' do
|
|
element = described_class.new(:name => 'link')
|
|
document = Oga::XML::Document.new(:type => :html, :children => [element])
|
|
|
|
element.to_xml.should == '<link />'
|
|
end
|
|
end
|
|
|
|
describe '#inspect' do
|
|
it 'inspects a node with a name' do
|
|
node = described_class.new(:name => 'a')
|
|
|
|
node.inspect.should == 'Element(name: "a")'
|
|
end
|
|
|
|
it 'inspects a node with attributes and children' do
|
|
node = described_class.new(
|
|
:name => 'p',
|
|
:children => [Oga::XML::Comment.new(:text => 'foo')],
|
|
:attributes => [Oga::XML::Attribute.new(:name => 'x', :value => 'y')]
|
|
)
|
|
|
|
node.inspect.should == 'Element(name: "p" attributes: ' \
|
|
'[Attribute(name: "x" value: "y")] children: NodeSet(Comment("foo")))'
|
|
end
|
|
|
|
it 'inspects a node with a namespace' do
|
|
node = described_class.new(
|
|
:name => 'p',
|
|
:namespace_name => 'x',
|
|
:namespaces => {'x' => Oga::XML::Namespace.new(:name => 'x')}
|
|
)
|
|
|
|
node.inspect.should == 'Element(name: "p" ' \
|
|
'namespace: Namespace(name: "x" uri: nil))'
|
|
end
|
|
end
|
|
|
|
describe '#register_namespace' do
|
|
before do
|
|
@element = described_class.new
|
|
|
|
@element.register_namespace('foo', 'http://example.com')
|
|
end
|
|
|
|
it 'returns a Namespace instance' do
|
|
@element.namespaces['foo'].is_a?(Oga::XML::Namespace).should == true
|
|
end
|
|
|
|
it 'sets the name of the namespace' do
|
|
@element.namespaces['foo'].name.should == 'foo'
|
|
end
|
|
|
|
it 'sets the URI of the namespace' do
|
|
@element.namespaces['foo'].uri.should == 'http://example.com'
|
|
end
|
|
|
|
it 'raises ArgumentError if the namespace already exists' do
|
|
block = lambda { @element.register_namespace('foo', 'bar') }
|
|
|
|
block.should raise_error(ArgumentError)
|
|
end
|
|
|
|
it 'flushes the cache when registering a namespace' do
|
|
@element.available_namespaces.should == {
|
|
'foo' => @element.namespaces['foo']
|
|
}
|
|
|
|
@element.register_namespace('bar', 'http://exmaple.com')
|
|
|
|
@element.available_namespaces.should == {
|
|
'foo' => @element.namespaces['foo'],
|
|
'bar' => @element.namespaces['bar']
|
|
}
|
|
end
|
|
|
|
it 'does not flush the cache when "flush" is set to false' do
|
|
@element.should_not receive(:flush_namespaces_cache)
|
|
|
|
@element.register_namespace('bar', 'http://example.com', false)
|
|
end
|
|
end
|
|
|
|
describe '#available_namespaces' do
|
|
before do
|
|
@parent = described_class.new
|
|
@child = described_class.new
|
|
|
|
@child.node_set = Oga::XML::NodeSet.new([@child], @parent)
|
|
|
|
@parent.register_namespace('foo', 'bar')
|
|
@parent.register_namespace('baz', 'yyy')
|
|
|
|
@child.register_namespace('baz', 'xxx')
|
|
|
|
@parent_ns = @parent.available_namespaces
|
|
@child_ns = @child.available_namespaces
|
|
end
|
|
|
|
it 'inherits the "foo" namespace from the parent' do
|
|
@child_ns['foo'].uri.should == 'bar'
|
|
end
|
|
|
|
it 'overwrites the "baz" namespace in the child' do
|
|
@child_ns['baz'].uri.should == 'xxx'
|
|
end
|
|
|
|
it 'returns the "foo" namespace for the parent' do
|
|
@parent_ns['foo'].uri.should == 'bar'
|
|
end
|
|
|
|
it 'returns the "baz" namespace for the parent' do
|
|
@parent_ns['baz'].uri.should == 'yyy'
|
|
end
|
|
|
|
it 'does not modify the list of direct namespaces' do
|
|
@child.namespaces.key?('foo').should == false
|
|
end
|
|
|
|
describe 'in an HTML document' do
|
|
it 'returns an empty Hash' do
|
|
ns = Oga::XML::Namespace.new(:name => 'xmlns')
|
|
el = described_class.new(:namespaces => {'xmlns' => ns})
|
|
doc = Oga::XML::Document.new(:type => :html, :children => [el])
|
|
|
|
el.available_namespaces.should == {}
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#self_closing?' do
|
|
it 'returns true for an empty XML element' do
|
|
described_class.new(:name => 'foo').should be_self_closing
|
|
end
|
|
|
|
it 'returns false for a non empty XML element' do
|
|
text = Oga::XML::Text.new(:text => 'bar')
|
|
node = described_class.new(:name => 'foo', :children => [text])
|
|
|
|
node.should_not be_self_closing
|
|
end
|
|
|
|
it 'returns true for an HTML void element' do
|
|
element = described_class.new(:name => 'link')
|
|
document = Oga::XML::Document.new(:type => :html, :children => [element])
|
|
|
|
element.should be_self_closing
|
|
end
|
|
|
|
it 'returns false for a non empty HTML element' do
|
|
text = Oga::XML::Text.new(:text => 'alert()')
|
|
element = described_class.new(:name => 'script', :children => [text])
|
|
document = Oga::XML::Document.new(:type => :html, :children => [element])
|
|
|
|
element.should_not be_self_closing
|
|
end
|
|
end
|
|
|
|
describe '#flush_namespaces_cache' do
|
|
it 'flushes the namespaces cache of the current element' do
|
|
element = described_class.new(:name => 'a')
|
|
|
|
element.available_namespaces.should == {}
|
|
|
|
element.register_namespace('foo', 'bar', false)
|
|
|
|
element.flush_namespaces_cache
|
|
|
|
element.available_namespaces.should == {
|
|
'foo' => element.namespaces['foo']
|
|
}
|
|
end
|
|
|
|
it 'flushes the namespace cache of all child elements' do
|
|
child = described_class.new(:name => 'b')
|
|
parent = described_class.new(:name => 'a', :children => [child])
|
|
|
|
child.should_receive(:flush_namespaces_cache)
|
|
|
|
parent.flush_namespaces_cache
|
|
end
|
|
end
|
|
end
|