restful 0.2.20

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.
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.rb +65 -0
  8. data/lib/restful/apimodel/attribute.rb +17 -0
  9. data/lib/restful/apimodel/collection.rb +22 -0
  10. data/lib/restful/apimodel/link.rb +21 -0
  11. data/lib/restful/apimodel/map.rb +41 -0
  12. data/lib/restful/apimodel/resource.rb +23 -0
  13. data/lib/restful/converters/active_record.rb +160 -0
  14. data/lib/restful/rails.rb +22 -0
  15. data/lib/restful/rails/action_controller.rb +14 -0
  16. data/lib/restful/rails/active_record/configuration.rb +219 -0
  17. data/lib/restful/rails/active_record/metadata_tools.rb +102 -0
  18. data/lib/restful/serializers/atom_like_serializer.rb +51 -0
  19. data/lib/restful/serializers/base.rb +58 -0
  20. data/lib/restful/serializers/hash_serializer.rb +46 -0
  21. data/lib/restful/serializers/json_serializer.rb +18 -0
  22. data/lib/restful/serializers/params_serializer.rb +46 -0
  23. data/lib/restful/serializers/xml_serializer.rb +160 -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 +106 -0
@@ -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
@@ -0,0 +1,154 @@
1
+ require 'rubygems'
2
+ require 'ruby-debug'
3
+ require 'active_support'
4
+ require 'active_record'
5
+ require 'action_controller'
6
+ require 'test/spec'
7
+ require 'mocha'
8
+ require 'hpricot'
9
+ require 'xmlsimple'
10
+ require 'yajl'
11
+ require 'pathname'
12
+ require 'stringio'
13
+
14
+ plugin_test = Pathname.new(File.dirname(__FILE__))
15
+ plugin_root = plugin_test.join '..'
16
+ plugin_lib = plugin_root.join 'lib'
17
+
18
+ $:.unshift plugin_lib, plugin_test
19
+
20
+ RAILS_ENV = "test"
21
+ RAILS_ROOT = plugin_root # fake the rails root directory.
22
+ RESTFUL_ROOT = plugin_root
23
+
24
+ ActiveRecord::Base.logger = Logger.new(STDERR)
25
+ ActiveRecord::Base.logger.level = Logger::ERROR
26
+ ActiveRecord::Base.colorize_logging = false
27
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :dbfile => ":memory:")
28
+
29
+ silence_stream(STDOUT) do
30
+ ActiveRecord::Schema.define do
31
+
32
+ create_table :pets do |t|
33
+ t.integer :age, :default => 10
34
+ t.string :name
35
+ t.integer :species
36
+ t.integer :person_id
37
+ t.string :type
38
+
39
+ t.timestamps
40
+ end
41
+
42
+ create_table :houses do |t|
43
+ t.string :name
44
+
45
+ t.timestamps
46
+ end
47
+
48
+ create_table :people do |t|
49
+ t.string :name
50
+ t.string :current_location
51
+ t.string :biography
52
+ t.integer :house_id
53
+ t.date :birthday
54
+ t.datetime :last_login
55
+
56
+ t.timestamps
57
+ end
58
+
59
+ create_table :wallets do |t|
60
+ t.string :person_id
61
+ t.string :contents
62
+
63
+ t.timestamps
64
+ end
65
+ end
66
+ end
67
+
68
+ require plugin_root.join 'init'
69
+ require 'fixtures/models/house'
70
+ require 'fixtures/models/pet'
71
+ require 'fixtures/models/emu'
72
+ require 'fixtures/models/wallet'
73
+ require 'fixtures/models/person'
74
+ require 'fixtures/models/paginated_collection'
75
+
76
+ Restful::Rails.api_hostname = "http://example.com:3000"
77
+
78
+ #
79
+ # Helper methods
80
+ #
81
+ def reset_config
82
+ Person.restful_config = Restful.cfg
83
+ Pet.restful_config = Restful.cfg
84
+ Wallet.restful_config = Restful.cfg
85
+ end
86
+
87
+ def xml_cmp(actual, expected)
88
+ eq_all_but_zero = Object.new.instance_eval do
89
+ def ==(other)
90
+ Integer(other) == 0 ? false : true
91
+ end
92
+ self
93
+ end
94
+
95
+ actual = XmlSimple.xml_in(actual.to_s, 'normalisespace' => eq_all_but_zero)
96
+ expected = XmlSimple.xml_in(expected.to_s, 'normalisespace' => eq_all_but_zero)
97
+ actual == expected
98
+ end
99
+
100
+ def json_cmp(actual, expected)
101
+ actual = Yajl::Parser.parse(actual)
102
+ expected = Yajl::Parser.parse(expected)
103
+ puts_hash_diff actual, expected
104
+ actual == expected
105
+ end
106
+
107
+ def puts_hash_diff(hash1, hash2, indent = 0)
108
+ return if hash1 == hash2
109
+
110
+ ((hash1 || {}).keys + (hash2 || {}).keys).uniq.each do |key|
111
+ next if hash1[key] == hash2[key]
112
+ print " "*indent
113
+ if hash1[key].is_a? Hash or hash2[key].is_a? Hash
114
+ puts "=== #{key} is a Hash ==="
115
+ puts_hash_diff(hash1[key] || {}, hash2[key] || {}, indent+2)
116
+ else
117
+ printf "%-#{20-indent}s %#{50-indent}s != %-50s\n", key[0..19], hash1[key], hash2[key]
118
+ end
119
+ end
120
+ end
121
+
122
+ def xml_should_eql_fixture(actual, name, key)
123
+ expected = Hpricot(xml_fixture(name)[key])
124
+ actual = Hpricot(actual)
125
+
126
+ xml_should_eql(actual, expected)
127
+ end
128
+
129
+ # doing this tests that the content is the same regardless of attribute order etc.
130
+ def xml_should_eql(actual, expected)
131
+ same = xml_cmp(actual, expected)
132
+ actual.should.== expected unless same
133
+ end
134
+
135
+ def json_should_eql_fixture(actual, name, key)
136
+ expected = json_fixture(name)[key]
137
+ json_should_eql(actual, expected)
138
+ end
139
+
140
+ # doing this tests that the content is the same regardless of attribute order etc.
141
+ def json_should_eql(actual, expected)
142
+ same = json_cmp(actual, expected)
143
+ actual.should.== expected unless same
144
+ end
145
+
146
+ def file_fixture(name)
147
+ template = File.open(RESTFUL_ROOT.join("test", "fixtures", name)).read
148
+ fixture = ERB.new(template).result(binding)
149
+ yaml = YAML.load(fixture)
150
+ yaml.symbolize_keys
151
+ end
152
+
153
+ def xml_fixture(name); file_fixture("#{ name }.xml.yaml"); end
154
+ def json_fixture(name); file_fixture("#{ name }.json.yaml"); end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: restful
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ - 20
9
+ version: 0.2.20
10
+ platform: ruby
11
+ authors:
12
+ - Daniel Bornkessel
13
+ - Rany Keddo
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2009-08-11 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description:
23
+ email: M4SSIVE@m4ssive.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files:
29
+ - README.markdown
30
+ files:
31
+ - CHANGES.markdown
32
+ - init.rb
33
+ - lib/restful/apimodel/attribute.rb
34
+ - lib/restful/apimodel/collection.rb
35
+ - lib/restful/apimodel/link.rb
36
+ - lib/restful/apimodel/map.rb
37
+ - lib/restful/apimodel/resource.rb
38
+ - lib/restful/converters/active_record.rb
39
+ - lib/restful/rails/action_controller.rb
40
+ - lib/restful/rails/active_record/configuration.rb
41
+ - lib/restful/rails/active_record/metadata_tools.rb
42
+ - lib/restful/rails.rb
43
+ - lib/restful/serializers/atom_like_serializer.rb
44
+ - lib/restful/serializers/base.rb
45
+ - lib/restful/serializers/hash_serializer.rb
46
+ - lib/restful/serializers/json_serializer.rb
47
+ - lib/restful/serializers/params_serializer.rb
48
+ - lib/restful/serializers/xml_serializer.rb
49
+ - lib/restful.rb
50
+ - LICENSE.markdown
51
+ - rails/init.rb
52
+ - Rakefile
53
+ - README.markdown
54
+ - restful.gemspec
55
+ - test/converters/active_record_converter_test.rb
56
+ - test/converters/basic_types_converter_test.rb
57
+ - test/fixtures/models/paginated_collection.rb
58
+ - test/fixtures/models/person.rb
59
+ - test/fixtures/models/pet.rb
60
+ - test/fixtures/models/wallet.rb
61
+ - test/fixtures/people.json.yaml
62
+ - test/fixtures/people.xml.yaml
63
+ - test/fixtures/pets.json.yaml
64
+ - test/fixtures/pets.xml.yaml
65
+ - test/rails/active_record_metadata_test.rb
66
+ - test/rails/configuration_test.rb
67
+ - test/rails/restful_publish_test.rb
68
+ - test/serializers/atom_serializer_test.rb
69
+ - test/serializers/json_serializer_test.rb
70
+ - test/serializers/params_serializer_test.rb
71
+ - test/serializers/xml_serializer_test.rb
72
+ - test/test_helper.rb
73
+ - TODO.markdown
74
+ has_rdoc: true
75
+ homepage: http://github.com/M4SSIVE/restful
76
+ licenses: []
77
+
78
+ post_install_message:
79
+ rdoc_options:
80
+ - --line-numbers
81
+ - --inline-source
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ segments:
89
+ - 0
90
+ version: "0"
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ requirements:
99
+ - brianmario-yajl-ruby
100
+ rubyforge_project:
101
+ rubygems_version: 1.3.6
102
+ signing_key:
103
+ specification_version: 3
104
+ summary: api niceness.
105
+ test_files: []
106
+