Skip to content

Commit 28174e2

Browse files
committed
Add linter for serializable resource
1 parent 952d8ad commit 28174e2

File tree

3 files changed

+162
-0
lines changed

3 files changed

+162
-0
lines changed

lib/active_model/serializer.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ class Serializer
66
autoload :Configuration
77
autoload :ArraySerializer
88
autoload :Adapter
9+
autoload :Lint
910
include Configuration
1011

1112
class << self

lib/active_model/serializer/lint.rb

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
module ActiveModel::Serializer::Lint
2+
# == Active \Model \Serializer \Lint \Tests
3+
#
4+
# You can test whether an object is compliant with the Active \Model \Serializers
5+
# API by including <tt>ActiveModel::Serializer::Lint::Tests</tt> in your TestCase.
6+
# It will include tests that tell you whether your object is fully compliant,
7+
# or if not, which aspects of the API are not implemented.
8+
#
9+
# Note an object is not required to implement all APIs in order to work
10+
# with Active \Model \Serializers. This module only intends to provide guidance in case
11+
# you want all features out of the box.
12+
#
13+
# These tests do not attempt to determine the semantic correctness of the
14+
# returned values. For instance, you could implement <tt>serializable_hash</tt> to
15+
# always return +{}+, and the tests would pass. It is up to you to ensure
16+
# that the values are semantically meaningful.
17+
module Tests
18+
19+
# Passes if the object responds to <tt>serializable_hash</tt> and if it takes
20+
# zero or one arguments.
21+
# Fails otherwise.
22+
#
23+
# <tt>serializable_hash</tt> returns a hash representation of a object's attributes.
24+
# Typically, it is implemented by including ActiveModel::Serialization.
25+
def test_serializable_hash
26+
assert_respond_to resource, :serializable_hash, "The resource should respond to serializable_hash"
27+
resource.serializable_hash
28+
resource.serializable_hash(nil)
29+
end
30+
31+
# Passes if the object responds to <tt>read_attribute_for_serialization</tt>
32+
# and if it requires one argument (the attribute to be read).
33+
# Fails otherwise.
34+
#
35+
# <tt>read_attribute_for_serialization</tt> gets the attribute value for serialization
36+
# Typically, it is implemented by including ActiveModel::Serialization.
37+
def test_read_attribute_for_serialization
38+
assert_respond_to resource, :read_attribute_for_serialization, "The resource should respond to read_attribute_for_serialization"
39+
assert_equal resource.method(:read_attribute_for_serialization).arity, 1
40+
end
41+
42+
# Passes if the object responds to <tt>as_json</tt> and if it takes
43+
# zero or one arguments.
44+
# Fails otherwise.
45+
#
46+
# <tt>as_json</tt> returns a hash representation of a serialized object.
47+
# It may delegate to <tt>serializable_hash</tt>
48+
# Typically, it is implemented either by including ActiveModel::Serialization
49+
# which includes ActiveModel::Serializers::JSON.
50+
# or by the JSON gem when required.
51+
def test_as_json
52+
assert_respond_to resource, :as_json
53+
resource.as_json
54+
resource.as_json(nil)
55+
end
56+
57+
# Passes if the object responds to <tt>to_json</tt> and if it takes
58+
# zero or one arguments.
59+
# Fails otherwise.
60+
#
61+
# <tt>to_json</tt> returns a string representation (JSON) of a serialized object.
62+
# It may be called on the result of <tt>as_json</tt>.
63+
# Typically, it is implemented on all objects when the JSON gem is required.
64+
def test_to_json
65+
assert_respond_to resource, :to_json
66+
resource.to_json
67+
resource.to_json(nil)
68+
end
69+
70+
# Passes if the object responds to <tt>cache_key</tt> and if it takes no
71+
# arguments.
72+
# Fails otherwise.
73+
#
74+
# <tt>cache_key</tt> returns a (self-expiring) unique key for the object,
75+
# which is used by the adapter.
76+
# It is not required unless caching is enabled.
77+
def test_cache_key
78+
assert_respond_to resource, :cache_key
79+
assert_equal resource.method(:cache_key).arity, 0
80+
end
81+
82+
# Passes if the object responds to <tt>id</tt> and if it takes no
83+
# arguments.
84+
# Fails otherwise.
85+
#
86+
# <tt>id</tt> returns a unique identifier for the object.
87+
# It is not required unless caching is enabled.
88+
def test_id
89+
assert_respond_to resource, :id
90+
assert_equal resource.method(:id).arity, 0
91+
end
92+
93+
# Passes if the object's class responds to <tt>model_name</tt> and if it
94+
# is in an instance of +ActiveModel::Name+.
95+
# Fails otherwise.
96+
#
97+
# <tt>model_name</tt> returns an ActiveModel::Name instance.
98+
# It is used by the serializer to identify the object's type.
99+
# It is not required unless caching is enabled.
100+
def test_model_name
101+
resource_class = resource.class
102+
assert_respond_to resource_class, :model_name
103+
assert_instance_of resource_class.model_name, ActiveModel::Name
104+
end
105+
106+
private
107+
108+
def resource
109+
@resource
110+
end
111+
112+
def assert_instance_of(result, name)
113+
assert result.instance_of?(name), "#{result} should be an instance of #{name}"
114+
end
115+
116+
end
117+
end

test/lint_test.rb

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
require 'test_helper'
2+
3+
module ActiveModel
4+
class Serializer
5+
class LintTest < Minitest::Test
6+
include ActiveModel::Serializer::Lint::Tests
7+
8+
class CompliantResource
9+
def serializable_hash(options = nil)
10+
11+
end
12+
13+
def read_attribute_for_serialization(name)
14+
15+
end
16+
17+
def as_json(options = nil)
18+
19+
end
20+
21+
def to_json(options = nil)
22+
23+
end
24+
25+
def cache_key
26+
27+
end
28+
29+
def id
30+
31+
end
32+
33+
def self.model_name
34+
@_model_name ||= ActiveModel::Name.new(self)
35+
end
36+
end
37+
38+
def setup
39+
@resource = CompliantResource.new
40+
end
41+
42+
end
43+
end
44+
end

0 commit comments

Comments
 (0)