Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for assigning a class to an attribute #68

Merged
merged 4 commits into from
Mar 22, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion lib/sax-machine/config/sax_element_value.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
module SAXMachine
class SAXConfig
class ElementValueConfig
attr_reader :name, :setter
attr_reader :name, :setter, :data_class

def initialize(name, options)
@name = name.to_s
@as = options[:as]
@setter = "#{@as}="
@required = options[:required]
@data_class = options[:class]
end

def column
Expand Down
13 changes: 11 additions & 2 deletions lib/sax-machine/handlers/sax_abstract_handler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def _end_element(name)
case config.data_class.to_s
when "String" then value != NO_BUFFER ? value.to_s : value
when "Integer" then value != NO_BUFFER ? value.to_i : value
when "Float" then value != NO_BUFFER ? value.to_f : value
when "Float" then value != NO_BUFFER ? value.to_s.gsub(",",".").to_f : value
when "Symbol" then
if value != NO_BUFFER
value.to_s.empty? ? nil : value.to_s.downcase.to_sym
Expand Down Expand Up @@ -186,7 +186,16 @@ def set_attributes_on(object, attributes)

if config
config.attribute_configs_for_element(attributes).each do |ac|
object.send(ac.setter, ac.value_from_attrs(attributes))
value = ac.value_from_attrs(attributes)
new_value =
case ac.data_class.to_s
when "Integer" then value != NO_BUFFER ? value.to_i : value
when "Float" then value != NO_BUFFER ? value.to_s.gsub(",",".").to_f : value
when "Time" then value != NO_BUFFER ? Time.parse(value.to_s) : value
when "" then value

end
object.send(ac.setter, new_value)
end
end
end
Expand Down
144 changes: 108 additions & 36 deletions spec/sax-machine/sax_document_spec.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')

describe "SAXMachine" do
describe "element" do
describe "when parsing a single element" do
Expand Down Expand Up @@ -143,24 +142,66 @@ def title=(val)
expect(@klass.data_class(:date)).to eq(DateTime)
end

it "handles an integer class" do
@klass = Class.new do
include SAXMachine
element :number, class: Integer
describe "integer" do
before do
class TestNumberAttribute
include SAXMachine
attribute :sub_number, class: Integer
end

class TestNumberWithAttribute
include SAXMachine
element :number, class: TestNumberAttribute
end

class TestNumber
include SAXMachine
element :number, class: Integer
end
end
it "is handled in an element" do
document = TestNumber.parse("<number>5</number>")
expect(document.number).to eq(5)
end

it "is handled in an attribute" do
document = TestNumberWithAttribute.parse("<number sub_number='5'></number>")
expect(document.number.sub_number).to eq(5)
end

document = @klass.parse("<number>5</number>")
expect(document.number).to eq(5)
end

it "handles an float class" do
@klass = Class.new do
include SAXMachine
element :number, class: Float
describe "float" do
before do
class TestNumberFloatAttribute
include SAXMachine
attribute :sub_number, class: Float
end

class TestNumberFloatWithAttribute
include SAXMachine
element :number, class: TestNumberFloatAttribute
end

class TestNumberFloat
include SAXMachine
element :number, class: Float
end
end
it "is handled in an element with '.' delimiter" do
document = TestNumberFloat.parse("<number>5.5</number>")
expect(document.number).to eq(5.5)
end

document = @klass.parse("<number>5.5</number>")
expect(document.number).to eq(5.5)
it "is handled in an element with ',' delimiter" do
document = TestNumberFloat.parse("<number>5,5</number>")
expect(document.number).to eq(5.5)
end

it "is handled in an attribute" do
document = TestNumberFloatWithAttribute.parse("<number sub_number='5.5'>5.5</number>")
expect(document.number.sub_number).to eq(5.5)
end
end

it "handles an string class" do
Expand All @@ -173,16 +214,46 @@ def title=(val)
expect(document.number).to eq("5.5")
end

it "handles a time class" do
@klass = Class.new do
include SAXMachine
element :time, class: Time
describe "time" do
before do
class TestTimeAttribute
include SAXMachine
attribute :sub_time, class: Time
value :text, class: Time
end

class TestTimeWithAttribute
include SAXMachine
element :time, class: TestTimeAttribute
end

class TestTime
include SAXMachine
element :time, class: Time
end
end
it "is handled in an element" do
document = TestTime.parse("<time>1994-02-04T06:20:00Z</time>")
expect(document.time).to eq(Time.utc(1994, 2, 4, 6, 20, 0, 0))
end

