active_model_serializers 0.7.0 → 0.8.0
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +3 -3
- data/CHANGELOG.md +61 -0
- data/DESIGN.textile +2 -2
- data/Gemfile +3 -1
- data/README.md +44 -21
- data/Rakefile +5 -0
- data/active_model_serializers.gemspec +2 -1
- data/bench/perf.rb +43 -0
- data/lib/action_controller/serialization.rb +8 -25
- data/lib/active_model/array_serializer.rb +58 -20
- data/lib/active_model/serializer.rb +132 -16
- data/lib/active_model/serializer/associations.rb +17 -10
- data/lib/active_model/serializers/version.rb +1 -1
- data/lib/active_model_serializers.rb +20 -8
- data/lib/active_record/serializer_override.rb +16 -0
- data/lib/generators/serializer/serializer_generator.rb +3 -2
- data/lib/generators/serializer/templates/serializer.rb +11 -0
- data/test/array_serializer_test.rb +0 -1
- data/test/association_test.rb +103 -0
- data/test/caching_test.rb +96 -0
- data/test/generators_test.rb +16 -2
- data/test/no_serialization_scope_test.rb +1 -1
- data/test/serialization_scope_name_test.rb +67 -0
- data/test/serialization_test.rb +1 -1
- data/test/serializer_support_test.rb +10 -0
- data/test/serializer_test.rb +142 -3
- data/test/test_fakes.rb +12 -0
- data/test/test_helper.rb +8 -7
- metadata +25 -4
- data/RELEASE_NOTES.md +0 -15
@@ -0,0 +1,96 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class CachingTest < ActiveModel::TestCase
|
4
|
+
class NullStore
|
5
|
+
def fetch(key)
|
6
|
+
return store[key] if store[key]
|
7
|
+
|
8
|
+
store[key] = yield
|
9
|
+
end
|
10
|
+
|
11
|
+
def clear
|
12
|
+
store.clear
|
13
|
+
end
|
14
|
+
|
15
|
+
def store
|
16
|
+
@store ||= {}
|
17
|
+
end
|
18
|
+
|
19
|
+
def read(key)
|
20
|
+
store[key]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Programmer
|
25
|
+
def name
|
26
|
+
'Adam'
|
27
|
+
end
|
28
|
+
|
29
|
+
def skills
|
30
|
+
%w(ruby)
|
31
|
+
end
|
32
|
+
|
33
|
+
def read_attribute_for_serialization(name)
|
34
|
+
send name
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_serializers_have_a_cache_store
|
39
|
+
ActiveModel::Serializer.cache = NullStore.new
|
40
|
+
|
41
|
+
assert_kind_of NullStore, ActiveModel::Serializer.cache
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_serializers_can_enable_caching
|
45
|
+
serializer = Class.new(ActiveModel::Serializer) do
|
46
|
+
cached true
|
47
|
+
end
|
48
|
+
|
49
|
+
assert serializer.perform_caching
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_serializers_use_cache
|
53
|
+
serializer = Class.new(ActiveModel::Serializer) do
|
54
|
+
cached true
|
55
|
+
attributes :name, :skills
|
56
|
+
|
57
|
+
def self.to_s
|
58
|
+
'serializer'
|
59
|
+
end
|
60
|
+
|
61
|
+
def cache_key
|
62
|
+
object.name
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
serializer.cache = NullStore.new
|
67
|
+
instance = serializer.new Programmer.new
|
68
|
+
|
69
|
+
instance.to_json
|
70
|
+
|
71
|
+
assert_equal(instance.serializable_hash, serializer.cache.read('serializer/Adam/serializable-hash'))
|
72
|
+
assert_equal(instance.to_json, serializer.cache.read('serializer/Adam/to-json'))
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_array_serializer_uses_cache
|
76
|
+
serializer = Class.new(ActiveModel::ArraySerializer) do
|
77
|
+
cached true
|
78
|
+
|
79
|
+
def self.to_s
|
80
|
+
'array_serializer'
|
81
|
+
end
|
82
|
+
|
83
|
+
def cache_key
|
84
|
+
'cache-key'
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
serializer.cache = NullStore.new
|
89
|
+
instance = serializer.new [Programmer.new]
|
90
|
+
|
91
|
+
instance.to_json
|
92
|
+
|
93
|
+
assert_equal instance.serializable_array, serializer.cache.read('array_serializer/cache-key/serializable-array')
|
94
|
+
assert_equal instance.to_json, serializer.cache.read('array_serializer/cache-key/to-json')
|
95
|
+
end
|
96
|
+
end
|
data/test/generators_test.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class Foo < Rails::Application
|
4
|
-
if Rails.version.start_with? '4'
|
4
|
+
if Rails.version.to_s.start_with? '4'
|
5
5
|
config.eager_load = false
|
6
6
|
config.secret_key_base = 'abc123'
|
7
7
|
end
|
@@ -36,6 +36,18 @@ class SerializerGeneratorTest < Rails::Generators::TestCase
|
|
36
36
|
Object.send :remove_const, :ApplicationSerializer
|
37
37
|
end
|
38
38
|
|
39
|
+
def test_serializer_gets_id
|
40
|
+
run_generator
|
41
|
+
|
42
|
+
assert_file "app/serializers/account_serializer.rb" do |content|
|
43
|
+
if RUBY_VERSION =~ /1.8/
|
44
|
+
assert_match /def id/, content
|
45
|
+
else
|
46
|
+
assert_no_match /def id/, content
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
39
51
|
# def test_uses_namespace_application_serializer_if_one_exists
|
40
52
|
# Object.const_set(:SerializerNamespace, Module.new)
|
41
53
|
# SerializerNamespace.const_set(:ApplicationSerializer, Class.new)
|
@@ -66,6 +78,8 @@ class SerializerGeneratorTest < Rails::Generators::TestCase
|
|
66
78
|
|
67
79
|
def test_with_no_attributes_does_not_add_extra_space
|
68
80
|
run_generator ["account"]
|
69
|
-
assert_file "app/serializers/account_serializer.rb"
|
81
|
+
assert_file "app/serializers/account_serializer.rb" do |content|
|
82
|
+
assert_no_match /\n\nend/, content
|
83
|
+
end
|
70
84
|
end
|
71
85
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
class DefaultScopeNameTest < ActionController::TestCase
|
5
|
+
TestUser = Struct.new(:name, :admin)
|
6
|
+
|
7
|
+
class UserSerializer < ActiveModel::Serializer
|
8
|
+
attributes :admin?
|
9
|
+
def admin?
|
10
|
+
current_user.admin
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class UserTestController < ActionController::Base
|
15
|
+
protect_from_forgery
|
16
|
+
|
17
|
+
before_filter { request.format = :json }
|
18
|
+
|
19
|
+
def current_user
|
20
|
+
TestUser.new('Pete', false)
|
21
|
+
end
|
22
|
+
|
23
|
+
def render_new_user
|
24
|
+
render :json => TestUser.new('pete', false), :serializer => UserSerializer
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
tests UserTestController
|
29
|
+
|
30
|
+
def test_default_scope_name
|
31
|
+
get :render_new_user
|
32
|
+
assert_equal '{"user":{"admin":false}}', @response.body
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class SerializationScopeNameTest < ActionController::TestCase
|
37
|
+
TestUser = Struct.new(:name, :admin)
|
38
|
+
|
39
|
+
class AdminUserSerializer < ActiveModel::Serializer
|
40
|
+
attributes :admin?
|
41
|
+
def admin?
|
42
|
+
current_admin.admin
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class AdminUserTestController < ActionController::Base
|
47
|
+
protect_from_forgery
|
48
|
+
|
49
|
+
serialization_scope :current_admin
|
50
|
+
before_filter { request.format = :json }
|
51
|
+
|
52
|
+
def current_admin
|
53
|
+
TestUser.new('Bob', true)
|
54
|
+
end
|
55
|
+
|
56
|
+
def render_new_user
|
57
|
+
render :json => TestUser.new('pete', false), :serializer => AdminUserSerializer
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
tests AdminUserTestController
|
62
|
+
|
63
|
+
def test_override_scope_name_with_controller
|
64
|
+
get :render_new_user
|
65
|
+
assert_equal '{"admin_user":{"admin":true}}', @response.body
|
66
|
+
end
|
67
|
+
end
|
data/test/serialization_test.rb
CHANGED
@@ -378,7 +378,7 @@ class RenderJsonTest < ActionController::TestCase
|
|
378
378
|
assert_equal '{"awesome":[]}', @response.body
|
379
379
|
end
|
380
380
|
|
381
|
-
def
|
381
|
+
def test_render_json_empty_array_with_array_serializer_root_false
|
382
382
|
ActiveModel::ArraySerializer.root = false
|
383
383
|
get :render_json_empty_array
|
384
384
|
assert_equal '[]', @response.body
|
@@ -20,6 +20,11 @@ module ActiveRecord
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
+
module Mongoid
|
24
|
+
class Criteria
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
23
28
|
class SerializerSupportTest < ActiveModel::TestCase
|
24
29
|
test "it returns nil if no serializer exists" do
|
25
30
|
assert_equal nil, RandomModel.new.active_model_serializer
|
@@ -37,5 +42,10 @@ class SerializerSupportTest < ActiveModel::TestCase
|
|
37
42
|
ActiveSupport.run_load_hooks(:active_record)
|
38
43
|
assert_equal ActiveModel::ArraySerializer, ActiveRecord::Relation.new.active_model_serializer
|
39
44
|
end
|
45
|
+
|
46
|
+
test "it automatically includes array_serializer in mongoid/criteria" do
|
47
|
+
ActiveSupport.run_load_hooks(:mongoid)
|
48
|
+
assert_equal ActiveModel::ArraySerializer, Mongoid::Criteria.new.active_model_serializer
|
49
|
+
end
|
40
50
|
end
|
41
51
|
|
data/test/serializer_test.rb
CHANGED
@@ -51,6 +51,17 @@ class SerializerTest < ActiveModel::TestCase
|
|
51
51
|
}, hash)
|
52
52
|
end
|
53
53
|
|
54
|
+
def test_attributes_method_with_unsymbolizable_key
|
55
|
+
user = User.new
|
56
|
+
user_serializer = UserAttributesWithUnsymbolizableKeySerializer.new(user, :scope => {})
|
57
|
+
|
58
|
+
hash = user_serializer.as_json
|
59
|
+
|
60
|
+
assert_equal({
|
61
|
+
:user_attributes_with_unsymbolizable_key => { :first_name => "Jose", :"last-name" => "Valim", :ok => true }
|
62
|
+
}, hash)
|
63
|
+
end
|
64
|
+
|
54
65
|
def test_attribute_method_with_name_as_serializer_prefix
|
55
66
|
object = SomeObject.new("something")
|
56
67
|
object_serializer = SomeSerializer.new(object, {})
|
@@ -318,6 +329,16 @@ class SerializerTest < ActiveModel::TestCase
|
|
318
329
|
assert_equal({ :author => nil }, serializer.new(blog, :scope => user).as_json)
|
319
330
|
end
|
320
331
|
|
332
|
+
def test_true_root
|
333
|
+
blog = Blog.new
|
334
|
+
|
335
|
+
assert_equal({
|
336
|
+
:blog_with_root => {
|
337
|
+
:author => nil,
|
338
|
+
}
|
339
|
+
}, BlogWithRootSerializer.new(blog).as_json)
|
340
|
+
end
|
341
|
+
|
321
342
|
def test_root_false_on_load_active_model_serializers
|
322
343
|
begin
|
323
344
|
ActiveSupport.on_load(:active_model_serializers) do
|
@@ -406,6 +427,33 @@ class SerializerTest < ActiveModel::TestCase
|
|
406
427
|
}, serializer.as_json)
|
407
428
|
end
|
408
429
|
|
430
|
+
def test_methods_take_priority_over_associations
|
431
|
+
post_serializer = Class.new(ActiveModel::Serializer) do
|
432
|
+
attributes :title
|
433
|
+
has_many :comments
|
434
|
+
embed :ids
|
435
|
+
|
436
|
+
def comments
|
437
|
+
object.comments[0,1]
|
438
|
+
end
|
439
|
+
end
|
440
|
+
|
441
|
+
post = Post.new(:title => "My Post")
|
442
|
+
comments = [Comment.new(:title => "Comment1", :id => 1), Comment.new(:title => "Comment2", :id => 2)]
|
443
|
+
post.comments = comments
|
444
|
+
|
445
|
+
post.class_eval do
|
446
|
+
define_method :comment_ids, lambda {
|
447
|
+
self.comments.map { |c| c.read_attribute_for_serialization(:id) }
|
448
|
+
}
|
449
|
+
end
|
450
|
+
json = post_serializer.new(post).as_json
|
451
|
+
assert_equal({
|
452
|
+
:title => "My Post",
|
453
|
+
:comment_ids => [1]
|
454
|
+
}, json)
|
455
|
+
end
|
456
|
+
|
409
457
|
def test_embed_objects
|
410
458
|
serializer = post_serializer
|
411
459
|
|
@@ -563,16 +611,17 @@ class SerializerTest < ActiveModel::TestCase
|
|
563
611
|
|
564
612
|
# Computed attributes (not real columns or associations).
|
565
613
|
def can_edit; end
|
614
|
+
def can_view; end
|
566
615
|
def drafts; end
|
567
616
|
|
568
|
-
attributes :name, :age, :can_edit
|
617
|
+
attributes :name, :age, {:can_edit => :boolean}, :can_view
|
569
618
|
has_many :posts, :serializer => Class.new
|
570
619
|
has_many :drafts, :serializer => Class.new
|
571
620
|
has_one :parent, :serializer => Class.new
|
572
621
|
end
|
573
622
|
|
574
623
|
assert_equal serializer.schema, {
|
575
|
-
:attributes => { :name => :string, :age => :integer, :can_edit => nil },
|
624
|
+
:attributes => { :name => :string, :age => :integer, :can_edit => :boolean, :can_view => nil },
|
576
625
|
:associations => {
|
577
626
|
:posts => { :has_many => :posts },
|
578
627
|
:drafts => nil,
|
@@ -1076,7 +1125,7 @@ class SerializerTest < ActiveModel::TestCase
|
|
1076
1125
|
:name => 'logo.png',
|
1077
1126
|
:url => 'http://example.com/logo.png',
|
1078
1127
|
:attachable => {
|
1079
|
-
:type => :email,
|
1128
|
+
:type => :email,
|
1080
1129
|
:id => 1
|
1081
1130
|
}},
|
1082
1131
|
:emails => [{
|
@@ -1310,4 +1359,94 @@ class SerializerTest < ActiveModel::TestCase
|
|
1310
1359
|
]
|
1311
1360
|
}, actual)
|
1312
1361
|
end
|
1362
|
+
|
1363
|
+
def test_inheritance_does_not_used_cached_attributes
|
1364
|
+
parent = Class.new(ActiveModel::Serializer) do
|
1365
|
+
attributes :title
|
1366
|
+
end
|
1367
|
+
|
1368
|
+
child = Class.new(parent) do
|
1369
|
+
attributes :body
|
1370
|
+
end
|
1371
|
+
|
1372
|
+
data_class = Class.new do
|
1373
|
+
attr_accessor :title, :body
|
1374
|
+
end
|
1375
|
+
|
1376
|
+
item = data_class.new
|
1377
|
+
item.title = "title"
|
1378
|
+
item.body = "body"
|
1379
|
+
|
1380
|
+
2.times do
|
1381
|
+
assert_equal({:title => "title"},
|
1382
|
+
parent.new(item).attributes)
|
1383
|
+
assert_equal({:body => "body", :title => "title"},
|
1384
|
+
child.new(item).attributes)
|
1385
|
+
end
|
1386
|
+
|
1387
|
+
end
|
1388
|
+
|
1389
|
+
def test_scope_name_method
|
1390
|
+
serializer = Class.new(ActiveModel::Serializer) do
|
1391
|
+
def has_permission?
|
1392
|
+
current_user.super_user?
|
1393
|
+
end
|
1394
|
+
end
|
1395
|
+
|
1396
|
+
user = User.new
|
1397
|
+
user.superuser = true
|
1398
|
+
post = Post.new(:title => 'Foo')
|
1399
|
+
|
1400
|
+
a_serializer = serializer.new(post, :scope => user, :scope_name => :current_user)
|
1401
|
+
assert a_serializer.has_permission?
|
1402
|
+
end
|
1403
|
+
|
1404
|
+
def test_only_option_filters_attributes_and_associations
|
1405
|
+
post = Post.new(:title => "New Post", :body => "Body of new post")
|
1406
|
+
comments = [Comment.new(:title => "Comment1")]
|
1407
|
+
post.comments = comments
|
1408
|
+
|
1409
|
+
post_serializer = PostSerializer.new(post, :only => :title)
|
1410
|
+
|
1411
|
+
assert_equal({
|
1412
|
+
:post => {
|
1413
|
+
:title => "New Post"
|
1414
|
+
}
|
1415
|
+
}, post_serializer.as_json)
|
1416
|
+
end
|
1417
|
+
|
1418
|
+
def test_except_option_filters_attributes_and_associations
|
1419
|
+
post = Post.new(:title => "New Post", :body => "Body of new post")
|
1420
|
+
comments = [Comment.new(:title => "Comment1")]
|
1421
|
+
post.comments = comments
|
1422
|
+
|
1423
|
+
post_serializer = PostSerializer.new(post, :except => [:body, :comments])
|
1424
|
+
|
1425
|
+
assert_equal({
|
1426
|
+
:post => {
|
1427
|
+
:title => "New Post"
|
1428
|
+
}
|
1429
|
+
}, post_serializer.as_json)
|
1430
|
+
end
|
1431
|
+
|
1432
|
+
def test_only_option_takes_precedence_over_custom_defined_include_methods
|
1433
|
+
user = User.new
|
1434
|
+
|
1435
|
+
post = Post.new(:title => "New Post", :body => "Body of new post", :author => "Sausage King")
|
1436
|
+
comments = [Comment.new(:title => "Comment")]
|
1437
|
+
post.comments = comments
|
1438
|
+
|
1439
|
+
post_serializer = PostWithMultipleConditionalsSerializer.new(post, :scope => user, :only => :title)
|
1440
|
+
|
1441
|
+
# comments enabled
|
1442
|
+
post.comments_disabled = false
|
1443
|
+
# superuser - should see author
|
1444
|
+
user.superuser = true
|
1445
|
+
|
1446
|
+
assert_equal({
|
1447
|
+
:post => {
|
1448
|
+
:title => "New Post"
|
1449
|
+
}
|
1450
|
+
}, post_serializer.as_json)
|
1451
|
+
end
|
1313
1452
|
end
|
data/test/test_fakes.rb
CHANGED
@@ -70,6 +70,14 @@ class UserAttributesWithSomeKeySerializer < ActiveModel::Serializer
|
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
|
+
class UserAttributesWithUnsymbolizableKeySerializer < ActiveModel::Serializer
|
74
|
+
attributes :first_name, :last_name => :"last-name"
|
75
|
+
|
76
|
+
def serializable_hash
|
77
|
+
attributes.merge(:ok => true).merge(options[:scope])
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
73
81
|
class DefaultUserSerializer < ActiveModel::Serializer
|
74
82
|
attributes :first_name, :last_name
|
75
83
|
end
|
@@ -146,6 +154,10 @@ class BlogSerializer < ActiveModel::Serializer
|
|
146
154
|
has_one :author, :serializer => AuthorSerializer
|
147
155
|
end
|
148
156
|
|
157
|
+
class BlogWithRootSerializer < BlogSerializer
|
158
|
+
root true
|
159
|
+
end
|
160
|
+
|
149
161
|
class CustomPostSerializer < ActiveModel::Serializer
|
150
162
|
attributes :title
|
151
163
|
end
|