Support for Enumerator inputs in the XML lexer.

This fixes #48.
This commit is contained in:
Yorick Peterse 2014-09-28 22:27:30 +02:00
parent 27ee23eb31
commit 0299ff1ea4
3 changed files with 45 additions and 22 deletions

View File

@ -66,7 +66,7 @@ module Oga
@line = 1 @line = 1
@elements = [] @elements = []
@data.rewind if io_input? @data.rewind if @data.respond_to?(:rewind)
reset_native reset_native
end end
@ -78,25 +78,18 @@ module Oga
# @yieldparam [String] # @yieldparam [String]
# #
def read_data def read_data
# We can't check for #each_line since String also defines that. Using if @data.is_a?(String)
# String#each_line has no benefit over just lexing the String in one
# go.
if io_input?
@data.each_line do |line|
yield line
end
else
yield @data yield @data
end
end
## # IO, StringIO, etc
# Returns `true` if the input is an IO like object, false otherwise. # THINK: read(N) would be nice, but currently this screws up the C code
# elsif @data.respond_to?(:each_line)
# @return [TrueClass|FalseClass] @data.each_line { |line| yield line }
#
def io_input? # Enumerator, Array, etc
return @data.is_a?(IO) || @data.is_a?(StringIO) elsif @data.respond_to?(:each)
@data.each { |chunk| yield chunk }
end
end end
## ##

View File

@ -0,0 +1,28 @@
require 'spec_helper'
describe Oga::XML::Lexer do
context 'Enumerator as input' do
before do
@enum = Enumerator.new do |yielder|
yielder << '<p>foo'
yielder << '</p>'
end
end
example 'lex a paragraph element' do
lex(@enum).should == [
[:T_ELEM_START, nil, 1],
[:T_ELEM_NAME, 'p', 1],
[:T_TEXT, 'foo', 1],
[:T_ELEM_END, nil, 1]
]
end
example 'rewind input when resetting the lexer' do
lexer = described_class.new(@enum)
lexer.lex.empty?.should == false
lexer.lex.empty?.should == false
end
end
end

View File

@ -2,10 +2,12 @@ require 'spec_helper'
describe Oga::XML::Lexer do describe Oga::XML::Lexer do
context 'IO as input' do context 'IO as input' do
example 'lex a paragraph element with attributes' do before do
io = StringIO.new("<p class='foo'>\nHello</p>") @io = StringIO.new("<p class='foo'>\nHello</p>")
end
lex(io).should == [ example 'lex a paragraph element with attributes' do
lex(@io).should == [
[:T_ELEM_START, nil, 1], [:T_ELEM_START, nil, 1],
[:T_ELEM_NAME, 'p', 1], [:T_ELEM_NAME, 'p', 1],
[:T_ATTR, 'class', 1], [:T_ATTR, 'class', 1],
@ -17,7 +19,7 @@ describe Oga::XML::Lexer do
end end
example 'rewind input when resetting the lexer' do example 'rewind input when resetting the lexer' do
lexer = described_class.new(StringIO.new(('<a>foo</a>'))) lexer = described_class.new(@io)
lexer.lex.empty?.should == false lexer.lex.empty?.should == false
lexer.lex.empty?.should == false lexer.lex.empty?.should == false