document = @klass.parse("<time>1994-02-04T06:20:00Z</time>")
expect(document.time).to eq(Time.utc(1994, 2, 4, 6, 20, 0, 0))
end
it "is handled in an attribute" do
document = TestTimeWithAttribute.parse("<time sub_time='1994-02-04T06:20:00Z'>1994-02-04T06:20:00Z</time>")
expect(document.time.sub_time).to eq(Time.utc(1994, 2, 4, 6, 20, 0, 0))
end

it "handles time element value when attribute is classified too" do
pending
document = TestTimeWithAttribute.parse("<time sub_time='1994-02-04T06:20:00Z'>1994-02-04T06:20:00Z</time>")
expect(document.time.text).to eq(Time.utc(1994, 2, 4, 6, 20, 0, 0))
end

it "handles time attribute value when element is classified too" do
document = TestTimeWithAttribute.parse("<time sub_time='1994-02-04T06:20:00Z'>1994-02-04T06:20:00Z</time>")
expect(document.time.sub_time).to eq(Time.utc(1994, 2, 4, 6, 20, 0, 0))
end

end
it "handles a Symbol class" do
@klass = Class.new do
include SAXMachine
Expand Down Expand Up @@ -375,7 +446,7 @@ def items=(val)
before do
@klass = Class.new do
include SAXMachine
element :link, value: :href, with: { foo: "bar" }
element :link, value: :href, with: {foo: "bar"}
end
end

Expand All @@ -393,8 +464,8 @@ def items=(val)
before do
@klass = Class.new do
include SAXMachine
element :link, value: :href, as: :url, with: { foo: "bar" }
element :link, value: :href, as: :second_url, with: { asdf: "jkl" }
element :link, value: :href, as: :url, with: {foo: "bar"}
element :link, value: :href, as: :second_url, with: {asdf: "jkl"}
end
end

Expand All @@ -410,7 +481,7 @@ def items=(val)
before do
@klass = Class.new do
include SAXMachine
element :link, with: { foo: "bar" }
element :link, with: {foo: "bar"}
end
end

Expand Down Expand Up @@ -439,8 +510,8 @@ def items=(val)
before do
@klass = Class.new do
include SAXMachine
element :link, as: :first, with: { foo: "bar" }
element :link, as: :second, with: { asdf: "jkl" }
element :link, as: :first, with: {foo: "bar"}
element :link, as: :second, with: {asdf: "jkl"}
end
end

Expand All @@ -459,7 +530,7 @@ def items=(val)
before do
@klass = Class.new do
include SAXMachine
element :link, with: { foo: /ar$/ }
element :link, with: {foo: /ar$/}
end
end

Expand Down Expand Up @@ -607,8 +678,8 @@ class Item

@klass = Class.new do
include SAXMachine
elements :item, as: :items, with: { type: "Bar" }, class: Bar
elements :item, as: :items, with: { type: /Foo/ }, class: Foo
elements :item, as: :items, with: {type: "Bar"}, class: Bar
elements :item, as: :items, with: {type: /Foo/}, class: Foo
end
end

Expand Down Expand Up @@ -706,7 +777,7 @@ class AtomEntry
element :title
element :name, as: :author
element "feedburner:origLink", as: :url
element :link, as: :alternate, value: :href, with: { type: "text/html", rel: "alternate" }
element :link, as: :alternate, value: :href, with: {type: "text/html", rel: "alternate"}
element :summary
element :content
element :published
Expand All @@ -715,8 +786,8 @@ class AtomEntry
class Atom
include SAXMachine
element :title
element :link, value: :href, as: :url, with: { type: "text/html" }
element :link, value: :href, as: :feed_url, with: { type: "application/atom+xml" }
element :link, value: :href, as: :url, with: {type: "text/html"}
element :link, value: :href, as: :feed_url, with: {type: "application/atom+xml"}
elements :entry, as: :entries, class: AtomEntry
end

Expand Down Expand Up @@ -752,7 +823,8 @@ class Atom
</categories>
]

class CategoryCollection; end
class CategoryCollection;
end

class Category
include SAXMachine
Expand Down Expand Up @@ -1074,9 +1146,9 @@ class ItemElement5
@errors = []
@warnings = []
@item = ItemElement5.parse(
@xml,
->(x) { @errors << x },
->(x) { @warnings << x },
@xml,
->(x) { @errors << x },
->(x) { @warnings << x },
)
end

Expand Down