require 'spec_helper' require 'test_xml/spec' describe Representable, "#xml" do class Contributor include Representable xml_accessor :role, :from => :attr xml_accessor :name end class Band include Representable xml_accessor :name end class Label def to_xml "" end end describe "generic tests" do context ".from_xml" do it "works with empty string" do album = Album.from_xml("") album.band.should == [] end end end describe ":from => @rel" do class Link include Representable xml_accessor :href, :from => "@href" xml_accessor :title, :from => "@title" end context ".from_xml" do it "creates correct accessors" do link = Link.from_xml(%{ }) link.href.should == "http://apotomo.de" link.title.should == "Home, sweet home" end end context "#to_xml" do it "serializes correctly" do link = Link.new link.href = "http://apotomo.de/" link.to_xml.to_s.should equal_xml %{} end end end describe ":as => Item" do class Albumy include Representable xml_accessor :band, :as => Band xml_accessor :label, :as => Label end context ".from_xml" do it "creates one Item instance" do album = Albumy.from_xml(%{ Bad Religion }) album.band.name.should == "Bad Religion" end end context "#to_xml" do it "doesn't escape xml from Band#to_xml" do band = Band.new band.name = "Bad Religion" album = Albumy.new album.band = band album.to_xml.to_s.should equal_xml %{ Bad Religion } end it "doesn't escape and wrap string from Label#to_xml" do album = Albumy.new album.label = Label.new album.to_xml.to_s.should equal_xml %{ } end end end describe "collections" do context ":as => [Item]" do class Book include Representable xml_accessor :contributors, :as => [Contributor], :tag => :contributor end it ".from_xml pushes collection items to array" do book = Book.from_xml(%{ David Thomas Andrew Hunt Chad Fowler }) book.contributors.map(&:name).sort.should == ["David Thomas","Andrew Hunt","Chad Fowler"].sort end it "collections can be empty" do book = Book.from_xml(%{ }) book.contributors.should == [] end it "responds to #to_xml" do book = Book.new david = Contributor.new david.name= "David Thomas" chad = Contributor.new chad.name= "Chad Fowler" book.contributors = [david, chad] book.to_xml.to_s.should equal_xml %{ David Thomas Chad Fowler } end end context ":as => []" do class Album include Representable xml_accessor :songs, :as => [], :tag => :song end it "collects untyped items" do album = Album.from_xml(%{ Two Kevins Wright and Rong Laundry Basket }) album.songs.sort.should == ["Laundry Basket", "Two Kevins", "Wright and Rong"].sort end end end def parse_xml(xml); Nokogiri::XML::Node.from(xml); end describe "Reference" do context "ObjectRef with []" do subject do Representable::XMLObjectRef.new(Representable::Definition.new(:songs, :as => [Album])) end it "responds to #default" do subject.send(:default).should == [] end end context "TextRef#value_in" do subject do Representable::XMLTextRef.new(Representable::Definition.new(:song)) end it "returns found value" do subject.value_in(parse_xml("Unkoil")).should == "Unkoil" end end end describe "Definition" do context "generic API" do subject do Representable::Definition.new(:songs) end it "responds to #typed?" do subject.typed? == false Representable::Definition.new(:songs, :as => Album).typed? == true Representable::Definition.new(:songs, :as => [Album]).typed? == true end context "#apply" do subject do Representable::Definition.new(:song) end it "works with a single item" do subject.apply(1) { |v| v+1 }.should == 2 end it "works with collection" do d = Representable::Definition.new(:song, :as => []) d.apply([1,2,3]) { |v| v+1 }.should == [2,3,4] end it "skips with collection and nil" do d = Representable::Definition.new(:song, :as => []) d.apply(nil) { |v| v+1 }.should == nil end end end context ":as => []" do subject do Representable::Definition.new(:songs, :as => [], :tag => :song) end it "responds to #accessor" do subject.accessor.should == "songs" end it "responds to #array?" do subject.array?.should be_true end it "responds to #name" do subject.accessor.should == "songs" end it "responds to #instance_variable_name" do subject.instance_variable_name.should == :"@songs" end it "responds to #setter" do subject.setter.should == :"songs=" end it "responds to #sought_type" do subject.sought_type.should == :text end end context ":as => [Item]" do subject do class Song; end Representable::Definition.new(:songs, :as => [Song]) end it "responds to #sought_type" do subject.sought_type.should == Song end end context ":as => Item" do subject do class Song; end Representable::Definition.new(:songs, :as => Song) end it "responds to #sought_type" do subject.sought_type.should == Song end end end end