moviepilot-restful 0.2.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/CHANGES.markdown +40 -0
  2. data/LICENSE.markdown +22 -0
  3. data/README.markdown +126 -0
  4. data/Rakefile +22 -0
  5. data/TODO.markdown +10 -0
  6. data/init.rb +1 -0
  7. data/lib/restful/apimodel/attribute.rb +17 -0
  8. data/lib/restful/apimodel/collection.rb +22 -0
  9. data/lib/restful/apimodel/link.rb +21 -0
  10. data/lib/restful/apimodel/map.rb +41 -0
  11. data/lib/restful/apimodel/resource.rb +23 -0
  12. data/lib/restful/converters/active_record.rb +159 -0
  13. data/lib/restful/rails/action_controller.rb +14 -0
  14. data/lib/restful/rails/active_record/configuration.rb +219 -0
  15. data/lib/restful/rails/active_record/metadata_tools.rb +102 -0
  16. data/lib/restful/rails.rb +22 -0
  17. data/lib/restful/serializers/atom_like_serializer.rb +51 -0
  18. data/lib/restful/serializers/base.rb +58 -0
  19. data/lib/restful/serializers/hash_serializer.rb +46 -0
  20. data/lib/restful/serializers/json_serializer.rb +18 -0
  21. data/lib/restful/serializers/params_serializer.rb +46 -0
  22. data/lib/restful/serializers/xml_serializer.rb +161 -0
  23. data/lib/restful.rb +65 -0
  24. data/rails/init.rb +1 -0
  25. data/restful.gemspec +17 -0
  26. data/test/converters/active_record_converter_test.rb +147 -0
  27. data/test/converters/basic_types_converter_test.rb +99 -0
  28. data/test/fixtures/models/paginated_collection.rb +3 -0
  29. data/test/fixtures/models/person.rb +29 -0
  30. data/test/fixtures/models/pet.rb +5 -0
  31. data/test/fixtures/models/wallet.rb +5 -0
  32. data/test/fixtures/people.json.yaml +107 -0
  33. data/test/fixtures/people.xml.yaml +117 -0
  34. data/test/fixtures/pets.json.yaml +20 -0
  35. data/test/fixtures/pets.xml.yaml +31 -0
  36. data/test/rails/active_record_metadata_test.rb +23 -0
  37. data/test/rails/configuration_test.rb +47 -0
  38. data/test/rails/restful_publish_test.rb +54 -0
  39. data/test/serializers/atom_serializer_test.rb +33 -0
  40. data/test/serializers/json_serializer_test.rb +90 -0
  41. data/test/serializers/params_serializer_test.rb +76 -0
  42. data/test/serializers/xml_serializer_test.rb +51 -0
  43. data/test/test_helper.rb +154 -0
  44. metadata +97 -0
