representable 0.0.1.alpha1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +7 -0
- data/.gitmodules +3 -0
- data/.rspec +1 -0
- data/Gemfile +3 -0
- data/History.txt +354 -0
- data/LICENSE +20 -0
- data/README.rdoc +186 -0
- data/Rakefile +10 -0
- data/TODO +37 -0
- data/VERSION +1 -0
- data/examples/amazon.rb +35 -0
- data/examples/current_weather.rb +27 -0
- data/examples/dashed_elements.rb +20 -0
- data/examples/library.rb +40 -0
- data/examples/posts.rb +27 -0
- data/examples/rails.rb +70 -0
- data/examples/twitter.rb +37 -0
- data/examples/xml/active_record.xml +70 -0
- data/examples/xml/amazon.xml +133 -0
- data/examples/xml/current_weather.xml +89 -0
- data/examples/xml/dashed_elements.xml +52 -0
- data/examples/xml/posts.xml +23 -0
- data/examples/xml/twitter.xml +422 -0
- data/lib/representable.rb +257 -0
- data/lib/representable/definition.rb +109 -0
- data/lib/representable/nokogiri_extensions.rb +19 -0
- data/lib/representable/references.rb +153 -0
- data/lib/representable/version.rb +3 -0
- data/lib/representable/xml.rb +79 -0
- data/representable.gemspec +29 -0
- data/spec/definition_spec.rb +495 -0
- data/spec/examples/active_record_spec.rb +41 -0
- data/spec/examples/amazon_spec.rb +54 -0
- data/spec/examples/current_weather_spec.rb +37 -0
- data/spec/examples/dashed_elements_spec.rb +20 -0
- data/spec/examples/library_spec.rb +46 -0
- data/spec/examples/post_spec.rb +24 -0
- data/spec/examples/twitter_spec.rb +32 -0
- data/spec/roxml_integration_test.rb +289 -0
- data/spec/roxml_spec.rb +372 -0
- data/spec/shared_specs.rb +15 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/support/libxml.rb +3 -0
- data/spec/support/nokogiri.rb +3 -0
- data/spec/xml/array_spec.rb +36 -0
- data/spec/xml/attributes_spec.rb +71 -0
- data/spec/xml/encoding_spec.rb +53 -0
- data/spec/xml/namespace_spec.rb +270 -0
- data/spec/xml/namespaces_spec.rb +67 -0
- data/spec/xml/object_spec.rb +82 -0
- data/spec/xml/parser_spec.rb +21 -0
- data/spec/xml/text_spec.rb +71 -0
- data/test/fixtures/book_malformed.xml +5 -0
- data/test/fixtures/book_pair.xml +8 -0
- data/test/fixtures/book_text_with_attribute.xml +5 -0
- data/test/fixtures/book_valid.xml +5 -0
- data/test/fixtures/book_with_authors.xml +7 -0
- data/test/fixtures/book_with_contributions.xml +9 -0
- data/test/fixtures/book_with_contributors.xml +7 -0
- data/test/fixtures/book_with_contributors_attrs.xml +7 -0
- data/test/fixtures/book_with_default_namespace.xml +9 -0
- data/test/fixtures/book_with_depth.xml +6 -0
- data/test/fixtures/book_with_octal_pages.xml +4 -0
- data/test/fixtures/book_with_publisher.xml +7 -0
- data/test/fixtures/book_with_wrapped_attr.xml +3 -0
- data/test/fixtures/dictionary_of_attr_name_clashes.xml +8 -0
- data/test/fixtures/dictionary_of_attrs.xml +6 -0
- data/test/fixtures/dictionary_of_guarded_names.xml +6 -0
- data/test/fixtures/dictionary_of_mixeds.xml +4 -0
- data/test/fixtures/dictionary_of_name_clashes.xml +10 -0
- data/test/fixtures/dictionary_of_names.xml +4 -0
- data/test/fixtures/dictionary_of_texts.xml +10 -0
- data/test/fixtures/library.xml +30 -0
- data/test/fixtures/library_uppercase.xml +30 -0
- data/test/fixtures/muffins.xml +3 -0
- data/test/fixtures/nameless_ageless_youth.xml +2 -0
- data/test/fixtures/node_with_attr_name_conflicts.xml +1 -0
- data/test/fixtures/node_with_name_conflicts.xml +4 -0
- data/test/fixtures/numerology.xml +4 -0
- data/test/fixtures/person.xml +1 -0
- data/test/fixtures/person_with_guarded_mothers.xml +13 -0
- data/test/fixtures/person_with_mothers.xml +10 -0
- data/test/mocks/dictionaries.rb +57 -0
- data/test/mocks/mocks.rb +279 -0
- data/test/roxml_test.rb +58 -0
- data/test/support/fixtures.rb +11 -0
- data/test/test_helper.rb +6 -0
- data/test/unit/definition_test.rb +235 -0
- data/test/unit/deprecations_test.rb +24 -0
- data/test/unit/to_xml_test.rb +81 -0
- data/test/unit/xml_attribute_test.rb +39 -0
- data/test/unit/xml_block_test.rb +81 -0
- data/test/unit/xml_bool_test.rb +122 -0
- data/test/unit/xml_convention_test.rb +150 -0
- data/test/unit/xml_hash_test.rb +115 -0
- data/test/unit/xml_initialize_test.rb +49 -0
- data/test/unit/xml_name_test.rb +141 -0
- data/test/unit/xml_namespace_test.rb +31 -0
- data/test/unit/xml_object_test.rb +206 -0
- data/test/unit/xml_required_test.rb +94 -0
- data/test/unit/xml_text_test.rb +71 -0
- data/website/index.html +98 -0
- metadata +248 -0
@@ -0,0 +1,49 @@
|
|
1
|
+
require_relative './../test_helper'
|
2
|
+
|
3
|
+
class InheritedBookWithDepth < Book
|
4
|
+
xml_reader :depth, :as => Measurement
|
5
|
+
end
|
6
|
+
|
7
|
+
class BookWithXmlInitialize < BookWithDepth
|
8
|
+
attr_reader :created_at, :creator
|
9
|
+
|
10
|
+
def initialize(created_at, creator = "Unknown")
|
11
|
+
@created_at = created_at
|
12
|
+
@creator = creator
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class TestXMLInitialize < ActiveSupport::TestCase
|
17
|
+
def test_initialize_is_run
|
18
|
+
m = Measurement.from_xml('<measurement units="hundredths-meters">1130</measurement>')
|
19
|
+
assert_equal 11.3, m.value
|
20
|
+
assert_equal 'meters', m.units
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_initialize_is_run_for_nested_type
|
24
|
+
b = BookWithDepth.from_xml(fixture(:book_with_depth))
|
25
|
+
assert_equal Measurement.new(11.3, 'meters'), b.depth
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_initialize_is_run_for_nested_type_with_inheritance
|
29
|
+
b = InheritedBookWithDepth.from_xml(fixture(:book_with_depth))
|
30
|
+
assert_equal Measurement.new(11.3, 'meters'), b.depth
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_initialize_fails_on_missing_required_arg
|
34
|
+
assert_raise ArgumentError do
|
35
|
+
BookWithXmlInitialize.from_xml(fixture(:book_with_depth))
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_initialize_with_extra_args
|
40
|
+
now = Time.now
|
41
|
+
b = BookWithXmlInitialize.from_xml(fixture(:book_with_depth), now)
|
42
|
+
assert_equal now, b.created_at
|
43
|
+
assert_equal "Unknown", b.creator
|
44
|
+
|
45
|
+
b = BookWithXmlInitialize.from_xml(fixture(:book_with_depth), Time.now, "Joe Librarian")
|
46
|
+
assert now < b.created_at
|
47
|
+
assert_equal "Joe Librarian", b.creator
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require_relative './../test_helper'
|
2
|
+
|
3
|
+
# Parent | Child
|
4
|
+
# :from | no :from |
|
5
|
+
# -------------------|--------------
|
6
|
+
# :from | xml_name | xml_name-d
|
7
|
+
# value | value |
|
8
|
+
# -------------------|--------------
|
9
|
+
# :from | parent's |
|
10
|
+
# value | accessor | un-xml_name-d
|
11
|
+
# | name |
|
12
|
+
|
13
|
+
class Child
|
14
|
+
include ROXML
|
15
|
+
end
|
16
|
+
|
17
|
+
class NamedChild
|
18
|
+
include ROXML
|
19
|
+
|
20
|
+
xml_name :xml_name_of_child
|
21
|
+
end
|
22
|
+
|
23
|
+
class ParentOfNamedChild
|
24
|
+
include ROXML
|
25
|
+
|
26
|
+
xml_name :parent
|
27
|
+
xml_accessor :child_accessor_name, :as => NamedChild
|
28
|
+
end
|
29
|
+
|
30
|
+
class ParentOfNamedChildWithFrom
|
31
|
+
include ROXML
|
32
|
+
|
33
|
+
xml_name :parent
|
34
|
+
xml_accessor :child_accessor_name, :as => NamedChild, :from => 'child_from_name'
|
35
|
+
end
|
36
|
+
|
37
|
+
class ParentOfUnnamedChild
|
38
|
+
include ROXML
|
39
|
+
|
40
|
+
xml_name :parent
|
41
|
+
xml_accessor :child_accessor_name, :as => Child
|
42
|
+
end
|
43
|
+
|
44
|
+
class ParentOfUnnamedChildWithFrom
|
45
|
+
include ROXML
|
46
|
+
|
47
|
+
xml_name :parent
|
48
|
+
xml_accessor :child_accessor_name,:as => Child, :from => 'child_from_name'
|
49
|
+
end
|
50
|
+
|
51
|
+
class TestXMLName < ActiveSupport::TestCase
|
52
|
+
def test_from_always_dominates_attribute_name_xml_name_or_not
|
53
|
+
parent = ParentOfNamedChildWithFrom.new
|
54
|
+
parent.child_accessor_name = Child.new
|
55
|
+
|
56
|
+
assert_equal "<parent><child_from_name/></parent>", parent.to_xml.to_s.gsub(/[\n ]/, '')
|
57
|
+
|
58
|
+
parent = ParentOfUnnamedChildWithFrom.new
|
59
|
+
parent.child_accessor_name = Child.new
|
60
|
+
|
61
|
+
assert_equal "<parent><child_from_name/></parent>", parent.to_xml.to_s.gsub(/[\n ]/, '')
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_attribute_name_comes_from_the_xml_name_value_if_present
|
65
|
+
parent = ParentOfNamedChild.new
|
66
|
+
parent.child_accessor_name = Child.new
|
67
|
+
|
68
|
+
assert_equal "<parent><xml_name_of_child/></parent>", parent.to_xml.to_s.gsub(/[\n ]/, '')
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_attribute_name_comes_from_parent_accessor_by_default
|
72
|
+
parent = ParentOfUnnamedChild.new
|
73
|
+
parent.child_accessor_name = Child.new
|
74
|
+
|
75
|
+
assert_equal "<parent><child_accessor_name/></parent>", parent.to_xml.to_s.gsub(/[\n ]/, '')
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_it_should_be_inherited
|
79
|
+
class_with_inherited_name = Class.new(ParentOfNamedChild)
|
80
|
+
assert_equal :parent, class_with_inherited_name.tag_name
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_it_should_be_inherited_over_multiple_levels
|
84
|
+
class_with_inherited_name = Class.new(Class.new(ParentOfNamedChild))
|
85
|
+
assert_equal :parent, class_with_inherited_name.tag_name
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_named_books_picked_up
|
89
|
+
named = Library.from_xml(fixture(:library))
|
90
|
+
assert named.books
|
91
|
+
assert_equal :book, named.books.first.class.tag_name
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_nameless_books_missing
|
95
|
+
nameless = LibraryWithBooksOfUnderivableName.from_xml(fixture(:library))
|
96
|
+
assert nameless.novels.empty?
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_tag_name
|
100
|
+
assert_equal :dictionary, DictionaryOfTexts.tag_name
|
101
|
+
|
102
|
+
dict = DictionaryOfTexts.from_xml(fixture(:dictionary_of_texts))
|
103
|
+
|
104
|
+
assert_equal :dictionary, dict.class.tag_name
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_roxml_attrs
|
108
|
+
assert_equal 'definition', DictionaryOfTexts.roxml_attrs.first.name
|
109
|
+
assert_equal 'word', DictionaryOfTexts.roxml_attrs.first.hash.key.name
|
110
|
+
assert_equal 'meaning', DictionaryOfTexts.roxml_attrs.first.hash.value.name
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_xml_name_should_not_be_conventionalized_if_explicitly_set
|
114
|
+
reference = ROXML::XMLTextRef.new(ROXML::Definition.new(:name, :from => 'georss:name'), WrapModule::InstanceStandin.new)
|
115
|
+
assert_equal "georss:name", reference.name
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_xml_name_not_screwed_up_by_xml_convention
|
119
|
+
reference = ROXML::XMLTextRef.new(ROXML::Definition.new(:name, :in => './'), WrapModule::InstanceStandin.new)
|
120
|
+
assert_equal "name value", reference.value_in(ROXML::XML.parse_string(%(
|
121
|
+
<Wrapper>
|
122
|
+
<MoreStuff>
|
123
|
+
<DeepWrapper>
|
124
|
+
<Name>name value</Name>
|
125
|
+
</DeepWrapper>
|
126
|
+
</MoreStuff>
|
127
|
+
</Wrapper>
|
128
|
+
)).root)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
module WrapModule
|
133
|
+
class BaseClass
|
134
|
+
include ROXML
|
135
|
+
xml_convention :camelcase
|
136
|
+
end
|
137
|
+
|
138
|
+
class InstanceStandin < BaseClass
|
139
|
+
xml_reader :name, :in => './'
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require_relative './../test_helper'
|
2
|
+
|
3
|
+
class TestDefaultXMLNamespaces < ActiveSupport::TestCase
|
4
|
+
def setup
|
5
|
+
@book = BookWithContributions.from_xml(fixture(:book_with_default_namespace))
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_default_namespace_doesnt_interfere_with_normal_operation
|
9
|
+
assert_equal("Programming Ruby - 2nd Edition", @book.title)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_default_namespace_is_applied_to_in_element
|
13
|
+
expected_authors = ["David Thomas","Andrew Hunt","Chad Fowler"]
|
14
|
+
assert !@book.contributions.empty?
|
15
|
+
@book.contributions.each do |contributor|
|
16
|
+
assert expected_authors.include?(contributor.name)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_default_namespace_on_root_node_should_be_found
|
21
|
+
require 'libxml'
|
22
|
+
xml = LibXML::XML::Parser.string(
|
23
|
+
'<container xmlns="http://defaultnamespace.org"><node>Yeah, content</node><node><subnode>Another</subnode></node></container>').parse
|
24
|
+
|
25
|
+
assert_equal nil, xml.find_first('node')
|
26
|
+
assert_equal "Yeah, content", xml.find_first('ns:node', 'ns:http://defaultnamespace.org').content
|
27
|
+
assert_equal nil, xml.find_first('ns:node/subnode', 'ns:http://defaultnamespace.org')
|
28
|
+
assert_equal "Another", xml.find_first('ns:node/ns:subnode', 'ns:http://defaultnamespace.org').content
|
29
|
+
rescue LoadError
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,206 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require_relative './../test_helper'
|
3
|
+
|
4
|
+
class EmptyCart
|
5
|
+
include ROXML
|
6
|
+
|
7
|
+
xml_reader :id
|
8
|
+
|
9
|
+
def empty?
|
10
|
+
true
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class CartHolder
|
15
|
+
include ROXML
|
16
|
+
|
17
|
+
xml_reader :cart, :as => EmptyCart, :required => true
|
18
|
+
end
|
19
|
+
|
20
|
+
class TestXMLObject < ActiveSupport::TestCase
|
21
|
+
# Test book with text and attribute
|
22
|
+
def test_book_author_text_attribute
|
23
|
+
book = BookWithAuthorTextAttribute.from_xml(fixture(:book_text_with_attribute))
|
24
|
+
assert_equal("primary",book.author.role)
|
25
|
+
assert_equal("David Thomas",book.author.text)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Test XML object containing list of other XML objects (one-to-many)
|
29
|
+
# In this case, book with contibutions
|
30
|
+
def test_one_to_many_with_container
|
31
|
+
expected_authors = ["David Thomas","Andrew Hunt","Chad Fowler"]
|
32
|
+
book = BookWithContributions.from_xml(fixture(:book_with_contributions))
|
33
|
+
assert_equal("Programming Ruby - 2nd Edition", book.title)
|
34
|
+
book.contributions.each do |contributor|
|
35
|
+
assert expected_authors.include?(contributor.name)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Test XML object containing 1-n other XML objects without container (one-to-many)
|
40
|
+
# In this case, book with contibutions
|
41
|
+
def test_one_to_many_without_container
|
42
|
+
expected_contributors = ["David Thomas","Andrew Hunt","Chad Fowler"]
|
43
|
+
book = BookWithContributors.from_xml(fixture(:book_with_contributors))
|
44
|
+
assert_equal("Programming Ruby - 2nd Edition", book.title)
|
45
|
+
book.contributors.each do |contributor|
|
46
|
+
assert(expected_contributors.include?(contributor.name))
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# when building objects that contain arrays, the second object seems to
|
51
|
+
# inherit data from the first
|
52
|
+
#
|
53
|
+
def test_one_to_many_without_container_sequence
|
54
|
+
contrib = WriteableContributor.new
|
55
|
+
contrib.name = "David Thomas"
|
56
|
+
|
57
|
+
book_one = WriteableBookWithContributors.new
|
58
|
+
book_one.isbn = "9781843549161"
|
59
|
+
book_one.title = "Anathem"
|
60
|
+
book_one.description = "A new title from Neal Stephenson"
|
61
|
+
book_one.contributors = [contrib]
|
62
|
+
|
63
|
+
# this book should be completely empty
|
64
|
+
book_two = WriteableBookWithContributors.new
|
65
|
+
|
66
|
+
assert_equal(nil, book_two.isbn)
|
67
|
+
assert_equal(nil, book_two.title)
|
68
|
+
assert_equal(nil, book_two.description)
|
69
|
+
assert_equal(nil, book_two.contributors)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Test XML object containing one other XML object (one-to-one)
|
73
|
+
# In this case, book with publisher
|
74
|
+
def test_one_to_one
|
75
|
+
book = BookWithPublisher.from_xml(fixture(:book_with_publisher))
|
76
|
+
assert_equal("Programming Ruby - 2nd Edition", book.title)
|
77
|
+
assert_equal("Pragmatic Bookshelf", book.publisher.name)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Test XML object containing type of self (self-reference)
|
81
|
+
def test_self_reference
|
82
|
+
book = BookPair.from_xml(fixture(:book_pair))
|
83
|
+
assert_equal("Programming Ruby - 2nd Edition", book.title)
|
84
|
+
assert_equal("Agile Web Development with Rails", book.book.title)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Test three-level composition (one-to-many-to-many)
|
88
|
+
def test_one_to_many_to_many
|
89
|
+
expected_contributors = ["David Thomas","Andrew Hunt","Chad Fowler", "David Heinemeier Hansson"]
|
90
|
+
expected_books = ["Programming Ruby - 2nd Edition", "Agile Web Development with Rails"]
|
91
|
+
library = Library.from_xml(fixture(:library))
|
92
|
+
assert_equal("Ruby library", library.name)
|
93
|
+
assert !library.books.empty?
|
94
|
+
library.books.each do |book|
|
95
|
+
assert expected_books.include?(book.title)
|
96
|
+
book.contributions.each do |contributor|
|
97
|
+
assert(expected_contributors.include?(contributor.name))
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_without_needed_from
|
103
|
+
assert_equal [], UppercaseLibrary.from_xml(fixture(:library)).books
|
104
|
+
assert_equal [], Library.from_xml(fixture(:library_uppercase)).books
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_with_needed_from
|
108
|
+
assert Library.from_xml(fixture(:library)).books
|
109
|
+
assert UppercaseLibrary.from_xml(fixture(:library_uppercase)).books
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_with_recursion
|
113
|
+
p = PersonWithMother.from_xml(fixture(:person_with_mothers))
|
114
|
+
assert_equal 'Ben Franklin', p.name
|
115
|
+
assert_equal 'Abiah Folger', p.mother.name
|
116
|
+
assert_equal 'Madeup Mother', p.mother.mother.name
|
117
|
+
assert_equal nil, p.mother.mother.mother
|
118
|
+
end
|
119
|
+
|
120
|
+
class Node
|
121
|
+
include ROXML
|
122
|
+
|
123
|
+
xml_reader :name, :from => 'node_name'
|
124
|
+
xml_reader :nodes, :as => [Node]
|
125
|
+
end
|
126
|
+
|
127
|
+
class Taxonomy
|
128
|
+
include ROXML
|
129
|
+
|
130
|
+
xml_reader :name, :from => 'taxonomy_name'
|
131
|
+
xml_reader :nodes, :as => [Node]
|
132
|
+
end
|
133
|
+
|
134
|
+
class Taxonomies
|
135
|
+
include ROXML
|
136
|
+
xml_reader :taxonomies, :as => [Taxonomy]
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_more_recursion
|
140
|
+
taxonomies = Taxonomies.from_xml(<<HERE)
|
141
|
+
<?xml version="1.0" encoding="UTF-8" ?>
|
142
|
+
<!DOCTYPE taxonomies SYSTEM "taxonomy.dtd">
|
143
|
+
<taxonomies>
|
144
|
+
<taxonomy>
|
145
|
+
<taxonomy_name>World</taxonomy_name>
|
146
|
+
<node node_id="2" content_object_id="82534" object_type_id="2">
|
147
|
+
<node_name lang_iso="eng">Africa</node_name>
|
148
|
+
<node node_id="331" content_object_id="11" object_type_id="4">
|
149
|
+
<node_name lang_iso="eng">Algeria</node_name>
|
150
|
+
<node node_id="7271" content_object_id="117629" object_type_id="8">
|
151
|
+
<node_name lang_iso="eng">Algiers</node_name>
|
152
|
+
</node>
|
153
|
+
<node node_id="7272" content_object_id="117630" object_type_id="8">
|
154
|
+
<node_name lang_iso="eng">Ghardaïa</node_name>
|
155
|
+
</node>
|
156
|
+
<node node_id="7871" content_object_id="1000713999" object_type_id="8">
|
157
|
+
<node_name lang_iso="eng">El Oued</node_name>
|
158
|
+
</node>
|
159
|
+
<node node_id="7872" content_object_id="1000714008" object_type_id="8">
|
160
|
+
<node_name lang_iso="eng">Timimoun</node_name>
|
161
|
+
</node>
|
162
|
+
<node node_id="8903" content_object_id="1000565565" object_type_id="8">
|
163
|
+
<node_name lang_iso="eng">Annaba</node_name>
|
164
|
+
</node>
|
165
|
+
</node>
|
166
|
+
</node>
|
167
|
+
</taxonomy>
|
168
|
+
</taxonomies>
|
169
|
+
HERE
|
170
|
+
assert_equal 1, taxonomies.taxonomies.size
|
171
|
+
assert_equal 'World', taxonomies.taxonomies.first.name
|
172
|
+
node = taxonomies.taxonomies.first.nodes.first
|
173
|
+
assert_equal 'Africa', node.name
|
174
|
+
assert_equal 'Algeria', node.nodes.first.name
|
175
|
+
assert_equal ['Algiers', "Ghardaïa", 'El Oued', 'Timimoun', 'Annaba'],
|
176
|
+
node.nodes.first.nodes.map(&:name)
|
177
|
+
end
|
178
|
+
|
179
|
+
def test_with_guarded_recursion
|
180
|
+
p = PersonWithGuardedMother.from_xml(fixture(:person_with_guarded_mothers))
|
181
|
+
assert_equal 'Ben "Benji" Franklin', p.name
|
182
|
+
assert_equal 'Abiah \'Abby\' Folger', p.mother.name
|
183
|
+
assert_equal 'Madeup Mother < the third >', p.mother.mother.name
|
184
|
+
assert_equal nil, p.mother.mother.mother
|
185
|
+
end
|
186
|
+
|
187
|
+
def test_recursive_with_default_initialization
|
188
|
+
p = PersonWithMotherOrMissing.from_xml(fixture(:person_with_mothers))
|
189
|
+
assert_equal 'Unknown', p.mother.mother.mother.name
|
190
|
+
assert_equal Person, p.mother.mother.mother.class
|
191
|
+
end
|
192
|
+
|
193
|
+
def test_defining_empty_on_object_doesnt_cause_it_to_be_seen_as_absent
|
194
|
+
# absent means defaulting, failing required
|
195
|
+
|
196
|
+
holder = CartHolder.from_xml(%{
|
197
|
+
<cartholder>
|
198
|
+
<cart>
|
199
|
+
<id>111111</id>
|
200
|
+
</cart>
|
201
|
+
</cartholder>
|
202
|
+
})
|
203
|
+
|
204
|
+
assert_equal "111111", holder.cart.id
|
205
|
+
end
|
206
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require_relative './../test_helper'
|
2
|
+
|
3
|
+
class TestXMLRequired < ActiveSupport::TestCase
|
4
|
+
def setup
|
5
|
+
@full_book = <<BOOK
|
6
|
+
<book ISBN="1234">
|
7
|
+
<title>This & that</title>
|
8
|
+
<contributor_array>
|
9
|
+
<contributor role="Author">
|
10
|
+
<name>Johnny</name>
|
11
|
+
</contributor>
|
12
|
+
</contributor_array>
|
13
|
+
<contributor_hash>
|
14
|
+
<contributor role="Author" name="Johnny" />
|
15
|
+
</contributor_hash>
|
16
|
+
</book>
|
17
|
+
BOOK
|
18
|
+
|
19
|
+
@book_missing_attr = <<BOOK
|
20
|
+
<book>
|
21
|
+
<title>This & that</title>
|
22
|
+
<contributor_array>
|
23
|
+
<contributor role="Author">
|
24
|
+
<name>Johnny</name>
|
25
|
+
</contributor>
|
26
|
+
</contributor_array>
|
27
|
+
<contributor_hash>
|
28
|
+
<contributor role="Author" name="Johnny" />
|
29
|
+
</contributor_hash>
|
30
|
+
</book>
|
31
|
+
BOOK
|
32
|
+
|
33
|
+
@book_missing_text = <<BOOK
|
34
|
+
<book ISBN="1234">
|
35
|
+
<contributor_array>
|
36
|
+
<contributor role="Author">
|
37
|
+
<name>Johnny</name>
|
38
|
+
</contributor>
|
39
|
+
</contributor_array>
|
40
|
+
<contributor_hash>
|
41
|
+
<contributor role="Author" name="Johnny" />
|
42
|
+
</contributor_hash>
|
43
|
+
</book>
|
44
|
+
BOOK
|
45
|
+
|
46
|
+
@book_missing_array = <<BOOK
|
47
|
+
<book ISBN="1234">
|
48
|
+
<title>This & that</title>
|
49
|
+
<contributor_hash>
|
50
|
+
<contributor role="Author" name="Johnny" />
|
51
|
+
</contributor_hash>
|
52
|
+
</book>
|
53
|
+
BOOK
|
54
|
+
|
55
|
+
@book_missing_hash = <<BOOK
|
56
|
+
<book ISBN="1234">
|
57
|
+
<title>This & that</title>
|
58
|
+
<contributor_array>
|
59
|
+
<contributor role="Author">
|
60
|
+
<name>Johnny</name>
|
61
|
+
</contributor>
|
62
|
+
</contributor_array>
|
63
|
+
</book>
|
64
|
+
BOOK
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_required_passes_on_prescence
|
68
|
+
BookWithRequired.from_xml(@full_book)
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_required_throws_on_attr_absence
|
72
|
+
assert_raise ROXML::RequiredElementMissing do
|
73
|
+
BookWithRequired.from_xml(@book_missing_attr)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_required_throws_on_text_absence
|
78
|
+
assert_raise ROXML::RequiredElementMissing do
|
79
|
+
BookWithRequired.from_xml(@book_missing_text)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_required_throws_on_array_absence
|
84
|
+
assert_raise ROXML::RequiredElementMissing do
|
85
|
+
BookWithRequired.from_xml(@book_missing_array)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_required_throws_on_hash_absence
|
90
|
+
assert_raise ROXML::RequiredElementMissing do
|
91
|
+
BookWithRequired.from_xml(@book_missing_hash)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|