purzelrakete-restful 0.2.1 → 0.2.2

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/README.markdown CHANGED
@@ -31,8 +31,7 @@ Some example configurations:
31
31
  restful_publish :name, :pets, :restful_options => { :expansion => :expanded } # default on level 1-2: expanded. default above: collapsed.
32
32
  restful_publish :name, :pets, :wallet => :contents, :restful_options => { :expansion => :expanded } # combined options and expansion rules
33
33
  restful_publish :name, :pets, :restful_options => { :collapsed => :pets } # collapsed pets, even though they are on the second level.
34
- restful_publish :name, :pets, :restful_options => { :expanded => [:pets, :wallet] }
35
- restful_publish :name, :pets, :restful_options => { :pets_page => 1, :pets_per_page => 100, :collapsed => :pets }
34
+ restful_publish :name, :pets, :restful_options => { :force_expanded => [:pets, :wallet] }
36
35
 
37
36
  # Pet
38
37
  restful_publish :name, :person # expands person per default because it is on the second level. Does not expand person.pets.first.person, since this is higher than second level.
@@ -42,7 +41,9 @@ Rails-like
42
41
 
43
42
  This format sticks to xml_simple, adding links as `<association-name-restful-url>` nodes of type "link".
44
43
 
45
- `Person.last.to_restful.serialize(:xml)` results in something like...
44
+
45
+ `Person.last.to_restful.serialize(:xml)` OR
46
+ `Person.last.to_restful_xml` results in something like...
46
47
 
47
48
  <?xml version="1.0" encoding="UTF-8"?>
48
49
  <person>
