Fixed decoding entities in attribute values

This was broken by introducing the process of lazy decoding of XML/HTML
entities. The new setup works similar to how XML::Text#text decodes any
entities that may be present.

Fixes #91
This commit is contained in:
Yorick Peterse 2015-04-07 21:18:22 +02:00
parent ef7f50137a
commit 6a1010c287
2 changed files with 91 additions and 6 deletions

View File

@ -10,16 +10,12 @@ module Oga
# @!attribute [rw] namespace_name
# @return [String]
#
# @!attribute [rw] value
# The value of the attribute.
# @return [String]
#
# @!attribute [r] element
# The element this attribute belongs to.
# @return [Oga::XML::Element]
#
class Attribute
attr_accessor :name, :namespace_name, :element, :value
attr_accessor :name, :namespace_name, :element
##
# The default namespace available to all attributes. This namespace can
@ -67,8 +63,28 @@ module Oga
end
##
# Returns the value of the attribute.
# @param [String] value
#
def value=(value)
@value = value
@decoded = false
end
##
# Returns the value of the attribute or nil if no explicit value was set.
#
# @return [String|NilClass]
#
def value
if !@decoded and @value
@value = EntityDecoder.try_decode(@value, html?)
@decoded = true
end
return @value
end
##
# @return [String]
#
def text
@ -108,6 +124,15 @@ module Oga
return "Attribute(#{segments.join(' ')})"
end
private
##
# @return [TrueClass|FalseClass]
#
def html?
return !!@element && @element.html?
end
end # Attribute
end # XML
end # Oga

View File

@ -37,6 +37,66 @@ describe Oga::XML::Attribute do
end
end
describe '#value=' do
it 'sets the value of an attribute' do
attr = described_class.new
attr.value = 'foo'
attr.value.should == 'foo'
end
it 'flushes the decoded cache when setting a new value' do
attr = described_class.new(:value => '<')
attr.value.should == Oga::XML::Entities::DECODE_MAPPING['<']
attr.value = '>'
attr.value.should == Oga::XML::Entities::DECODE_MAPPING['>']
end
end
describe '#value' do
it 'returns the value of an attribute' do
described_class.new(:value => 'foo').value.should == 'foo'
end
describe 'using an XML document' do
before do
@el = Oga::XML::Element.new(:name => 'a')
@doc = Oga::XML::Document.new(:children => [@el], :type => :xml)
end
it 'returns a String with decoded XML entities' do
attr = described_class.new(
:name => 'class',
:value => '<',
:element => @el
)
attr.value.should == '<'
end
end
describe 'using HTML documents' do
before do
@el = Oga::XML::Element.new(:name => 'a')
@doc = Oga::XML::Document.new(:children => [@el], :type => :html)
end
it 'returns a String with decoded HTML entities' do
attr = described_class.new(
:name => 'class',
:value => '&copy;',
:element => @el
)
attr.value.should == Oga::HTML::Entities::DECODE_MAPPING['&copy;']
end
end
end
describe '#text' do
it 'returns an empty String when there is no value' do
described_class.new.text.should == ''