restpack_serializer 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,102 @@
1
+ require './spec/spec_helper'
2
+
3
+ describe RestPack::Serializer do
4
+ let(:serializer) { PersonSerializer.new }
5
+ let(:person) { Person.new(id: 123, name: 'Gavin', age: 36) }
6
+ class Person
7
+ attr_accessor :id, :name, :age
8
+
9
+ def initialize(attributes = {})
10
+ @id = attributes[:id]
11
+ @name = attributes[:name]
12
+ @age = attributes[:age]
13
+ end
14
+
15
+ def self.table_name
16
+ "people"
17
+ end
18
+ end
19
+
20
+ context "bare bones serializer" do
21
+ class EmptySerializer
22
+ include RestPack::Serializer
23
+ end
24
+
25
+ it "serializes to an empty hash" do
26
+ EmptySerializer.as_json(person).should == { }
27
+ end
28
+ end
29
+
30
+ class PersonSerializer
31
+ include RestPack::Serializer
32
+ attributes :id, :name, :url, :admin_info
33
+
34
+ def url
35
+ "/api/v1/people/#{id}.json"
36
+ end
37
+
38
+ def admin_info
39
+ { key: "super_secret_sauce" }
40
+ end
41
+
42
+ def include_admin_info?
43
+ @options[:is_admin?]
44
+ end
45
+ end
46
+
47
+ describe ".as_json" do
48
+ it "serializes specified attributes" do
49
+ serializer.as_json(person).should == {
50
+ id: '123', name: 'Gavin', url: '/api/v1/people/123.json'
51
+ }
52
+ end
53
+
54
+ context "with options" do
55
+ it "excludes specified attributes" do
56
+ serializer.as_json(person, { include_url?: false }).should == {
57
+ id: '123', name: 'Gavin'
58
+ }
59
+ end
60
+
61
+ it "excludes custom attributes if specified" do
62
+ hash = serializer.as_json(person, { is_admin?: false })
63
+ hash[:admin_info].should == nil
64
+ end
65
+
66
+ it "includes custom attributes if specified" do
67
+ hash = serializer.as_json(person, { is_admin?: true })
68
+ hash[:admin_info].should == { key: "super_secret_sauce" }
69
+ end
70
+ end
71
+
72
+ context "links" do
73
+ let(:serializer) { SongSerializer.new }
74
+ it "includes 'links' data" do
75
+ @album1 = FactoryGirl.create(:album_with_songs, song_count: 11)
76
+ json = serializer.as_json(@album1.songs.first)
77
+ json[:links].should == {
78
+ artist: @album1.artist_id.to_s,
79
+ album: @album1.id.to_s
80
+ }
81
+ end
82
+ end
83
+ end
84
+
85
+ describe "#model_name" do
86
+ it "extracted the Model name from the Serializer name" do
87
+ PersonSerializer.model_name.should == "Person"
88
+ end
89
+ end
90
+
91
+ describe "#model_class" do
92
+ it "returns the correct class" do
93
+ PersonSerializer.model_class.should == Person
94
+ end
95
+ end
96
+
97
+ describe "#key" do
98
+ it "returns the correct key" do
99
+ PersonSerializer.key.should == :people
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,72 @@
1
+ require './spec/spec_helper'
2
+
3
+ describe RestPack::Serializer::SideLoading do
4
+ context "when side-loading" do
5
+ describe ".belongs_to" do
6
+
7
+ before(:each) do
8
+ FactoryGirl.create(:artist_with_albums, album_count: 2)
9
+ FactoryGirl.create(:artist_with_albums, album_count: 1)
10
+ end
11
+ let(:side_loads) { SongSerializer.side_loads(models, options) }
12
+
13
+ context "with no models" do
14
+ let(:models) { [] }
15
+
16
+ context "no side-loads" do
17
+ let(:options) { RestPack::Serializer::Options.new(Song) }
18
+
19
+ it "returns a hash with no data" do
20
+ side_loads.should == { :meta => {} }
21
+ end
22
+ end
23
+
24
+ context "when including :albums" do
25
+ let(:options) { RestPack::Serializer::Options.new(Song, { "includes" => "albums" }) }
26
+
27
+ it "returns a hash with no data" do
28
+ side_loads.should == { :meta => {} }
29
+ end
30
+ end
31
+ end
32
+
33
+ context "with a single model" do
34
+ let(:models) { [Song.first] }
35
+
36
+ context "when including :albums" do
37
+ let(:options) { RestPack::Serializer::Options.new(Song, { "includes" => "albums" }) }
38
+
39
+ it "returns side-loaded albums" do
40
+ side_loads.should == {
41
+ albums: [AlbumSerializer.as_json(Song.first.album)],
42
+ meta: { }
43
+ }
44
+ end
45
+ end
46
+ end
47
+
48
+ context "with multiple models" do
49
+ let(:artist1) { Artist.find(1) }
50
+ let(:artist2) { Artist.find(2) }
51
+ let(:song1) { artist1.songs.first }
52
+ let(:song2) { artist2.songs.first }
53
+ let(:models) { [song1, song2] }
54
+
55
+ context "when including :albums" do
56
+ let(:options) { RestPack::Serializer::Options.new(Song, { "includes" => "albums" }) }
57
+
58
+ it "returns side-loaded albums" do
59
+ side_loads.should == {
60
+ albums: [
61
+ AlbumSerializer.as_json(song1.album),
62
+ AlbumSerializer.as_json(song2.album)
63
+ ],
64
+ :meta => { }
65
+ }
66
+ end
67
+ end
68
+ end
69
+
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,43 @@
1
+ require './spec/spec_helper'
2
+
3
+ describe RestPack::Serializer::SideLoading do
4
+ context "when side-loading" do
5
+ describe ".has_many" do
6
+
7
+ before(:each) do
8
+ @artist1 = FactoryGirl.create(:artist_with_albums, album_count: 2)
9
+ @artist2 = FactoryGirl.create(:artist_with_albums, album_count: 1)
10
+ end
11
+ let(:side_loads) { ArtistSerializer.side_loads(models, options) }
12
+
13
+ context "with a single model" do
14
+ let(:models) { [@artist1] }
15
+
16
+ context "when including :albums" do
17
+ let(:options) { RestPack::Serializer::Options.new(Artist, { "includes" => "albums" }) }
18
+
19
+ it "returns side-loaded albums" do
20
+ side_loads[:albums].count.should == @artist1.albums.count
21
+ side_loads[:meta][:albums][:page].should == 1
22
+ side_loads[:meta][:albums][:count].should == @artist1.albums.count
23
+ end
24
+ end
25
+ end
26
+
27
+ context "with two models" do
28
+ let(:models) { [@artist1, @artist2] }
29
+
30
+ context "when including :albums" do
31
+ let(:options) { RestPack::Serializer::Options.new(Artist, { "includes" => "albums" }) }
32
+
33
+ it "returns side-loaded albums" do
34
+ expected_count = @artist1.albums.count + @artist2.albums.count
35
+ side_loads[:albums].count.should == expected_count
36
+ side_loads[:meta][:albums][:count].should == expected_count
37
+ end
38
+ end
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,82 @@
1
+ require './spec/spec_helper'
2
+
3
+ describe RestPack::Serializer::SideLoading do
4
+ context "invalid :includes" do
5
+ before(:each) do
6
+ FactoryGirl.create(:song)
7
+ end
8
+
9
+ context "an include to an inexistent model" do
10
+ it "raises an exception" do
11
+ exception = RestPack::Serializer::InvalidInclude
12
+ message = ":wrong is not a valid include for Song"
13
+
14
+ expect do
15
+ SongSerializer.side_loads([Song.first], RestPack::Serializer::Options.new(Song, { "includes" => "wrong" }))
16
+ end.to raise_error(exception, message)
17
+ end
18
+ end
19
+
20
+ context "an include to a model which has not been whitelisted with 'can_include'" do
21
+ it "raises an exception" do
22
+ payment = FactoryGirl.create(:payment)
23
+ exception = RestPack::Serializer::InvalidInclude
24
+ message = ":payments is not a valid include for Artist"
25
+
26
+ expect do
27
+ ArtistSerializer.side_loads([payment.artist], RestPack::Serializer::Options.new(Artist, { "includes" => "payments" }))
28
+ end.to raise_error(exception, message)
29
+ end
30
+ end
31
+ end
32
+
33
+ describe "#can_include" do
34
+ class CustomSerializer
35
+ include RestPack::Serializer
36
+ attributes :a, :b, :c
37
+ end
38
+ it "defaults to empty array" do
39
+ CustomSerializer.can_includes.should == []
40
+ end
41
+
42
+ it "allows includes to be specified" do
43
+ class CustomSerializer
44
+ can_include :model1
45
+ can_include :model2, :model3
46
+ end
47
+
48
+ CustomSerializer.can_includes.should == [:model1, :model2, :model3]
49
+ end
50
+ end
51
+
52
+ describe "#links" do
53
+ AlbumSerializer.links.should == {
54
+ "albums.artists" => {
55
+ :href => "/artists/{albums.artist}.json",
56
+ :type => :artists
57
+ },
58
+ "albums.songs" => {
59
+ :href => "/songs.json?album_id={albums.id}",
60
+ :type => :songs
61
+ }
62
+ }
63
+ end
64
+
65
+ describe "#filterable_by" do
66
+ context "a model with no :belongs_to relations" do
67
+ it "is filterable by :id only" do
68
+ ArtistSerializer.filterable_by.should == [:id]
69
+ end
70
+ end
71
+ context "a model with a single :belongs_torelations" do
72
+ it "is filterable by primary key and foreign keys" do
73
+ AlbumSerializer.filterable_by.should =~ [:id, :artist_id]
74
+ end
75
+ end
76
+ context "a model with multiple :belongs_to relations" do
77
+ it "is filterable by primary key and foreign keys" do
78
+ SongSerializer.filterable_by.should =~ [:id, :artist_id, :album_id]
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,32 @@
1
+ require 'rspec'
2
+ require './lib/restpack_serializer'
3
+ require './spec/fixtures/db'
4
+ require './spec/fixtures/serializers'
5
+ require './spec/support/factory'
6
+ require 'database_cleaner'
7
+
8
+ FactoryGirl.find_definitions
9
+
10
+ RSpec.configure do |config|
11
+ config.include FactoryGirl::Syntax::Methods
12
+
13
+ config.before(:suite) do
14
+ DatabaseCleaner.clean_with(:truncation)
15
+ end
16
+
17
+ config.before(:each) do
18
+ DatabaseCleaner.strategy = :transaction
19
+ end
20
+
21
+ config.before(:each, :js => true) do
22
+ DatabaseCleaner.strategy = :truncation
23
+ end
24
+
25
+ config.before(:each) do
26
+ DatabaseCleaner.start
27
+ end
28
+
29
+ config.after(:each) do
30
+ DatabaseCleaner.clean
31
+ end
32
+ end
@@ -0,0 +1,45 @@
1
+ require 'factory_girl'
2
+
3
+ FactoryGirl.define do
4
+ factory :artist do
5
+ sequence(:name) {|n| "Artist ##{n}" }
6
+ sequence(:website) {|n| "http://website#{n}.com/" }
7
+
8
+ factory :artist_with_albums do
9
+ ignore do
10
+ album_count 3
11
+ end
12
+
13
+ after(:create) do |artist, evaluator|
14
+ create_list(:album_with_songs, evaluator.album_count, artist: artist)
15
+ end
16
+ end
17
+ end
18
+
19
+ factory :album do
20
+ sequence(:title) {|n| "Album ##{n}" }
21
+ sequence(:year) {|n| 1960 + n }
22
+ artist
23
+
24
+ factory :album_with_songs do
25
+ ignore do
26
+ song_count 10
27
+ end
28
+
29
+ after(:create) do |album, evaluator|
30
+ create_list(:song, evaluator.song_count, album: album, artist: album.artist)
31
+ end
32
+ end
33
+ end
34
+
35
+ factory :song do
36
+ sequence(:title) {|n| "Song ##{n}" }
37
+ artist
38
+ album
39
+ end
40
+
41
+ factory :payment do
42
+ amount 999
43
+ artist
44
+ end
45
+ end
metadata ADDED
@@ -0,0 +1,266 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: restpack_serializer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Gavin Joyce
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-05-18 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activerecord
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '3.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '3.0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: activesupport
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '3.0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '3.0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: will_paginate
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '3.0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 10.0.3
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 10.0.3
78
+ - !ruby/object:Gem::Dependency
79
+ name: rspec
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: '2.12'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: '2.12'
94
+ - !ruby/object:Gem::Dependency
95
+ name: guard-rspec
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: 2.5.4
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: 2.5.4
110
+ - !ruby/object:Gem::Dependency
111
+ name: growl
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: 1.0.3
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: 1.0.3
126
+ - !ruby/object:Gem::Dependency
127
+ name: factory_girl
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ~>
132
+ - !ruby/object:Gem::Version
133
+ version: 4.2.0
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ~>
140
+ - !ruby/object:Gem::Version
141
+ version: 4.2.0
142
+ - !ruby/object:Gem::Dependency
143
+ name: sqlite3
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ~>
148
+ - !ruby/object:Gem::Version
149
+ version: 1.3.7
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ~>
156
+ - !ruby/object:Gem::Version
157
+ version: 1.3.7
158
+ - !ruby/object:Gem::Dependency
159
+ name: database_cleaner
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ~>
164
+ - !ruby/object:Gem::Version
165
+ version: 0.9.1
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ~>
172
+ - !ruby/object:Gem::Version
173
+ version: 0.9.1
174
+ - !ruby/object:Gem::Dependency
175
+ name: bump
176
+ requirement: !ruby/object:Gem::Requirement
177
+ none: false
178
+ requirements:
179
+ - - ! '>='
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ type: :development
183
+ prerelease: false
184
+ version_requirements: !ruby/object:Gem::Requirement
185
+ none: false
186
+ requirements:
187
+ - - ! '>='
188
+ - !ruby/object:Gem::Version
189
+ version: '0'
190
+ description: Model serialization, paging, side-loading and filtering
191
+ email:
192
+ - gavinjoyce@gmail.com
193
+ executables: []
194
+ extensions: []
195
+ extra_rdoc_files: []
196
+ files:
197
+ - .gitignore
198
+ - .rspec
199
+ - .travis.yml
200
+ - Gemfile
201
+ - Gemfile.lock
202
+ - Guardfile
203
+ - LICENSE
204
+ - README.md
205
+ - Rakefile
206
+ - lib/restpack_serializer.rb
207
+ - lib/restpack_serializer/factory.rb
208
+ - lib/restpack_serializer/options.rb
209
+ - lib/restpack_serializer/serializable.rb
210
+ - lib/restpack_serializer/serializable/attributes.rb
211
+ - lib/restpack_serializer/serializable/paging.rb
212
+ - lib/restpack_serializer/serializable/resource.rb
213
+ - lib/restpack_serializer/serializable/side_loading.rb
214
+ - lib/restpack_serializer/version.rb
215
+ - restpack_serializer.gemspec
216
+ - spec/factory/factory_spec.rb
217
+ - spec/fixtures/db.rb
218
+ - spec/fixtures/serializers.rb
219
+ - spec/serializable/attributes_spec.rb
220
+ - spec/serializable/options_spec.rb
221
+ - spec/serializable/paging_spec.rb
222
+ - spec/serializable/resource_spec.rb
223
+ - spec/serializable/serializer_spec.rb
224
+ - spec/serializable/side_loading/belongs_to_spec.rb
225
+ - spec/serializable/side_loading/has_many_spec.rb
226
+ - spec/serializable/side_loading/side_loading_spec.rb
227
+ - spec/spec_helper.rb
228
+ - spec/support/factory.rb
229
+ homepage: https://github.com/RestPack
230
+ licenses: []
231
+ post_install_message:
232
+ rdoc_options: []
233
+ require_paths:
234
+ - lib
235
+ required_ruby_version: !ruby/object:Gem::Requirement
236
+ none: false
237
+ requirements:
238
+ - - ! '>='
239
+ - !ruby/object:Gem::Version
240
+ version: '0'
241
+ required_rubygems_version: !ruby/object:Gem::Requirement
242
+ none: false
243
+ requirements:
244
+ - - ! '>='
245
+ - !ruby/object:Gem::Version
246
+ version: '0'
247
+ requirements: []
248
+ rubyforge_project:
249
+ rubygems_version: 1.8.24
250
+ signing_key:
251
+ specification_version: 3
252
+ summary: Model serialization, paging, side-loading and filtering
253
+ test_files:
254
+ - spec/factory/factory_spec.rb
255
+ - spec/fixtures/db.rb
256
+ - spec/fixtures/serializers.rb
257
+ - spec/serializable/attributes_spec.rb
258
+ - spec/serializable/options_spec.rb
259
+ - spec/serializable/paging_spec.rb
260
+ - spec/serializable/resource_spec.rb
261
+ - spec/serializable/serializer_spec.rb
262
+ - spec/serializable/side_loading/belongs_to_spec.rb
263
+ - spec/serializable/side_loading/has_many_spec.rb
264
+ - spec/serializable/side_loading/side_loading_spec.rb
265
+ - spec/spec_helper.rb
266
+ - spec/support/factory.rb