tint 0.0.5.pre1 → 0.0.5
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/.rspec +1 -0
- data/Guardfile +29 -0
- data/lib/tint/decorator.rb +42 -24
- data/lib/tint/json_conversion.rb +10 -1
- data/lib/tint/version.rb +1 -1
- data/spec/tint/decorator_spec.rb +14 -29
- data/tint.gemspec +4 -1
- metadata +35 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0043f48824279d1625572d74b4bd9f9e7c504a4
|
4
|
+
data.tar.gz: c42e86959edfd7411dba82f08736cb2b0faed36d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a1d114c2f5254e27c25c41f410a9dd8d3c03b39c75d831acf6765f984a95dceadecdf8048c3f0778fbdf28585e31b67fe240ef46e40c73b3c0dff4a2038e427c
|
7
|
+
data.tar.gz: d47802117dbf5598db469fa102cf67ee3392909b73cdd7f47948e91ab5af67b54cef53d5839fb9acb3c0712dbc914fc7beb8b0f804c1861666ce82144ffbc26c
|
data/.rspec
CHANGED
data/Guardfile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
guard :rspec, cmd: "bundle exec rspec" do
|
2
|
+
require "guard/rspec/dsl"
|
3
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
4
|
+
|
5
|
+
last_run_spec = nil
|
6
|
+
|
7
|
+
watch(%r{^lib/(.+)\.rb$}) do |match|
|
8
|
+
file_path =
|
9
|
+
if match[1] === 'lib'
|
10
|
+
"spec/lib/#{match[2]}_spec.rb"
|
11
|
+
else
|
12
|
+
"spec/#{match[2]}_spec.rb"
|
13
|
+
end
|
14
|
+
|
15
|
+
if File.exists?(file_path)
|
16
|
+
file_path
|
17
|
+
else
|
18
|
+
last_run_spec
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# RSpec files
|
23
|
+
rspec = dsl.rspec
|
24
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
25
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
26
|
+
watch(rspec.spec_files) do |spec|
|
27
|
+
last_run_spec = spec[0]
|
28
|
+
end
|
29
|
+
end
|
data/lib/tint/decorator.rb
CHANGED
@@ -8,9 +8,11 @@ module Tint
|
|
8
8
|
class Decorator < Draper::Decorator
|
9
9
|
include JsonConversion
|
10
10
|
|
11
|
+
attr_accessor :object_attributes
|
12
|
+
|
11
13
|
def initialize(object, options = {})
|
12
14
|
super(object, options.except(:parent_decorator, :parent_association))
|
13
|
-
|
15
|
+
@object_attributes = {}
|
14
16
|
@context = @context.merge(options.slice(:parent_decorator, :parent_association))
|
15
17
|
end
|
16
18
|
|
@@ -23,26 +25,20 @@ module Tint
|
|
23
25
|
end
|
24
26
|
|
25
27
|
class << self
|
26
|
-
attr_accessor :_attributes, :parent_decorator, :parent_association
|
28
|
+
attr_accessor :_attributes, :_override_methods, :parent_decorator, :parent_association
|
27
29
|
|
28
30
|
def eager_loads
|
29
|
-
{}
|
31
|
+
@_eager_loads ||= {}
|
30
32
|
end
|
31
33
|
|
32
34
|
def eager_loads=(value)
|
33
|
-
|
34
|
-
remove_possible_method(:eager_loads)
|
35
|
-
|
36
|
-
define_method(:eager_loads){
|
37
|
-
value
|
38
|
-
}
|
39
|
-
end
|
35
|
+
@_eager_loads = value
|
40
36
|
end
|
41
37
|
|
42
38
|
def attributes(*options)
|
43
39
|
@_attributes ||= Set.new
|
44
40
|
|
45
|
-
return
|
41
|
+
return if options.blank?
|
46
42
|
|
47
43
|
mapped_attrs = options.extract_options!
|
48
44
|
|
@@ -102,6 +98,20 @@ module Tint
|
|
102
98
|
def decorate(object, options = {})
|
103
99
|
object_class = object.class
|
104
100
|
|
101
|
+
_object_attributes =
|
102
|
+
if object.present? && object.respond_to?(:attributes)
|
103
|
+
object.attributes
|
104
|
+
else
|
105
|
+
{}
|
106
|
+
end
|
107
|
+
|
108
|
+
@object_attributes =
|
109
|
+
if _object_attributes && _object_attributes.kind_of?(Hash)
|
110
|
+
_object_attributes
|
111
|
+
else
|
112
|
+
{}
|
113
|
+
end
|
114
|
+
|
105
115
|
unless already_eager_loaded_associations?(object)
|
106
116
|
object =
|
107
117
|
if responds_to_methods?(object_class, :includes, :find) && eager_loads.present?
|
@@ -115,11 +125,16 @@ module Tint
|
|
115
125
|
end
|
116
126
|
|
117
127
|
def parent_eager_loads_include_own?(context = {})
|
128
|
+
|
118
129
|
if context && context[:parent_decorator]
|
119
130
|
if (parent_eager_loads = context[:parent_decorator].class.eager_loads)
|
120
|
-
|
121
|
-
|
122
|
-
|
131
|
+
|
132
|
+
association_eager_load =
|
133
|
+
context[:parent_association].inject(parent_eager_loads) do |memo, chain_link|
|
134
|
+
memo[chain_link] if memo
|
135
|
+
end
|
136
|
+
|
137
|
+
!!association_eager_load
|
123
138
|
end
|
124
139
|
else
|
125
140
|
false
|
@@ -143,27 +158,30 @@ module Tint
|
|
143
158
|
end
|
144
159
|
|
145
160
|
def link_delegations_to_object(delegated_attrs)
|
161
|
+
@_override_methods ||= {}
|
162
|
+
|
146
163
|
delegated_attrs.each do |delegate_method|
|
147
164
|
@_attributes.add(delegate_method)
|
148
165
|
|
149
|
-
|
166
|
+
if method_defined?(delegate_method)
|
167
|
+
@_override_methods[delegate_method] = true
|
168
|
+
else
|
150
169
|
define_method(delegate_method) do
|
151
|
-
|
152
|
-
object.send(delegate_method)
|
153
|
-
end
|
170
|
+
object.try(delegate_method)
|
154
171
|
end
|
155
172
|
end
|
156
173
|
end
|
157
174
|
end
|
158
175
|
|
159
176
|
def link_mappings_to_object(mapped_attrs)
|
177
|
+
@_override_methods ||= {}
|
178
|
+
|
160
179
|
mapped_attrs.each do |decorator_attribute, object_method|
|
161
180
|
@_attributes.add(decorator_attribute)
|
181
|
+
@_override_methods[decorator_attribute] = true
|
162
182
|
|
163
183
|
define_method(decorator_attribute) do
|
164
|
-
|
165
|
-
object.send(object_method)
|
166
|
-
end
|
184
|
+
@object_attributes[object_method.to_s] || object.try(object_method)
|
167
185
|
end
|
168
186
|
end
|
169
187
|
end
|
@@ -188,9 +206,9 @@ module Tint
|
|
188
206
|
def define_association_method(association_alias, association_chain, options)
|
189
207
|
define_method(association_alias) do
|
190
208
|
context_with_association = context.merge({
|
191
|
-
|
192
|
-
|
193
|
-
|
209
|
+
parent_decorator: self,
|
210
|
+
parent_association: association_chain
|
211
|
+
})
|
194
212
|
|
195
213
|
decorated_associations[association_alias] ||= Tint::DecoratedAssociation.new(
|
196
214
|
self,
|
data/lib/tint/json_conversion.rb
CHANGED
@@ -46,6 +46,7 @@ module Tint
|
|
46
46
|
|
47
47
|
def attributes_for_json
|
48
48
|
attribute_list = self.class._attributes
|
49
|
+
override_methods = self.class._override_methods
|
49
50
|
|
50
51
|
return {} if attribute_list.blank?
|
51
52
|
|
@@ -61,10 +62,18 @@ module Tint
|
|
61
62
|
AttributeNameStrategy::Stringify
|
62
63
|
end
|
63
64
|
|
65
|
+
|
64
66
|
attribute_list.inject({}) do |memo, key_and_value|
|
65
67
|
key, _ = key_and_value
|
66
68
|
|
67
|
-
|
69
|
+
value =
|
70
|
+
if override_methods[key]
|
71
|
+
self.send(key)
|
72
|
+
else
|
73
|
+
self.object_attributes[key.to_s] || self.send(key)
|
74
|
+
end
|
75
|
+
|
76
|
+
unless value.nil?
|
68
77
|
memo[strategy.transform(key)] = value.respond_to?(:as_json) ? value.as_json : value
|
69
78
|
end
|
70
79
|
|
data/lib/tint/version.rb
CHANGED
data/spec/tint/decorator_spec.rb
CHANGED
@@ -194,9 +194,9 @@ RSpec.describe Tint::Decorator do
|
|
194
194
|
|
195
195
|
eager_load_schemas = [
|
196
196
|
[:associated],
|
197
|
-
[ { associated1:
|
198
|
-
[ { associated1: { associated2:
|
199
|
-
[ :associated1, { associated2:
|
197
|
+
[ { associated1: { associated2: {} } } ],
|
198
|
+
[ { associated1: { associated2: { associated3: {} } } } ],
|
199
|
+
[ :associated1, { associated2: { associated3: {} } } ]
|
200
200
|
]
|
201
201
|
|
202
202
|
eager_load_schemas.each do |eager_load_schema|
|
@@ -241,33 +241,13 @@ RSpec.describe Tint::Decorator do
|
|
241
241
|
it "returns true" do
|
242
242
|
context = {
|
243
243
|
parent_decorator: parent_decorator_class.decorate(object_class),
|
244
|
-
parent_association: :associated
|
244
|
+
parent_association: [:associated]
|
245
245
|
}
|
246
246
|
|
247
247
|
expect(decorator_class.parent_eager_loads_include_own?(context)).to eql(true)
|
248
248
|
end
|
249
249
|
end
|
250
250
|
|
251
|
-
context "when a decorator has a parent set via #decorate_association" do
|
252
|
-
let(:parent_decorator_class) do
|
253
|
-
Class.new(Tint::Decorator) do
|
254
|
-
attributes :associated
|
255
|
-
|
256
|
-
def associated
|
257
|
-
decorate_as_association(:association, object, with: AssociatedDecorator)
|
258
|
-
end
|
259
|
-
|
260
|
-
end
|
261
|
-
end
|
262
|
-
|
263
|
-
it "returns true" do
|
264
|
-
decorated_class = parent_decorator_class.decorate(object_class.new('foo', 'bar'))
|
265
|
-
|
266
|
-
context = decorated_class.send(:associated).context
|
267
|
-
expect(decorator_class.parent_eager_loads_include_own?(context)).to eql(true)
|
268
|
-
end
|
269
|
-
end
|
270
|
-
|
271
251
|
context "when a decorator has a parent manually set" do
|
272
252
|
context "and the parent doesn't manually eager load the association" do
|
273
253
|
let(:parent_decorator_class) do
|
@@ -277,7 +257,7 @@ RSpec.describe Tint::Decorator do
|
|
277
257
|
def associated
|
278
258
|
AssociatedDecorator.decorate(object, context: {
|
279
259
|
parent_decorator: self,
|
280
|
-
parent_association: :associated
|
260
|
+
parent_association: [:associated]
|
281
261
|
})
|
282
262
|
end
|
283
263
|
|
@@ -301,9 +281,9 @@ RSpec.describe Tint::Decorator do
|
|
301
281
|
eager_load :associated
|
302
282
|
|
303
283
|
def associated
|
304
|
-
AssociatedDecorator.decorate(object, context: {
|
284
|
+
AssociatedDecorator.decorate(object.attr1, context: {
|
305
285
|
parent_decorator: self,
|
306
|
-
parent_association: :associated
|
286
|
+
parent_association: [:associated]
|
307
287
|
})
|
308
288
|
end
|
309
289
|
|
@@ -312,9 +292,14 @@ RSpec.describe Tint::Decorator do
|
|
312
292
|
end
|
313
293
|
|
314
294
|
it "returns true" do
|
315
|
-
|
295
|
+
associated_object = object_class.new('foo', 'bar')
|
296
|
+
|
297
|
+
decorated_class = parent_decorator_class.decorate(
|
298
|
+
object_class.new(associated_object, 'bar')
|
299
|
+
)
|
300
|
+
|
301
|
+
context = decorated_class.associated.context
|
316
302
|
|
317
|
-
context = decorated_class.send(:associated).context
|
318
303
|
expect(decorator_class.parent_eager_loads_include_own?(context)).to eql(true)
|
319
304
|
end
|
320
305
|
end
|
data/tint.gemspec
CHANGED
@@ -20,7 +20,10 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.add_dependency "draper", "~> 2.1"
|
22
22
|
spec.add_dependency "deep_merge", "~> 1.0"
|
23
|
+
|
23
24
|
spec.add_development_dependency "bundler", "~> 1.6"
|
24
25
|
spec.add_development_dependency "rake", "~> 0"
|
25
|
-
spec.add_development_dependency "
|
26
|
+
spec.add_development_dependency "guard", "~> 2.1"
|
27
|
+
spec.add_development_dependency "rspec", ">= 3.5.0"
|
28
|
+
spec.add_development_dependency "guard-rspec", "~> 4.7"
|
26
29
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tint
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.5
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aleck Greenham
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-03-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: draper
|
@@ -66,20 +66,48 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: guard
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2.1'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '2.1'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 3.5.0
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 3.5.0
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: guard-rspec
|
71
99
|
requirement: !ruby/object:Gem::Requirement
|
72
100
|
requirements:
|
73
101
|
- - "~>"
|
74
102
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
103
|
+
version: '4.7'
|
76
104
|
type: :development
|
77
105
|
prerelease: false
|
78
106
|
version_requirements: !ruby/object:Gem::Requirement
|
79
107
|
requirements:
|
80
108
|
- - "~>"
|
81
109
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
110
|
+
version: '4.7'
|
83
111
|
description: Easily define object decorators for JSON APIs using simple declarative
|
84
112
|
syntax
|
85
113
|
email:
|
@@ -91,6 +119,7 @@ files:
|
|
91
119
|
- ".gitignore"
|
92
120
|
- ".rspec"
|
93
121
|
- Gemfile
|
122
|
+
- Guardfile
|
94
123
|
- LICENSE.txt
|
95
124
|
- README.md
|
96
125
|
- Rakefile
|
@@ -118,9 +147,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
118
147
|
version: '0'
|
119
148
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
149
|
requirements:
|
121
|
-
- - "
|
150
|
+
- - ">="
|
122
151
|
- !ruby/object:Gem::Version
|
123
|
-
version:
|
152
|
+
version: '0'
|
124
153
|
requirements: []
|
125
154
|
rubyforge_project:
|
126
155
|
rubygems_version: 2.2.2
|