require 'test/test_helper' class EmptyCart include ROXML xml_reader :id def empty? true end end class CartHolder include ROXML xml_reader :cart, :as => EmptyCart, :required => true end class TestXMLObject < ActiveSupport::TestCase # Test book with text and attribute def test_book_author_text_attribute book = BookWithAuthorTextAttribute.from_xml(fixture(:book_text_with_attribute)) assert_equal("primary",book.author.role) assert_equal("David Thomas",book.author.text) end # Test XML object containing list of other XML objects (one-to-many) # In this case, book with contibutions def test_one_to_many_with_container expected_authors = ["David Thomas","Andrew Hunt","Chad Fowler"] book = BookWithContributions.from_xml(fixture(:book_with_contributions)) assert_equal("Programming Ruby - 2nd Edition", book.title) book.contributions.each do |contributor| assert expected_authors.include?(contributor.name) end end # Test XML object containing 1-n other XML objects without container (one-to-many) # In this case, book with contibutions def test_one_to_many_without_container expected_contributors = ["David Thomas","Andrew Hunt","Chad Fowler"] book = BookWithContributors.from_xml(fixture(:book_with_contributors)) assert_equal("Programming Ruby - 2nd Edition", book.title) book.contributors.each do |contributor| assert(expected_contributors.include?(contributor.name)) end end # when building objects that contain arrays, the second object seems to # inherit data from the first # def test_one_to_many_without_container_sequence contrib = WriteableContributor.new contrib.name = "David Thomas" book_one = WriteableBookWithContributors.new book_one.isbn = "9781843549161" book_one.title = "Anathem" book_one.description = "A new title from Neal Stephenson" book_one.contributors = [contrib] # this book should be completely empty book_two = WriteableBookWithContributors.new assert_equal(nil, book_two.isbn) assert_equal(nil, book_two.title) assert_equal(nil, book_two.description) assert_equal(nil, book_two.contributors) end # Test XML object containing one other XML object (one-to-one) # In this case, book with publisher def test_one_to_one book = BookWithPublisher.from_xml(fixture(:book_with_publisher)) assert_equal("Programming Ruby - 2nd Edition", book.title) assert_equal("Pragmatic Bookshelf", book.publisher.name) end # Test XML object containing type of self (self-reference) def test_self_reference book = BookPair.from_xml(fixture(:book_pair)) assert_equal("Programming Ruby - 2nd Edition", book.title) assert_equal("Agile Web Development with Rails", book.book.title) end # Test three-level composition (one-to-many-to-many) def test_one_to_many_to_many expected_contributors = ["David Thomas","Andrew Hunt","Chad Fowler", "David Heinemeier Hansson"] expected_books = ["Programming Ruby - 2nd Edition", "Agile Web Development with Rails"] library = Library.from_xml(fixture(:library)) assert_equal("Ruby library", library.name) assert !library.books.empty? library.books.each do |book| assert expected_books.include?(book.title) book.contributions.each do |contributor| assert(expected_contributors.include?(contributor.name)) end end end def test_without_needed_from assert_equal [], UppercaseLibrary.from_xml(fixture(:library)).books assert_equal [], Library.from_xml(fixture(:library_uppercase)).books end def test_with_needed_from assert Library.from_xml(fixture(:library)).books assert UppercaseLibrary.from_xml(fixture(:library_uppercase)).books end def test_with_recursion p = PersonWithMother.from_xml(fixture(:person_with_mothers)) assert_equal 'Ben Franklin', p.name assert_equal 'Abiah Folger', p.mother.name assert_equal 'Madeup Mother', p.mother.mother.name assert_equal nil, p.mother.mother.mother end class Node include ROXML xml_reader :name, :from => 'node_name' xml_reader :nodes, :as => [Node] end class Taxonomy include ROXML xml_reader :name, :from => 'taxonomy_name' xml_reader :nodes, :as => [Node] end class Taxonomies include ROXML xml_reader :taxonomies, :as => [Taxonomy] end def test_more_recursion # quiet the error handler ROXML::XML::Error.reset_handler if ROXML::XML::Error.respond_to?(:reset_handler) taxonomies = Taxonomies.from_xml(< World Africa Algeria Algiers Ghardaïa El Oued Timimoun Annaba HERE assert_equal 1, taxonomies.taxonomies.size assert_equal 'World', taxonomies.taxonomies.first.name node = taxonomies.taxonomies.first.nodes.first assert_equal 'Africa', node.name assert_equal 'Algeria', node.nodes.first.name assert_equal ['Algiers', "Gharda\303\257a", 'El Oued', 'Timimoun', 'Annaba'], node.nodes.first.nodes.map(&:name) end def test_with_guarded_recursion p = PersonWithGuardedMother.from_xml(fixture(:person_with_guarded_mothers)) assert_equal 'Ben "Benji" Franklin', p.name assert_equal 'Abiah \'Abby\' Folger', p.mother.name assert_equal 'Madeup Mother < the third >', p.mother.mother.name assert_equal nil, p.mother.mother.mother end def test_recursive_with_default_initialization p = PersonWithMotherOrMissing.from_xml(fixture(:person_with_mothers)) assert_equal 'Unknown', p.mother.mother.mother.name assert_equal Person, p.mother.mother.mother.class end def test_defining_empty_on_object_doesnt_cause_it_to_be_seen_as_absent # absent means defaulting, failing required holder = CartHolder.from_xml(%{ 111111 }) assert_equal "111111", holder.cart.id end end