@@ -66,7 +67,8 @@ This format sticks to xml_simple, adding links as `<association-name-restful-url
66
67
  Atom-like
67
68
  =========
68
69
 
69
- `Person.last.to_restful.serialize(:atom_like)` results in something like...
70
+ `Person.last.to_restful.serialize(:atom_like)` OR
71
+ `Person.last.to_restful_atom_like` results in something like...
70
72
 
71
73
  <?xml version="1.0" encoding="UTF-8"?>
72
74
  <person xml:base="http://example.com:3000">
@@ -89,13 +91,19 @@ Atom-like
89
91
  Params-like
90
92
  ===========
91
93
 
92
- `Person.last.to_restful.serialize(:params)` results in something like...
94
+ `Person.last.to_restful.serialize(:params)` OR
95
+ `Person.last.to_restful_params` results in something like...
93
96
 
94
97
  {:sex_attributes => {:sex=>"male"},
95
98
  :current_location=>"Under a tree",
96
99
  :name=>"Joe Bloggs",
97
100
  :pets_attributes=> [ {:person_id=>1, :name=>nil} ]
98
101
  }
102
+
103
+ Other Serializers
104
+ =================
105
+
106
+ Hash. Spits out a plain ole hash, no nested attributes or such like. Useful for further conversions.
99
107
 
100
108
  Deserializing
101
109
  =============
@@ -105,4 +113,4 @@ Use `Restful.from_atom_like(xml).serialize(:hash)` to convert from an atom-like
105
113
  Nested Attributes
106
114
  =================
107
115
  Serializing uses Rails 2.3 notation of nested attributes. For deserializing you will need Rails 2.3 for having nested attributes support and the respective model must have the
108
- `accepts_nested_attributes_for :<table name>` set accordingly
116
+ `accepts_nested_attributes_for :<table name>` set accordingly.
data/TODO.markdown CHANGED
@@ -3,5 +3,6 @@ Refactor this shice. Seriously, this has devolved into some nasty-ass code.
3
3
  * the metamodel is kind of weird. make a better metamodel - how about just using activemodel?
4
4
  * remove requirement to call apiable in model classes; replace with restful_publish with no args (or with args.)
5
5
  * move configuration object out of rails folder - this is general stuff.
6
- * remove xml serialzation here and test resource directly (in active_record_converter_test)
7
- * get rid of to_a warning
6
+ * remove xml serialization here and test resource directly (in active_record_converter_test)
7
+ * get rid of to_a warning
8
+ * convert underscores to dashes (or not) in serializers instead of converter
data/init.rb CHANGED
@@ -1 +1 @@
1
- require File.dirname(__FILE__) + "/rails/init"
1
+ require File.dirname(__FILE__) + "/rails/init"
@@ -15,7 +15,6 @@ module Restful
15
15
  :path => model.restful_path,
16
16
  :url => model.restful_url
17
17
  })
18
-
19
18
 
20
19
  # simple attributes
21
20
  resource.values += Restful::Rails.tools.simple_attributes_on(model).map do |attribute|
@@ -41,7 +40,7 @@ module Restful
41
40
  end
42
41
  elsif model.class.reflections[key].macro == :has_one or model.class.reflections[key].macro == :belongs_to
43
42
 
44
- if(config.expanded? && !nested)
43
+ if(config.expanded?(key, nested))
45
44
  convert_to_collection(model, key, nested_config, published) do |key, resources, extended_type|
46
45
  returning(resources.first) do |res|
47
46
  res.name = key
@@ -74,18 +73,18 @@ module Restful
74
73
  resource.values += (model.public_methods - Restful::Rails.tools.simple_attributes_on(model).keys.map(&:to_s)).map do |method_name|
75
74
  if config.published?(method_name.to_sym) and not published.include?(method_name.to_sym)
76
75
  value = model.send(method_name.to_sym)
77
- sanitzed_method_name = method_name.tr("!?", "").tr("_", "-").to_sym
76
+ sanitized_method_name = method_name.tr("!?", "").tr("_", "-").to_sym
78
77
 
79
78
  if value.is_a? ::ActiveRecord::Base
80
- if config.expanded? && !nested
79
+ if config.expanded?(method_name.to_sym, nested)
81
80
  returning Restful::Rails.tools.expand(value, config.nested(method_name.to_sym)) do |expanded|
82
- expanded.name = sanitzed_method_name
81
+ expanded.name = sanitized_method_name
83
82
  end
84
83
  else
85
- Restful.link("#{ sanitzed_method_name }-restful-url", Restful::Rails.api_hostname, value ? value.restful_path : "", compute_extended_type(model, key))
84
+ Restful.link("#{ sanitized_method_name }-restful-url", Restful::Rails.api_hostname, value ? value.restful_path : "", compute_extended_type(model, key))
86
85
  end
87
86
  else
88
- Restful.attr(sanitzed_method_name, value, compute_extended_type(model, method_name))
87
+ Restful.attr(sanitized_method_name, value, compute_extended_type(model, method_name))
89
88
  end
90
89
  end
91
90
  end.compact
@@ -119,6 +118,8 @@ module Restful
119
118
  :string
120
119
  when :time
121
120
  :datetime
121
+ when :date
122
+ :date
122
123
  else
123
124
  type_symbol
124
125
  end
@@ -42,6 +42,7 @@ module Restful
42
42
  end
43
43
 
44
44
  config.whitelisted = self.class.restful_config.whitelisted if config.whitelisted.empty?
45
+ config.restful_options.merge! self.class.restful_config.restful_options
45
46
 
46
47
  Restful::Converters::ActiveRecord.convert(self, config)
47
48
  end
@@ -75,9 +76,14 @@ module Restful
75
76
  @whitelisted.include?(key) || !!@whitelisted.select { |field| field.is_a?(Hash) && field.keys.include?(key) }.first
76
77
  end
77
78
 
78
- def expanded? # if nothing was set, this defaults to true.
79
- @restful_options[:expansion] != :collapsed
80
- end
79
+ def expanded?(key, nested = false) # if nothing was set, this defaults to true.
80
+ force_expanded?(key) || (@restful_options[:expansion] != :collapsed && !nested)
81
+ end
82
+
83
+ def force_expanded?(key)
84
+ force = [*@restful_options[:force_expand]]
85
+ force.include?(key)
86
+ end
81
87
 
82
88
  def nested?
83
89
  !!restful_options[:nested]
@@ -28,6 +28,20 @@ module Restful
28
28
  self.serializers[key] = self
29
29
  end
30
30
 
31
+ def formatted_value(value)
32
+ return nil if value.value.blank? && value.extended_type != :false_class
33
+ case value.extended_type
34
+ when :datetime
35
+ value.value.xmlschema
36
+ when :time
37
+ value.value.xmlschema
38
+ when :date
39
+ value.value.to_s(:db)
40
+ else
41
+ value.value
42
+ end
43
+ end
44
+
31
45
  protected
32
46
  def transform_link_name(name)
33
47
  name.to_s.gsub /_id$/, "-restful-url"
@@ -8,6 +8,7 @@ module Restful
8
8
  class HashSerializer < Base
9
9
 
10
10
  serializer_name :hash
11
+
11
12
 
12
13
  def serialize(resource, options = {})
13
14
  params = {}
@@ -15,31 +16,32 @@ module Restful
15
16
  resource.values.each do |value|
16
17
  if value.type == :collection # serialize the stuffs
17
18
  resources = value.value
19
+ next if resources.empty?
18
20
  name = resources.first.name.pluralize
19
21
 
20
22
  array = []
21
- resources.each { |r| array << serialize(r) }
23
+ resources.each do |r|
24
+ array << serialize(r)
25
+ end
22
26
 
23
- params["#{value.name}".to_sym] = array
27
+ params[hashify_key(value.name)] = array
24
28
  elsif value.type == :link
25
- params[value.name] = Restful::Rails.tools.dereference(value.value)
29
+ params[hashify_key(value.name)] = Restful::Rails.tools.dereference(value.value)
26
30
  elsif value.type == :resource
27
- params["#{value.name}".to_sym] = serialize(value)
31
+ params[hashify_key(value.name)] = serialize(value)
28
32
  else # plain ole
29
- string_value = case value.extended_type
30
- when :datetime
31
- value.value.xmlschema
32
- else
33
- value.value
34
- end
35
-
36
- params[value.name] = string_value
33
+ params[hashify_key(value.name)] = formatted_value(value)
37
34
  end
38
35
  end
39
36
 
40
37
  params["restful_url"] = resource.full_url
41
38
  params
42
39
  end
40
+
41
+ private
42
+ def hashify_key(original_key)
43
+ original_key.to_s.tr("-", "_").to_sym
44
+ end
43
45
  end
44
46
  end
45
47
  end
@@ -12,10 +12,10 @@ module Restful
12
12
 
13
13
  def serialize(resource, options = {})
14
14
  params = {}
15
-
16
15
  resource.values.each do |value|
17
16
  if value.type == :collection # serialize the stuffs
18
17
  resources = value.value
18
+ next if resources.empty?
19
19
  name = resources.first.name.pluralize
20
20
 
21
21
  array = []
@@ -23,18 +23,24 @@ module Restful
23
23
  array << serialize(resource)
24
24
  end
25
25
 
26
- params["#{value.name.to_sym}_attributes".to_sym] = array
26
+ params["#{paramify_keys(value.name)}_attributes".to_sym] = array
27
27
  elsif value.type == :link
28
- params[value.name] = Restful::Rails.tools.dereference(value.value)
28
+ params[paramify_keys(value.name).to_sym] = Restful::Rails.tools.dereference(value.value)
29
29
  elsif value.type == :resource
30
- params["#{value.name.to_sym}_attributes".to_sym] = serialize(value)
30
+ params["#{paramify_keys(value.name)}_attributes".to_sym] = serialize(value)
31
31
  else # plain ole
32
- params[value.name] = value.value
32
+ params[paramify_keys(value.name).to_sym] = value.value # no need to format dates etc - just pass objects through.
33
33
  end
34
34
  end
35
35
 
36
36
  params
37
37
  end
38
- end
38
+
39
+ private
40
+
41
+ def paramify_keys(original_key)
42
+ original_key.to_s.tr("-", "_")
43
+ end
44
+ end
39
45
  end
40
46
  end
@@ -58,18 +58,20 @@ module Restful
58
58
  end
59
59
 
60
60
  def add_tag(builder, value)
61
- string_value = case value.extended_type
62
- when :datetime
63
- value.value.xmlschema
61
+
62
+ if value.extended_type == :hash
63
+ build_hash(builder, value)
64
64
  else
65
- value.value.to_s
65
+ builder.tag!(value.name.to_s.dasherize, formatted_value(value), decorations(value))
66
+ end
67
+ end
68
+
69
+ def build_hash(builder, value)
70
+ builder.tag!(value.name.to_s.dasherize) do
71
+ value.value.each do |k, v|
72
+ builder.tag! k.to_s.dasherize, v
73
+ end
66
74
  end
67
-
68
- builder.tag!(
69
- value.name.to_s.dasherize,
70
- string_value,
71
- decorations(value)
72
- )
73
75
  end
74
76
 
75
77
  def decorations(value)
@@ -91,6 +93,10 @@ module Restful
91
93
  decorations[:nil] = true
92
94
  end
93
95
 
96
+ if value.value.is_a?(FalseClass) || value.value.is_a?(TrueClass)
97
+ decorations[:type] = :boolean
98
+ end
99
+
94
100
  decorations
95
101
  end
96
102
 
data/restful.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "restful"
3
- s.version = "0.2.1"
3
+ s.version = "0.2.2"
4
4
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
5
5
  s.authors = ["Daniel Bornkessel", "Rany Keddo"]
6
6
  s.date = "2009-08-11"
@@ -8,7 +8,7 @@ context "active record converter" do
8
8
  Person.restful_publish(:name, :wallet, :current_location, :pets => [:name, :species])
9
9
  Pet.restful_publish(:person_id, :name) # person_id gets converted to a link automagically.
10
10
 
11
- @person = Person.create(:name => "Joe Bloggs", :current_location => "Under a tree")
11
+ @person = Person.create(:name => "Joe Bloggs", :current_location => "Under a tree", :birthday => "1976-04-03")
12
12
  @wallet = @person.wallet = Wallet.create!(:contents => "something in the wallet")
13
13
  @pet = @person.pets.create(:name => "Mietze", :species => "cat")
14
14
  end
@@ -17,6 +17,14 @@ context "active record converter" do
17
17
  reset_config
18
18
  end
19
19
 
20
+ specify "should be able to force expansion. force expanded attributes can never be collapsed. " do
21
+ Wallet.restful_publish(:contents)
22
+ Person.restful_publish(:name, :wallet, :current_location, { :pets => [:name, :species], :restful_options => { :force_expand => :wallet } })
23
+ Pet.restful_publish(:owner, :name)
24
+
25
+ @pet.to_restful
26
+ end
27
+
20
28
  specify "should return link attributes from a model" do
21
29
  @pet.to_restful.links.map { |node| node.name }.sort.should.equal [:person_id]
22
30
  end
@@ -38,6 +46,11 @@ context "active record converter" do
38
46
  restful.collections.map { |node| node.name }.sort.should.equal [:pets]
39
47
  end
40
48
 
49
+ specify "should set correct type for date" do
50
+ restful = @person.to_restful :birthday
51
+ restful.simple_attributes.detect { |node| node.name == :birthday }.extended_type.should.== :date
52
+ end
53
+
41
54
  specify "should be able to convert themselves to an apimodel containing all and only the attributes exposed by Model.publish_api" do
42
55
  resource = @person.to_restful
43
56
 
@@ -13,5 +13,17 @@ class Person < ActiveRecord::Base
13
13
  "Hi. I'm currently in #{ current_location }"
14
14
  end
15
15
 
16
+ def has_pets
17
+ pets.size > 0
18
+ end
19
+
20
+ def pets_ages_hash
21
+ returning pets_hash = {} do
22
+ pets.each do |pet|
23
+ pets_hash[pet.name] = pet.age
24
+ end
25
+ end
26
+ end
27
+
16
28
  apiable
17
29
  end
@@ -13,4 +13,57 @@ bloggs:
13
13
  "name": "mietze"
14
14
  }],
15
15
  "created_at": "<%= @person.created_at.xmlschema %>"
16
+ }
17
+
18
+ bloggs_with_oldest_pet:
19
+ |
20
+ {
21
+ "restful_url": "http://example.com:3000/people/<%= @person.to_param %>",
22
+ "oldest_pet": {
23
+ "restful_url": "http://example.com:3000/pets/<%= @person.pets.first.to_param %>",
24
+ "name": "mietze"
25
+ }
26
+ }
27
+
28
+ bloggs_with_birthday:
29
+ |
30
+ {
31
+ "restful_url": "http://example.com:3000/people/<%= @person.to_param %>",
32
+ "birthday": "<%= @person.birthday.to_s(:db) %>"
33
+ }
34
+
35
+ bloggs_with_pets_ages_hash:
36
+ |
37
+ {
38
+ "restful_url": "http://example.com:3000/people/<%= @person.to_param %>",
39
+ "pets_ages_hash": {
40
+ "mietze": 200,
41
+ "motze": 100
42
+ }
43
+ }
44
+ bloggs_with_has_pets:
45
+ |
46
+ {
47
+ "restful_url": "http://example.com:3000/people/<%= @person.to_param %>",
48
+ "has_pets": true
49
+ }
50
+ bloggs_with_hasno_pets:
51
+ |
52
+ {
53
+ "restful_url": "http://example.com:3000/people/<%= @person.to_param %>",
54
+ "has_pets": false
55
+ }
56
+
57
+
58
+ bloggs_da_pet_hater:
59
+ |
60
+ {
61
+ "restful_url": "http://example.com:3000/people/<%= @person.to_param %>",
62
+ "wallet": {
63
+ "restful_url": "http://example.com:3000/wallets/<%= @person.wallet.to_param %>",
64
+ "contents": "an old photo, 5 euros in coins"
65
+ },
66
+ "current_location": "Under a tree",
67
+ "name": "Joe Bloggs",
68
+ "created_at": "<%= @person.created_at.xmlschema %>"
16
69
  }
@@ -37,7 +37,15 @@ with_oldest_pet_species:
37
37
  <species type="integer"><%= @person.oldest_pet.species %></species>
38
38
  </oldest-pet>
39
39
  </person>
40
-
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
+
41
49
  joe_with_zwiebelleder:
42
50
  |
43
51
  <?xml version="1.0" encoding="UTF-8"?>
@@ -102,4 +110,14 @@ with_pets_and_expanded_wallet:
102
110
  <contents>an old photo, 5 euros in coins</contents>
103
111
  </wallet>
104
112
  </person>
105
-
113
+
114
+ hashy_person:
115
+ |
116
+ <?xml version="1.0" encoding="UTF-8"?>
117
+ <person>
118
+ <restful-url type="link">http://example.com:3000/people/<%= @person.id %></restful-url>
119
+ <pets-ages-hash>
120
+ <mietze>200</mietze>
121
+ <motze>100</motze>
122
+ </pets-ages-hash>
123
+ </person>
@@ -7,7 +7,7 @@ context "json serializer" do
7
7
  Pet.restful_publish(:name)
8
8
  Wallet.restful_publish(:contents)
9
9
 
10
- @person = Person.create(:name => "Joe Bloggs", :current_location => "Under a tree")
10
+ @person = Person.create(:name => "Joe Bloggs", :current_location => "Under a tree", :birthday => "2009-09-19")
11
11
  @pet = @person.pets.create(:species => "cat", :age => 200, :name => "mietze")
12
12
  @wallet = @person.wallet = Wallet.new(:contents => "an old photo, 5 euros in coins")
13
13
  @person.save
@@ -18,4 +18,46 @@ context "json serializer" do
18
18
  specify "serialize to json" do
19
19
  json_should_eql_fixture(@person.to_restful_json, "people", :bloggs)
20
20
  end
21
+
22
+ specify "should be able to serialize objects with empty collections" do
23
+ @person.pets = []
24
+ assert_nothing_raised do
25
+ json_should_eql_fixture(@person.to_restful_json, "people", :bloggs_da_pet_hater)
26
+ end
27
+ end
28
+
29
+ specify "should serialize date type correctly" do
30
+ json_should_eql_fixture(@person.to_restful_json(:birthday), "people", :bloggs_with_birthday)
31
+ end
32
+
33
+ specify "should not bug out on nil values in date fields" do
34
+ person = Person.create :created_at => nil, :birthday => nil, :last_login => nil
35
+ person.created_at = nil
36
+ expected = "{\"birthday\":null,\"restful_url\":\"http://example.com:3000/people/#{person.to_param}\",\"last_login\":null,\"created_at\":null}"
37
+ assert_nothing_raised do
38
+ actual = person.to_restful_json([:created_at, :birthday, :last_login])
39
+ json_should_eql(actual, expected)
40
+ end
41
+ end
42
+
43
+ specify "should serialize hashes correctly" do
44
+ @person.pets.create(:species => "cat", :age => 100, :name => "motze")
45
+ json_should_eql_fixture(@person.to_restful_json(:pets_ages_hash), "people", :bloggs_with_pets_ages_hash)
46
+ end
47
+
48
+ specify "should render boolean values correctly" do
49
+ json_should_eql_fixture(@person.to_restful_json(:has_pets), "people", :bloggs_with_has_pets)
50
+ @person.pets = []
51
+ @person.save!
52
+ json_should_eql_fixture(@person.to_restful_json(:has_pets), "people", :bloggs_with_hasno_pets)
53
+ end
54
+
55
+ specify "should not ever use dashes as hash keys but underscores" do
56
+ assert_nothing_raised do
57
+ json_should_eql_fixture(@person.to_restful_json(:oldest_pet), "people", :bloggs_with_oldest_pet)
58
+ end
59
+ end
60
+
61
+
62
+
21
63
  end
@@ -7,7 +7,7 @@ context "params serializer" do
7
7
  Pet.restful_publish(:name)
8
8
  Wallet.restful_publish(:contents)
9
9
 
10
- @person = Person.create(:name => "Joe Bloggs", :current_location => "Under a tree")
10
+ @person = Person.create(:name => "Joe Bloggs", :current_location => "Under a tree", :birthday => "1942-01-11")
11
11
  @pet = @person.pets.create(:species => "cat", :age => 200, :name => "mietze")
12
12
  @wallet = @person.wallet = Wallet.new(:contents => "an old photo, 5 euros in coins")
13
13
  @person.save
@@ -17,6 +17,30 @@ context "params serializer" do
17
17
  reset_config
18
18
  end
19
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
+
20
44
  specify "serialize to params" do
21
45
  actual = @person.to_restful.serialize(:params)
22
46
 
@@ -32,6 +56,14 @@ context "params serializer" do
32
56
  actual.should.== expected
33
57
  end
34
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
+
35
67
  specify "serialize to an ar params hash" do
36
68
  input = xml_fixture("pets")[:gracie]
37
69
  params = Restful.from_xml(input).serialize(:params)
@@ -6,7 +6,7 @@ context "params serializer" do
6
6
  Pet.restful_publish(:name)
7
7
  Wallet.restful_publish(:contents)
8
8
 
9
- @person = Person.create(:name => "Joe Bloggs", :current_location => "Under a tree")
9
+ @person = Person.create(:name => "Joe Bloggs", :current_location => "Under a tree", :birthday => "1990-03-09")
10
10
  @pet = @person.pets.create(:species => "cat", :age => 200, :name => "mietze")
11
11
  @wallet = @person.wallet = Wallet.new(:contents => "an old photo, 5 euros in coins")
12
12
  @person.save
@@ -26,6 +26,10 @@ context "params serializer" do
26
26
  xml_should_eql(expected, actual)
27
27
  end
28
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
+
29
33
  specify "should convert a NULL inner association such as person.wallet to a link with a null value" do
30
34
  @person.wallet = nil
31
35
 
@@ -35,4 +39,9 @@ context "params serializer" do
35
39
  specify "serialize to xml, rails style" do
36
40
  xml_should_eql_fixture(@person.to_restful_xml, "people", :with_pets_and_expanded_wallet)
37
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
38
47
  end
data/test/test_helper.rb CHANGED
@@ -43,6 +43,8 @@ silence_stream(STDOUT) do
43
43
  t.string :name
44
44
  t.string :current_location
45
45
  t.string :biography
46
+ t.date :birthday
47
+ t.datetime :last_login
46
48
 
47
49
  t.timestamp :created_at
48
50
  t.timestamp :updated_at
@@ -90,10 +92,25 @@ end
90
92
  def json_cmp(actual, expected)
91
93
  actual = Yajl::Parser.parse(actual)
92
94
  expected = Yajl::Parser.parse(expected)
93
-
95
+ puts_hash_diff actual, expected
94
96
  actual == expected
95
97
  end
96
98
 
99
+ def puts_hash_diff(hash1, hash2, indent = 0)
100
+ return if hash1 == hash2
101
+
102
+ (hash1.keys + hash2.keys).uniq.each do |key|
103
+ next if hash1[key] == hash2[key]
104
+ print " "*indent
105
+ if hash1[key].is_a? Hash or hash2[key].is_a? Hash
106
+ puts "=== #{key} is a Hash ==="
107
+ puts_hash_diff(hash1[key] || {}, hash2[key] || {}, indent+2)
108
+ else
109
+ printf "%-#{20-indent}s %#{50-indent}s != %-50s\n", key[0..19], hash1[key], hash2[key]
110
+ end
111
+ end
112
+ end
113
+
97
114
  def xml_should_eql_fixture(actual, name, key)
98
115
  expected = Hpricot(xml_fixture(name)[key])
99
116
  actual = Hpricot(actual)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: purzelrakete-restful
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Bornkessel