Skip to content

Commit

Permalink
Merge pull request #61 from aderyabin/using_block
Browse files Browse the repository at this point in the history
Add Blocks support
  • Loading branch information
krasnoukhov committed Dec 16, 2014
2 parents 44e6e86 + d7ef99b commit a29294c
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 7 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,10 @@ end

class Atom
include SAXMachine
element :title
# Using block handle custom parsing behavior
element :title do |title|
title.strip
end
# The :with argument means that you only match a link tag
# that has an attribute of type: "text/html"
element :link, value: :href, as: :url, with: {
Expand Down
21 changes: 15 additions & 6 deletions lib/sax-machine/sax_document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,16 @@ def parse(*args)
new.parse(*args)
end

def element(name, options = {})
def element(name, options = {}, &block)
real_name = (options[:as] ||= name).to_s
sax_config.add_top_level_element(name, options)
create_attr(real_name)
create_attr(real_name, &block)
end

def attribute(name, options = {})
def attribute(name, options = {}, &block)
real_name = (options[:as] ||= name).to_s
sax_config.add_top_level_attribute(self.class.to_s, options.merge(name: name))
create_attr(real_name)
create_attr(real_name, &block)
end

def value(name, options = {})
Expand Down Expand Up @@ -115,9 +115,18 @@ def sax_config
# we only want to insert the getter and setter if they haven't defined it from elsewhere.
# this is how we allow custom parsing behavior. So you could define the setter
# and have it parse the string into a date or whatever.
def create_attr(real_name)
def create_attr(real_name, &block)
attr_reader(real_name) unless method_defined?(real_name)
attr_writer(real_name) unless method_defined?("#{real_name}=")

if !method_defined?("#{real_name}=")
if block_given?
define_method("#{real_name}=") do |value|
instance_variable_set("@#{real_name}", (yield value))
end
else
attr_writer(real_name)
end
end
end
end
end
35 changes: 35 additions & 0 deletions spec/sax-machine/sax_document_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,41 @@ def title=(val)
expect(@klass.required?(:date)).to be_truthy
end
end

describe "the block" do
before do
@klass = Class.new do
include SAXMachine

element :title do |title|
"#{title}!!!"
end

attribute :id do |id|
id.to_i
end

element :link, value: :foo do |link|
link.downcase
end
end
end

it "handle element" do
document = @klass.parse("<title>SAX</title>")
expect(document.title).to eq("SAX!!!")
end

it 'handle attribute' do
document = @klass.parse("<title id='345'>SAX</title>")
expect(document.id).to eq(345)
end

it "handle attribute value" do
document = @klass.parse("<link foo='tEst'>hello</link>")
expect(document.link).to eq("test")
end
end
end

describe "when parsing multiple elements" do
Expand Down

0 comments on commit a29294c

Please sign in to comment.