dekorator 1.0.0.pre.1
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 +7 -0
- data/.editorconfig +14 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.rubocop.yml +114 -0
- data/.simplecov +5 -0
- data/.travis.yml +37 -0
- data/Appraisals +17 -0
- data/CHANGELOG.md +16 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +22 -0
- data/Gemfile.lock +157 -0
- data/LICENSE.txt +21 -0
- data/README.md +179 -0
- data/Rakefile +21 -0
- data/bin/console +16 -0
- data/bin/setup +8 -0
- data/dekorator.gemspec +34 -0
- data/gemfiles/.bundle/config +2 -0
- data/gemfiles/rails_5.0.x.gemfile +21 -0
- data/gemfiles/rails_5.0.x.gemfile.lock +207 -0
- data/gemfiles/rails_5.1.x.gemfile +21 -0
- data/gemfiles/rails_5.1.x.gemfile.lock +207 -0
- data/gemfiles/rails_5.2.x.gemfile +21 -0
- data/gemfiles/rails_5.2.x.gemfile.lock +207 -0
- data/gemfiles/rails_6.0.x.gemfile +21 -0
- data/gemfiles/rails_6.0.x.gemfile.lock +220 -0
- data/lib/dekorator.rb +123 -0
- data/lib/dekorator/decorators_helper.rb +5 -0
- data/lib/dekorator/railtie.rb +11 -0
- data/lib/dekorator/rspec.rb +0 -0
- data/lib/dekorator/version.rb +5 -0
- data/lib/generators/decorator/USAGE +9 -0
- data/lib/generators/decorator/decorator_generator.rb +11 -0
- data/lib/generators/decorator/templates/decorator.rb +17 -0
- data/lib/generators/decorator/templates/decorator_test.rb +1 -0
- data/lib/generators/dekorator/install_generator.rb +35 -0
- data/lib/generators/rspec/decorator_generator.rb +13 -0
- data/lib/generators/rspec/templates/decorator_spec.rb +17 -0
- data/lib/generators/test_unit/decorator_generator.rb +13 -0
- data/lib/generators/test_unit/templates/decorator_test.rb +6 -0
- metadata +187 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This file was generated by Appraisal
|
4
|
+
|
5
|
+
source "https://rubygems.org"
|
6
|
+
|
7
|
+
gem "activerecord"
|
8
|
+
gem "activemodel"
|
9
|
+
gem "activesupport"
|
10
|
+
gem "actionview"
|
11
|
+
gem "railties"
|
12
|
+
gem "appraisal", require: false
|
13
|
+
gem "rubocop", require: false
|
14
|
+
gem "rails", "~> 6.0.0.beta1"
|
15
|
+
|
16
|
+
group :test do
|
17
|
+
gem "simplecov", require: false
|
18
|
+
gem "coveralls", require: false
|
19
|
+
end
|
20
|
+
|
21
|
+
gemspec path: "../"
|
@@ -0,0 +1,220 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ..
|
3
|
+
specs:
|
4
|
+
dekorator (1.0.0.pre.1)
|
5
|
+
actionview (>= 5.0, < 6.1)
|
6
|
+
activesupport (>= 5.0, < 6.1)
|
7
|
+
railties (>= 5.0, < 6.1)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
actioncable (6.0.0.beta1)
|
13
|
+
actionpack (= 6.0.0.beta1)
|
14
|
+
nio4r (~> 2.0)
|
15
|
+
websocket-driver (>= 0.6.1)
|
16
|
+
actionmailbox (6.0.0.beta1)
|
17
|
+
actionpack (= 6.0.0.beta1)
|
18
|
+
activejob (= 6.0.0.beta1)
|
19
|
+
activerecord (= 6.0.0.beta1)
|
20
|
+
activestorage (= 6.0.0.beta1)
|
21
|
+
activesupport (= 6.0.0.beta1)
|
22
|
+
mail (>= 2.7.1)
|
23
|
+
actionmailer (6.0.0.beta1)
|
24
|
+
actionpack (= 6.0.0.beta1)
|
25
|
+
actionview (= 6.0.0.beta1)
|
26
|
+
activejob (= 6.0.0.beta1)
|
27
|
+
mail (~> 2.5, >= 2.5.4)
|
28
|
+
rails-dom-testing (~> 2.0)
|
29
|
+
actionpack (6.0.0.beta1)
|
30
|
+
actionview (= 6.0.0.beta1)
|
31
|
+
activesupport (= 6.0.0.beta1)
|
32
|
+
rack (~> 2.0)
|
33
|
+
rack-test (>= 0.6.3)
|
34
|
+
rails-dom-testing (~> 2.0)
|
35
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
36
|
+
actiontext (6.0.0.beta1)
|
37
|
+
actionpack (= 6.0.0.beta1)
|
38
|
+
activerecord (= 6.0.0.beta1)
|
39
|
+
activestorage (= 6.0.0.beta1)
|
40
|
+
activesupport (= 6.0.0.beta1)
|
41
|
+
nokogiri (>= 1.8.5)
|
42
|
+
actionview (6.0.0.beta1)
|
43
|
+
activesupport (= 6.0.0.beta1)
|
44
|
+
builder (~> 3.1)
|
45
|
+
erubi (~> 1.4)
|
46
|
+
rails-dom-testing (~> 2.0)
|
47
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
48
|
+
activejob (6.0.0.beta1)
|
49
|
+
activesupport (= 6.0.0.beta1)
|
50
|
+
globalid (>= 0.3.6)
|
51
|
+
activemodel (6.0.0.beta1)
|
52
|
+
activesupport (= 6.0.0.beta1)
|
53
|
+
activerecord (6.0.0.beta1)
|
54
|
+
activemodel (= 6.0.0.beta1)
|
55
|
+
activesupport (= 6.0.0.beta1)
|
56
|
+
activestorage (6.0.0.beta1)
|
57
|
+
actionpack (= 6.0.0.beta1)
|
58
|
+
activerecord (= 6.0.0.beta1)
|
59
|
+
marcel (~> 0.3.1)
|
60
|
+
activesupport (6.0.0.beta1)
|
61
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
62
|
+
i18n (>= 0.7, < 2)
|
63
|
+
minitest (~> 5.1)
|
64
|
+
tzinfo (~> 1.1)
|
65
|
+
appraisal (2.2.0)
|
66
|
+
bundler
|
67
|
+
rake
|
68
|
+
thor (>= 0.14.0)
|
69
|
+
ast (2.4.0)
|
70
|
+
builder (3.2.3)
|
71
|
+
concurrent-ruby (1.1.4)
|
72
|
+
coveralls (0.7.1)
|
73
|
+
multi_json (~> 1.3)
|
74
|
+
rest-client
|
75
|
+
simplecov (>= 0.7)
|
76
|
+
term-ansicolor
|
77
|
+
thor
|
78
|
+
crass (1.0.4)
|
79
|
+
diff-lcs (1.3)
|
80
|
+
docile (1.3.1)
|
81
|
+
domain_name (0.5.20180417)
|
82
|
+
unf (>= 0.0.5, < 1.0.0)
|
83
|
+
erubi (1.8.0)
|
84
|
+
globalid (0.4.2)
|
85
|
+
activesupport (>= 4.2.0)
|
86
|
+
http-cookie (1.0.3)
|
87
|
+
domain_name (~> 0.5)
|
88
|
+
i18n (1.5.3)
|
89
|
+
concurrent-ruby (~> 1.0)
|
90
|
+
jaro_winkler (1.5.2)
|
91
|
+
json (2.1.0)
|
92
|
+
loofah (2.2.3)
|
93
|
+
crass (~> 1.0.2)
|
94
|
+
nokogiri (>= 1.5.9)
|
95
|
+
mail (2.7.1)
|
96
|
+
mini_mime (>= 0.1.1)
|
97
|
+
marcel (0.3.3)
|
98
|
+
mimemagic (~> 0.3.2)
|
99
|
+
method_source (0.9.2)
|
100
|
+
mime-types (3.2.2)
|
101
|
+
mime-types-data (~> 3.2015)
|
102
|
+
mime-types-data (3.2018.0812)
|
103
|
+
mimemagic (0.3.3)
|
104
|
+
mini_mime (1.0.1)
|
105
|
+
mini_portile2 (2.4.0)
|
106
|
+
minitest (5.11.3)
|
107
|
+
multi_json (1.13.1)
|
108
|
+
netrc (0.11.0)
|
109
|
+
nio4r (2.3.1)
|
110
|
+
nokogiri (1.10.1)
|
111
|
+
mini_portile2 (~> 2.4.0)
|
112
|
+
parallel (1.13.0)
|
113
|
+
parser (2.6.0.0)
|
114
|
+
ast (~> 2.4.0)
|
115
|
+
powerpack (0.1.2)
|
116
|
+
rack (2.0.6)
|
117
|
+
rack-test (1.1.0)
|
118
|
+
rack (>= 1.0, < 3)
|
119
|
+
rails (6.0.0.beta1)
|
120
|
+
actioncable (= 6.0.0.beta1)
|
121
|
+
actionmailbox (= 6.0.0.beta1)
|
122
|
+
actionmailer (= 6.0.0.beta1)
|
123
|
+
actionpack (= 6.0.0.beta1)
|
124
|
+
actiontext (= 6.0.0.beta1)
|
125
|
+
actionview (= 6.0.0.beta1)
|
126
|
+
activejob (= 6.0.0.beta1)
|
127
|
+
activemodel (= 6.0.0.beta1)
|
128
|
+
activerecord (= 6.0.0.beta1)
|
129
|
+
activestorage (= 6.0.0.beta1)
|
130
|
+
activesupport (= 6.0.0.beta1)
|
131
|
+
bundler (>= 1.3.0)
|
132
|
+
railties (= 6.0.0.beta1)
|
133
|
+
sprockets-rails (>= 2.0.0)
|
134
|
+
rails-dom-testing (2.0.3)
|
135
|
+
activesupport (>= 4.2.0)
|
136
|
+
nokogiri (>= 1.6)
|
137
|
+
rails-html-sanitizer (1.0.4)
|
138
|
+
loofah (~> 2.2, >= 2.2.2)
|
139
|
+
railties (6.0.0.beta1)
|
140
|
+
actionpack (= 6.0.0.beta1)
|
141
|
+
activesupport (= 6.0.0.beta1)
|
142
|
+
method_source
|
143
|
+
rake (>= 0.8.7)
|
144
|
+
thor (>= 0.20.3, < 2.0)
|
145
|
+
rainbow (3.0.0)
|
146
|
+
rake (10.5.0)
|
147
|
+
rest-client (2.0.2)
|
148
|
+
http-cookie (>= 1.0.2, < 2.0)
|
149
|
+
mime-types (>= 1.16, < 4.0)
|
150
|
+
netrc (~> 0.8)
|
151
|
+
rspec (3.8.0)
|
152
|
+
rspec-core (~> 3.8.0)
|
153
|
+
rspec-expectations (~> 3.8.0)
|
154
|
+
rspec-mocks (~> 3.8.0)
|
155
|
+
rspec-core (3.8.0)
|
156
|
+
rspec-support (~> 3.8.0)
|
157
|
+
rspec-expectations (3.8.2)
|
158
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
159
|
+
rspec-support (~> 3.8.0)
|
160
|
+
rspec-mocks (3.8.0)
|
161
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
162
|
+
rspec-support (~> 3.8.0)
|
163
|
+
rspec-support (3.8.0)
|
164
|
+
rubocop (0.63.1)
|
165
|
+
jaro_winkler (~> 1.5.1)
|
166
|
+
parallel (~> 1.10)
|
167
|
+
parser (>= 2.5, != 2.5.1.1)
|
168
|
+
powerpack (~> 0.1)
|
169
|
+
rainbow (>= 2.2.2, < 4.0)
|
170
|
+
ruby-progressbar (~> 1.7)
|
171
|
+
unicode-display_width (~> 1.4.0)
|
172
|
+
ruby-progressbar (1.10.0)
|
173
|
+
simplecov (0.16.1)
|
174
|
+
docile (~> 1.1)
|
175
|
+
json (>= 1.8, < 3)
|
176
|
+
simplecov-html (~> 0.10.0)
|
177
|
+
simplecov-html (0.10.2)
|
178
|
+
sprockets (3.7.2)
|
179
|
+
concurrent-ruby (~> 1.0)
|
180
|
+
rack (> 1, < 3)
|
181
|
+
sprockets-rails (3.2.1)
|
182
|
+
actionpack (>= 4.0)
|
183
|
+
activesupport (>= 4.0)
|
184
|
+
sprockets (>= 3.0.0)
|
185
|
+
term-ansicolor (1.7.1)
|
186
|
+
tins (~> 1.0)
|
187
|
+
thor (0.20.3)
|
188
|
+
thread_safe (0.3.6)
|
189
|
+
tins (1.20.2)
|
190
|
+
tzinfo (1.2.5)
|
191
|
+
thread_safe (~> 0.1)
|
192
|
+
unf (0.1.4)
|
193
|
+
unf_ext
|
194
|
+
unf_ext (0.0.7.5)
|
195
|
+
unicode-display_width (1.4.1)
|
196
|
+
websocket-driver (0.7.0)
|
197
|
+
websocket-extensions (>= 0.1.0)
|
198
|
+
websocket-extensions (0.1.3)
|
199
|
+
|
200
|
+
PLATFORMS
|
201
|
+
ruby
|
202
|
+
|
203
|
+
DEPENDENCIES
|
204
|
+
actionview
|
205
|
+
activemodel
|
206
|
+
activerecord
|
207
|
+
activesupport
|
208
|
+
appraisal
|
209
|
+
bundler (~> 2.0)
|
210
|
+
coveralls
|
211
|
+
dekorator!
|
212
|
+
rails (~> 6.0.0.beta1)
|
213
|
+
railties
|
214
|
+
rake (~> 10.0)
|
215
|
+
rspec (~> 3.0)
|
216
|
+
rubocop
|
217
|
+
simplecov
|
218
|
+
|
219
|
+
BUNDLED WITH
|
220
|
+
2.0.1
|
data/lib/dekorator.rb
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dekorator/version"
|
4
|
+
require "active_support/core_ext/object/blank"
|
5
|
+
require "active_support/core_ext/module/delegation"
|
6
|
+
|
7
|
+
module Dekorator
|
8
|
+
class DecoratorNotFound < ArgumentError; end
|
9
|
+
|
10
|
+
# Base decorator.
|
11
|
+
class Base < SimpleDelegator
|
12
|
+
class << self
|
13
|
+
# Decorate an object with a decorator.
|
14
|
+
#
|
15
|
+
# @param object_or_collection [Object, Enumerable] the object or collection to decorate.
|
16
|
+
# @option opts [Class] :with the decorator class to use. If empty a decorator will be guessed.
|
17
|
+
#
|
18
|
+
# @return [Dekorator::Base, ActiveRecord::Relation, Enumerable] the obect or collection decorated.
|
19
|
+
#
|
20
|
+
# @raise [DecoratorNotFound] if decorator is not found.
|
21
|
+
def decorate(object_or_collection, with: nil)
|
22
|
+
return object_or_collection if object_or_collection.blank?
|
23
|
+
|
24
|
+
with = _guess_decorator(object_or_collection) if with.nil? && object_or_collection.present?
|
25
|
+
|
26
|
+
raise DecoratorNotFound, "Can't guess decorator for #{object_or_collection.class.name} object" if with.nil?
|
27
|
+
|
28
|
+
object_or_collection = _decorate(object_or_collection, with: with)
|
29
|
+
|
30
|
+
if block_given?
|
31
|
+
yield object_or_collection
|
32
|
+
else
|
33
|
+
object_or_collection
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Define that an association must be decorated.
|
38
|
+
#
|
39
|
+
# @param relation_name [String, Symbol] the association name to decorate.
|
40
|
+
# @option opts [Class] :with the decorator class to use. If empty a decorator will be guessed.
|
41
|
+
#
|
42
|
+
# @example Define an association to decorate
|
43
|
+
# class UserDecorator < ApplicationDecorator
|
44
|
+
# decorates_association :posts
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# # A decorator could be precise
|
48
|
+
# class UserDecorator < ApplicationDecorator
|
49
|
+
# decorates_association :posts, PostDecorator
|
50
|
+
# end
|
51
|
+
def decorates_association(relation_name, with: nil)
|
52
|
+
relation_name = relation_name.to_sym
|
53
|
+
|
54
|
+
define_method(relation_name) do
|
55
|
+
association = __getobj__.public_send(relation_name)
|
56
|
+
|
57
|
+
@decorated_associations[relation_name] ||= decorate(association, with: with)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def base_class
|
62
|
+
name.gsub("Decorator", "").safe_constantize
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def _decorate(object_or_enumerable, with: nil)
|
68
|
+
if defined?(ActiveRecord::Relation) && object_or_enumerable.is_a?(ActiveRecord::Relation)
|
69
|
+
DecoratedEnumerableProxy.new(object_or_enumerable, with)
|
70
|
+
elsif object_or_enumerable.is_a? Enumerable
|
71
|
+
object_or_enumerable.map { |object| with.new(object) }
|
72
|
+
else
|
73
|
+
with.new(object_or_enumerable)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def _guess_decorator(object_or_enumerable)
|
78
|
+
object_or_enumerable = object_or_enumerable.first if object_or_enumerable.is_a? Enumerable
|
79
|
+
|
80
|
+
"#{object_or_enumerable.class}Decorator".safe_constantize if object_or_enumerable.present?
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
delegate :decorate, to: :class
|
85
|
+
|
86
|
+
def initialize(object)
|
87
|
+
@decorated_associations = {}
|
88
|
+
|
89
|
+
super(object)
|
90
|
+
end
|
91
|
+
|
92
|
+
def object
|
93
|
+
__getobj__
|
94
|
+
end
|
95
|
+
|
96
|
+
if defined?(ActiveRecord::Relation)
|
97
|
+
class DecoratedEnumerableProxy < DelegateClass(ActiveRecord::Relation)
|
98
|
+
include Enumerable
|
99
|
+
|
100
|
+
delegate :as_json, :collect, :map, :each, :[], :all?, :include?,
|
101
|
+
:first, :last, :shift, to: :decorated_collection
|
102
|
+
delegate :each, to: :to_ary
|
103
|
+
|
104
|
+
def initialize(collection, decorator_class)
|
105
|
+
super(collection)
|
106
|
+
|
107
|
+
@decorator_class = decorator_class
|
108
|
+
end
|
109
|
+
|
110
|
+
def wrapped_collection
|
111
|
+
__getobj__
|
112
|
+
end
|
113
|
+
|
114
|
+
def decorated_collection
|
115
|
+
@decorated_collection ||= wrapped_collection.collect { |member| @decorator_class.decorate(member) }
|
116
|
+
end
|
117
|
+
alias to_ary decorated_collection
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
require "dekorator/railtie" if defined?(Rails)
|
File without changes
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class DecoratorGenerator < Rails::Generators::NamedBase
|
4
|
+
source_root File.expand_path("templates", __dir__)
|
5
|
+
|
6
|
+
def create_decorator
|
7
|
+
template "decorator.rb", File.join("app/decorators", class_path, "#{file_name}_decorator.rb")
|
8
|
+
end
|
9
|
+
|
10
|
+
hook_for :test_framework
|
11
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
<% module_namespacing do -%>
|
4
|
+
class <%= class_name %>Decorator < ApplicationDecorator
|
5
|
+
# include ActionView::Helpers::TextHelper
|
6
|
+
#
|
7
|
+
# decorates_association :posts
|
8
|
+
#
|
9
|
+
# def full_name
|
10
|
+
# [first_name, last_name].join(" ")
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# def biography_summary
|
14
|
+
# truncate(biography, length: 170)
|
15
|
+
# end
|
16
|
+
end
|
17
|
+
<% end -%>
|
@@ -0,0 +1 @@
|
|
1
|
+
# frozen_string_literal: true
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dekorator
|
4
|
+
module Generators
|
5
|
+
class InstallGenerator < Rails::Generators::Base
|
6
|
+
|
7
|
+
def create_root_directory
|
8
|
+
return if File.directory?(dekorator_root_directory)
|
9
|
+
|
10
|
+
empty_directory(dekorator_root_directory)
|
11
|
+
end
|
12
|
+
|
13
|
+
def create_application_decorator
|
14
|
+
return if File.exist?(application_decorator_path)
|
15
|
+
|
16
|
+
create_file application_decorator_path, <<-RUBY
|
17
|
+
# frozen_string_literal: true
|
18
|
+
|
19
|
+
class ApplicationDecorator < Dekorator::Base
|
20
|
+
end
|
21
|
+
RUBY
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
def dekorator_root_directory
|
27
|
+
Rails.root.join("app", "decorators")
|
28
|
+
end
|
29
|
+
|
30
|
+
def application_decorator_path
|
31
|
+
dekorator_root_directory.join("application_decorator.rb")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|