restful 0.2.20

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.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
+