@@ -0,0 +1,117 @@
1
+ joe_bloggs:
2
+ |
3
+ <?xml version="1.0" encoding="UTF-8"?>
4
+ <person>
5
+ <restful-url type="link">http://example.com:3000/people/<%= @person.id %></restful-url>
6
+ <name>Joe Bloggs</name>
7
+ <wallet-restful-url type="link">http://example.com:3000/wallets/<%= @wallet.id %></wallet-restful-url>
8
+ </person>
9
+
10
+ no_wallet:
11
+ |
12
+ <?xml version="1.0" encoding="UTF-8"?>
13
+ <person>
14
+ <restful-url type="link">http://example.com:3000/people/<%= @person.id %></restful-url>
15
+ <location-sentence><%= @person.location_sentence %></location-sentence>
16
+ </person>
17
+
18
+ with_oldest_pet:
19
+ |
20
+ <?xml version="1.0" encoding="UTF-8"?>
21
+ <person>
22
+ <restful-url type="link">http://example.com:3000/people/<%= @person.id %></restful-url>
23
+ <oldest-pet>
24
+ <restful-url type="link">http://example.com:3000/pets/<%= @person.oldest_pet.id %></restful-url>
25
+ <name><%= @person.oldest_pet.name %></name>
26
+ <person-restful-url type="link">http://example.com:3000/people/<%= @person.id %></person-restful-url>
27
+ </oldest-pet>
28
+ </person>
29
+
30
+ with_oldest_pet_species:
31
+ |
32
+ <?xml version="1.0" encoding="UTF-8"?>
33
+ <person>
34
+ <restful-url type="link">http://example.com:3000/people/<%= @person.id %></restful-url>
35
+ <oldest-pet>
36
+ <restful-url type="link">http://example.com:3000/pets/<%= @person.oldest_pet.id %></restful-url>
37
+ <species type="integer"><%= @person.oldest_pet.species %></species>
38
+ </oldest-pet>
39
+ </person>
40
+
41
+ joe_with_birthday:
42
+ |
43
+ <?xml version="1.0" encoding="UTF-8"?>
44
+ <person>
45
+ <restful-url type="link">http://example.com:3000/people/<%= @person.id %></restful-url>
46
+ <birthday type="date"><%= @person.birthday.to_s(:db) %></birthday>
47
+ </person>
48
+
49
+ joe_with_zwiebelleder:
50
+ |
51
+ <?xml version="1.0" encoding="UTF-8"?>
52
+ <person>
53
+ <restful-url type="link">http://example.com:3000/people/<%= @person.id %></restful-url>
54
+ <wallet nil="true"></wallet>
55
+ </person>
56
+
57
+ atom_person:
58
+ |
59
+ <?xml version="1.0" encoding="UTF-8"?>
60
+ <person xml:base="http://example.com:3000">
61
+ <created-at><%= @person.created_at.xmlschema %></created-at>
62
+ <link rel="self" href="/people/<%= @person.id %>"/>
63
+ <name>Joe Bloggs</name>
64
+ <current-location>Under a tree</current-location>
65
+ <pets>
66
+ <pet>
67
+ <link rel="self" href="/pets/<%= @pet.id %>"/>
68
+ <name>mietze</name>
69
+ </pet>
70
+ </pets>
71
+ <wallet>
72
+ <link rel="self" href="/wallets/<%= @wallet.id %>"/>
73
+ <contents>an old photo, 5 euros in coins</contents>
74
+ </wallet>
75
+ </person>
76
+
77
+ verbose_no_pets:
78
+ |
79
+ <?xml version="1.0" encoding="UTF-8"?>
80
+ <person>
81
+ <restful-url type="link">http://example.com:3000/people/<%= @person.id %></restful-url>
82
+ <name>Joe Bloggs</name>
83
+ <created-at type="datetime"><%= @person.created_at.xmlschema %></created-at>
84
+ <current-location>Under a tree</current-location>
85
+ <wallet-restful-url type="link" nil="true"></wallet-restful-url>
86
+ </person>
87
+
88
+ with_pets_and_expanded_wallet:
89
+ |
90
+ <?xml version="1.0" encoding="UTF-8"?>
91
+ <person>
92
+ <restful-url type="link">http://example.com:3000/people/<%= @person.id %></restful-url>
93
+ <name>Joe Bloggs</name>
94
+ <created-at type="datetime"><%= @person.created_at.xmlschema %></created-at>
95
+ <current-location>Under a tree</current-location>
96
+ <pets type="array">
97
+ <pet>
98
+ <restful-url type="link">http://example.com:3000/pets/<%= @pet.id %></restful-url>
99
+ <name>mietze</name>
100
+ </pet>
101
+ </pets>
102
+ <wallet>
103
+ <restful-url type="link">http://example.com:3000/wallets/<%= @wallet.id %></restful-url>
104
+ <contents>an old photo, 5 euros in coins</contents>
105
+ </wallet>
106
+ </person>
107
+
108
+ hashy_person:
109
+ |
110
+ <?xml version="1.0" encoding="UTF-8"?>
111
+ <person>
112
+ <restful-url type="link">http://example.com:3000/people/<%= @person.id %></restful-url>
113
+ <pets-ages-hash>
114
+ <mietze>200</mietze>
115
+ <motze>100</motze>
116
+ </pets-ages-hash>
117
+ </person>
@@ -0,0 +1,20 @@
1
+ pets_array:
2
+ |
3
+ [
4
+ {
5
+ "restful_url": "http://example.com:3000/pets/<%= @person.pets.first.to_param %>",
6
+ "name": "mietze"
7
+ }
8
+ ]
9
+
10
+ pets_array_with_total_entries:
11
+ |
12
+ {
13
+ "total_entries": 1001,
14
+ "pets": [
15
+ {
16
+ "restful_url": "http://example.com:3000/pets/<%= @person.pets.first.to_param %>",
17
+ "name": "mietze"
18
+ }
19
+ ]
20
+ }
@@ -0,0 +1,31 @@
1
+ nameless_pet:
2
+ |
3
+ <?xml version="1.0" encoding="UTF-8"?>
4
+ <pet>
5
+ <restful-url type="link">http://example.com:3000/pets/<%= @pet.id %></restful-url>
6
+ <owner>
7
+ <restful-url type="link">http://example.com:3000/people/<%= @person.id %></restful-url>
8
+ <name>Joe Bloggs</name>
9
+ <current-location>Under a tree</current-location>
10
+ <wallet-restful-url type="link">http://example.com:3000/wallets/<%= @wallet.id %></wallet-restful-url>
11
+ </owner>
12
+ </pet>
13
+
14
+ gracie:
15
+ |
16
+ <?xml version="1.0" encoding="UTF-8"?>
17
+ <pet>
18
+ <person-restful-url type="link">http://example.com:3000/people/<%= @person.id %></person-restful-url>
19
+ <species>123</species>
20
+ <name>Gracie</name>
21
+ </pet>
22
+
23
+ pets_array:
24
+ |
25
+ <?xml version="1.0" encoding="UTF-8"?>
26
+ <pets>
27
+ <pet>
28
+ <restful-url type="link">http://example.com:3000/pets/<%= @pet.id %></restful-url>
29
+ <name>mietze</name>
30
+ </pet>
31
+ </pets>
@@ -0,0 +1,23 @@
1
+ require File.dirname(__FILE__) + '/../test_helper.rb'
2
+
3
+ context "active record metadata" do
4
+ setup do
5
+ Person.restful_publish(:name, :pets => [:name, :species])
6
+ Pet.restful_publish(:person_id, :name) # person_id gets converted to a link automagically.
7
+
8
+ @person = Person.create(:name => "Jimmy Jones", :current_location => "Under a tree")
9
+ @pet = @person.pets.create(:name => "Mietze", :species => "cat")
10
+ end
11
+
12
+ teardown do
13
+ reset_config
14
+ end
15
+
16
+ specify "should be able to convert a collection to an array of resources" do
17
+ resources = Restful::Rails.tools.convert_collection_to_resources(@person, :pets, Restful.cfg)
18
+ pet = resources.first
19
+
20
+ resources.size.should.equal 1
21
+ pet.url.should.equal @pet.to_restful.url
22
+ end
23
+ end
@@ -0,0 +1,47 @@
1
+ require File.dirname(__FILE__) + '/../test_helper.rb'
2
+
3
+ context "Configuration" do
4
+ specify "should have an empty whitelist if only restful options are passed in" do
5
+ config = Restful.cfg
6
+ config.restful_options[:expansion] = :expanded
7
+ config.whitelisted.should.empty
8
+ end
9
+
10
+ specify "should return fields without restful_options via whitelisted" do
11
+ config = Restful.cfg([:one, :two])
12
+ config.restful_options[:expansion] = :expanded
13
+ config.whitelisted.should.not.include :restful_options
14
+ end
15
+
16
+ specify "should know if it has restful_options" do
17
+ config = Restful.cfg([:one, :two])
18
+ config.restful_options[:expansion] = :expanded
19
+ config.restful_options.should.not.empty
20
+ end
21
+
22
+ specify "should be able to handle nested whitelist attributes" do
23
+ config = Restful.cfg(:one, :two => [:a, :b])
24
+ config.nested(:two).whitelisted.should.== [:a,:b]
25
+ end
26
+
27
+ specify "should know which attributes are published" do
28
+ config = Restful.cfg(:one, :two => [:a, :b])
29
+ config.published?(:two).should.== true
30
+ config.published?(:one).should.== true
31
+ end
32
+
33
+ specify "should know if it is nested" do
34
+ config = Restful.cfg(:one, :restful_options => {:nested => true})
35
+ config.nested?.should.== true
36
+ end
37
+
38
+ specify "should preserve :include when :restful_options are present" do
39
+ Person.restful_publish :pets
40
+ p = Person.create
41
+ p.pets.create
42
+
43
+ restful = p.to_restful :include => :pets, :restful_options => {}
44
+ restful.collections.size.should.== 1
45
+ end
46
+
47
+ end
@@ -0,0 +1,54 @@
1
+ require File.dirname(__FILE__) + '/../test_helper.rb'
2
+
3
+ context "restful publish" do
4
+ teardown do
5
+ reset_config
6
+ end
7
+
8
+ specify "should result in a method .published?(:attr_key) return true for published attributes" do
9
+ Pet.restful_publish(:person_id, :name) # person_id gets converted to a link automagically.
10
+
11
+ Pet.restful_config.published?(:name).should.equal true
12
+ Pet.restful_config.published?(:pets).should.equal false
13
+ Pet.restful_config.published?(:species).should.equal false
14
+ end
15
+
16
+ specify "should have restful_options as an empty hash after calling restful_publish" do
17
+ Person.restful_publish(:name, :pets => [:name, :species])
18
+ Person.restful_config.restful_options.should.==({})
19
+ end
20
+ end
21
+
22
+ context "api publishing with nesting" do
23
+
24
+ teardown do
25
+ reset_config
26
+ end
27
+
28
+ specify "should result in a method .published?(:attr_key) return true for nested attributes" do
29
+ Person.restful_publish(:name, :pets => [:name, :species])
30
+ Person.restful_config.published?(:pets).should.equal true
31
+ end
32
+
33
+ specify "should be invoke to_restful on the nested model with the specified nested attributes" do
34
+ Person.restful_publish(:name, :pets => [:name, :species])
35
+ @person = Person.create(:name => "Joe Bloggs", :current_location => "Under a tree")
36
+ @pet = @person.pets.create(:name => "Mietze", :species => "cat")
37
+
38
+ Pet.any_instance.expects(:to_restful).with { |arg| arg.whitelisted == [:name, :species] }
39
+ @person.to_restful
40
+ end
41
+
42
+ specify "should pass config over to nested objects. " do
43
+ Pet.restful_publish :name
44
+ House.restful_publish :people
45
+
46
+ house = House.create
47
+ person = house.people.create :name => "johannes"
48
+ person.pets.create :name => "puenktchen"
49
+
50
+ restful = [house].to_restful(:include => :pets)
51
+
52
+ restful.value.first.collections.first.value.first.collections.size.should.== 1
53
+ end
54
+ end
@@ -0,0 +1,33 @@
1
+ require File.dirname(__FILE__) + '/../test_helper.rb'
2
+
3
+ context "params serializer" do
4
+
5
+ setup do
6
+ Person.restful_publish(:name, :current_location, :pets, :wallet, :created_at)
7
+ Pet.restful_publish(:name)
8
+ Wallet.restful_publish(:contents)
9
+
10
+ @person = Person.create(:name => "Joe Bloggs", :current_location => "Under a tree")
11
+ @pet = @person.pets.create(:species => "cat", :age => 200, :name => "mietze")
12
+ @wallet = @person.wallet = Wallet.new(:contents => "an old photo, 5 euros in coins")
13
+ @person.save
14
+ end
15
+
16
+ teardown do
17
+ reset_config
18
+ end
19
+
20
+ specify "serialize to xml, atom style" do
21
+ xml_should_eql_fixture(@person.to_restful_atom_like, "people", :atom_person)
22
+ end
23
+
24
+ specify "deserialize from atom style xml" do
25
+ restful = @pet.to_restful
26
+ expected = restful.serialize(:atom_like)
27
+ serializer = Restful::Serializers::AtomLikeSerializer.new
28
+ resource = serializer.deserialize(expected)
29
+ actual = serializer.serialize(resource)
30
+
31
+ xml_should_eql(expected, actual)
32
+ end
33
+ end
@@ -0,0 +1,90 @@
1
+ require File.dirname(__FILE__) + '/../test_helper.rb'
2
+
3
+ context "json serializer" do
4
+
5
+ setup do
6
+ Person.restful_publish(:name, :current_location, :pets, :wallet, :created_at)
7
+ Pet.restful_publish(:name)
8
+ Wallet.restful_publish(:contents)
9
+
10
+ @person = Person.create(:name => "Joe Bloggs", :current_location => "Under a tree", :birthday => "2009-09-19")
11
+ @pet = @person.pets.create(:species => "cat", :age => 200, :name => "mietze")
12
+ @wallet = @person.wallet = Wallet.new(:contents => "an old photo, 5 euros in coins")
13
+ @person.save
14
+ end
15
+
16
+ teardown { reset_config }
17
+
18
+ specify "serialize to json" do
19
+ json_should_eql_fixture(@person.to_restful_json, "people", :bloggs)
20
+ end
21
+
22
+ specify "should be able to serialize objects with empty collections" do
23
+ @person.pets = []
24
+
25
+ assert_nothing_raised do
26
+ json_should_eql_fixture(@person.to_restful_json, "people", :bloggs_da_pet_hater)
27
+ end
28
+ end
29
+
30
+ specify "should serialize date type correctly" do
31
+ json_should_eql_fixture(@person.to_restful_json(:birthday), "people", :bloggs_with_birthday)
32
+ end
33
+
34
+ specify "should not bug out on nil values in date fields" do
35
+ person = Person.create :created_at => nil, :birthday => nil, :last_login => nil
36
+ person.created_at = nil
37
+ expected = "{\"birthday\":null,\"restful_url\":\"http://example.com:3000/people/#{person.to_param}\",\"last_login\":null,\"created_at\":null}"
38
+ assert_nothing_raised do
39
+ actual = person.to_restful_json([:created_at, :birthday, :last_login])
40
+ json_should_eql(actual, expected)
41
+ end
42
+ end
43
+
44
+ specify "should serialize hashes correctly" do
45
+ @person.pets.create(:species => "cat", :age => 100, :name => "motze")
46
+ json_should_eql_fixture(@person.to_restful_json(:pets_ages_hash), "people", :bloggs_with_pets_ages_hash)
47
+ end
48
+
49
+ specify "should render boolean values correctly" do
50
+ json_should_eql_fixture(@person.to_restful_json(:has_pets), "people", :bloggs_with_has_pets)
51
+ @person.pets = []
52
+ @person.save!
53
+ json_should_eql_fixture(@person.to_restful_json(:has_pets), "people", :bloggs_with_hasno_pets)
54
+ end
55
+
56
+ specify "should not ever use dashes as hash keys but underscores" do
57
+ assert_nothing_raised do
58
+ json_should_eql_fixture(@person.to_restful_json(:oldest_pet), "people", :bloggs_with_oldest_pet)
59
+ end
60
+ end
61
+
62
+ specify "should serialize collections correctly" do
63
+ json_should_eql_fixture(@person.pets.to_restful_json, "pets", :pets_array)
64
+ end
65
+
66
+ specify "should be able to serialize collections with total entries info" do
67
+ pets = PaginatedCollection.new(@person.pets)
68
+ pets.total_entries = 1001
69
+
70
+ json_should_eql_fixture(pets.to_restful_json, "pets", :pets_array_with_total_entries)
71
+ end
72
+
73
+ specify "should be able to serialize a map" do
74
+ Person.restful_publish(:name)
75
+ json_should_eql_fixture({ "total_hits" => 1, "a_person" => @person }.to_restful_json, "people", :hash_with_person)
76
+ end
77
+
78
+ specify "should be able to serialize a map with arrays as values" do
79
+ Person.restful_publish(:name)
80
+ json_should_eql_fixture({ "total_hits" => 2, "people" => [ @person, @person ] }.to_restful_json, "people", :hash_with_people)
81
+ end
82
+
83
+ specify 'should serialize a hash with include option correctly - the include option should be passed to the values' do
84
+ Person.restful_publish(:name)
85
+ Wallet.restful_publish(:contents)
86
+
87
+ json = {:person => @person}.to_restful_json(:include => :wallet)
88
+ json_should_eql_fixture(json, "people", :hash_with_rich_person)
89
+ end
90
+ end
@@ -0,0 +1,76 @@
1
+ require File.dirname(__FILE__) + '/../test_helper.rb'
2
+
3
+ context "params serializer" do
4
+
5
+ setup do
6
+ Person.restful_publish(:name, :current_location, :pets, :wallet, :created_at)
7
+ Pet.restful_publish(:name)
8
+ Wallet.restful_publish(:contents)
9
+
10
+ @person = Person.create(:name => "Joe Bloggs", :current_location => "Under a tree", :birthday => "1942-01-11")
11
+ @pet = @person.pets.create(:species => "cat", :age => 200, :name => "mietze")
12
+ @wallet = @person.wallet = Wallet.new(:contents => "an old photo, 5 euros in coins")
13
+ @person.save
14
+ end
15
+
16
+ teardown do
17
+ reset_config
18
+ end
19
+
20
+ specify "should be able to serialize objects empty collections" do
21
+ @person.pets = []
22
+ expected =
23
+ {
24
+ :name => "Joe Bloggs",
25
+ :current_location => "Under a tree",
26
+ :created_at => @person.created_at,
27
+ :wallet_attributes=>{:contents=>"an old photo, 5 euros in coins"}
28
+ }
29
+
30
+ assert_nothing_raised do
31
+ actual = @person.to_restful.serialize :params
32
+ actual.should.== expected
33
+ end
34
+ end
35
+
36
+ specify "should render correct date" do
37
+ actual = @person.to_restful(:birthday).serialize(:params)
38
+
39
+ expected = { :birthday => @person.birthday.to_s(:db) }
40
+
41
+ Person.create(expected).birthday.should.== @person.birthday
42
+ end
43
+
44
+ specify "serialize to params" do
45
+ actual = @person.to_restful.serialize(:params)
46
+
47
+ expected =
48
+ {
49
+ :name => "Joe Bloggs",
50
+ :current_location => "Under a tree",
51
+ :created_at => @person.created_at,
52
+ :wallet_attributes=>{:contents=>"an old photo, 5 euros in coins"},
53
+ :pets_attributes => [ {:name => "mietze"} ]
54
+ }
55
+
56
+ actual.should.== expected
57
+ end
58
+
59
+ specify "use correct key names for method that include '-' character" do
60
+ actual = @person.to_restful(:oldest_pet).serialize(:params)
61
+
62
+ expected = { :oldest_pet_attributes => {:name => "mietze"} }
63
+
64
+ actual.should.== expected
65
+ end
66
+
67
+ specify "serialize to an ar params hash" do
68
+ input = xml_fixture("pets")[:gracie]
69
+ params = Restful.from_xml(input).serialize(:params)
70
+ clone = Pet.create!(params)
71
+
72
+ clone.name.should.== "Gracie"
73
+ clone.species.should.== 123
74
+ clone.person_id.should.== @person.id
75
+ end
76
+ end
@@ -0,0 +1,51 @@
1
+ require File.dirname(__FILE__) + '/../test_helper.rb'
2
+
3
+ context "xml serializer" do
4
+ setup do
5
+ Person.restful_publish(:name, :current_location, :pets, :wallet, :created_at)
6
+ Pet.restful_publish(:name)
7
+ Wallet.restful_publish(:contents)
8
+
9
+ @person = Person.create(:name => "Joe Bloggs", :current_location => "Under a tree", :birthday => "1990-03-09")
10
+ @pet = @person.pets.create(:species => "cat", :age => 200, :name => "mietze")
11
+ @wallet = @person.wallet = Wallet.new(:contents => "an old photo, 5 euros in coins")
12
+ @person.save
13
+ end
14
+
15
+ teardown do
16
+ reset_config
17
+ end
18
+
19
+ specify "deserialize from rails style xml" do
20
+ restful = @person.to_restful
21
+ expected = restful.serialize(:xml)
22
+ serializer = Restful::Serializers::XMLSerializer.new
23
+ resource = serializer.deserialize(expected)
24
+ actual = serializer.serialize(resource)
25
+
26
+ xml_should_eql(expected, actual)
27
+ end
28
+
29
+ specify "should serialize date type correctly" do
30
+ xml_should_eql_fixture(@person.to_restful_xml(:birthday), "people", :joe_with_birthday)
31
+ end
32
+
33
+ specify "should convert a NULL inner association such as person.wallet to a link with a null value" do
34
+ @person.wallet = nil
35
+
36
+ xml_should_eql_fixture(@person.to_restful_xml(:restful_options => { :expansion => :collapsed }), "people", :verbose_no_pets)
37
+ end
38
+
39
+ specify "serialize to xml, rails style" do
40
+ xml_should_eql_fixture(@person.to_restful_xml, "people", :with_pets_and_expanded_wallet)
41
+ end
42
+
43
+ specify "should serialize hashes correctly" do
44
+ @person.pets.create(:species => "cat", :age => 100, :name => "motze")
45
+ xml_should_eql_fixture(@person.to_restful_xml(:pets_ages_hash), "people", :hashy_person)
46
+ end
47
+
48
+ specify "should serialize collections correctly" do
49
+ xml_should_eql_fixture(@person.pets.to_restful_xml, "pets", :pets_array)
50
+ end
51
+ end