dekorator 1.0.0 → 1.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e632f3f499971f15713b16354a960d3c0c2e42436694a040d5a77c8627baec7a
4
- data.tar.gz: 1318630635b3406f2336d0d144d1651c0b66bb013e4f5e342c726314ba145b30
3
+ metadata.gz: b54b4599f372c2cf35b0ac966ef4491374af34cb11a02081ed94c1e98b54d5ba
4
+ data.tar.gz: 816309b5406ab7f95b2468e9a3c1b16fcdc1f6e7e09994cef4f055d252eafa76
5
5
  SHA512:
6
- metadata.gz: c51f4aa3459a64007d77e6f33361e2fdacceb56893f05cfef773c2bd0401ea92cb021bd6fc8153ff8b679fcff52de642fe7338d8cefe448b59595edc36e1ed19
7
- data.tar.gz: 453e6c9a109f4b0c791a211365284adac236496dd7e7f7280103066f074e867c103f9d1c298b5096f3228e9bc4627f73713da659c38e62e5e20af5b0eaa74909
6
+ metadata.gz: 0fc9fed3fab894d17a0f1436c169b36cdfddab34d32e73e749458092731b921c295ed1d9d48963117df81518f88fde9f716fe81017eccbe6890e47d99b33f355
7
+ data.tar.gz: 299d6600c2320b28543c64c8252d2b6fa6b8714087dcbd2f59d3e79da8441b05786d17b36a441e9079dc6845a9c89c485c6a5deda4022943036b54738429656c
@@ -0,0 +1,4 @@
1
+ exclude_patterns:
2
+ - "benchmarks/**/*"
3
+ - "lib/generators/**/*"
4
+ - "spec/**/*"
@@ -9,17 +9,17 @@ jobs:
9
9
  strategy:
10
10
  matrix:
11
11
  versions:
12
- - { ruby: "2.4.x", rails: "5.0.x" }
13
- - { ruby: "2.5.x", rails: "5.0.x" }
14
- - { ruby: "2.6.x", rails: "5.0.x" }
15
- - { ruby: "2.4.x", rails: "5.1.x" }
16
- - { ruby: "2.5.x", rails: "5.1.x" }
17
- - { ruby: "2.6.x", rails: "5.1.x" }
18
- - { ruby: "2.4.x", rails: "5.2.x" }
19
- - { ruby: "2.5.x", rails: "5.2.x" }
20
- - { ruby: "2.6.x", rails: "5.2.x" }
21
- - { ruby: "2.5.x", rails: "6.0.x" }
22
- - { ruby: "2.6.x", rails: "6.0.x" }
12
+ - { ruby: "2.5", rails: "5.2.x" }
13
+ - { ruby: "2.6", rails: "5.2.x" }
14
+ - { ruby: "2.7", rails: "5.2.x" }
15
+ - { ruby: "2.5", rails: "6.0.x" }
16
+ - { ruby: "2.6", rails: "6.0.x" }
17
+ - { ruby: "2.7", rails: "6.0.x" }
18
+ - { ruby: "3.0", rails: "6.0.x" }
19
+ - { ruby: "2.5", rails: "6.1.x" }
20
+ - { ruby: "2.6", rails: "6.1.x" }
21
+ - { ruby: "2.7", rails: "6.1.x" }
22
+ - { ruby: "3.0", rails: "6.1.x" }
23
23
 
24
24
  steps:
25
25
  - uses: actions/checkout@v1
@@ -31,9 +31,10 @@ jobs:
31
31
  key: ruby-${{ matrix.versions.ruby }}-rails-${{ matrix.versions.rails }}
32
32
 
33
33
  - name: Set up Ruby
34
- uses: actions/setup-ruby@v1
34
+ uses: ruby/setup-ruby@v1
35
35
  with:
36
36
  ruby-version: ${{ matrix.versions.ruby }}
37
+ bundler-cache: true
37
38
 
38
39
  - name: Set up bundler
39
40
  run: |
@@ -8,6 +8,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8
8
  ## [Unreleased]
9
9
  Nothing yet
10
10
 
11
+ ## [1.1.0] - 2020-12-23
12
+ ### Added
13
+ - Ruby 2.7 support ([#37](https://github.com/komposable/dekorator/pull/37))
14
+ - List decorators in Rails stats task ([#38](https://github.com/komposable/dekorator/pull/38))
15
+ - Add Rails 6.1 support and drop Rails 5.0 and 5.1 support ([#41](https://github.com/komposable/dekorator/pull/41))
16
+ ### Changed
17
+ - Refactorisation ([#39](https://github.com/komposable/dekorator/pull/39))
18
+ ### Removed
19
+ - Remove `DecoratedEnumerableProxy` ([#36](https://github.com/komposable/dekorator/pull/36))
20
+ - Drop Ruby 2.4 support ([#37](https://github.com/komposable/dekorator/pull/37))
21
+ - Drop Rails 5.0 and 5.1 support ([#41](https://github.com/komposable/dekorator/pull/41))
22
+
11
23
  ## [1.0.0] - 2019-12-02
12
24
  ### Added
13
25
  - Avoid deep decoration ([#25](https://github.com/komposable/dekorator/pull/25))
@@ -28,5 +40,6 @@ Nothing yet
28
40
  - Create `dekorator:install` generator ([a2a36d66](https://github.com/komposable/dekorator/commit/a2a36d66c6de6cb0a00f783794cd29f899bc04b6))
29
41
  - Create `decorator` generator ([a2a36d66](https://github.com/komposable/dekorator/commit/a2a36d66c6de6cb0a00f783794cd29f899bc04b6))
30
42
 
31
- [Unreleased]: https://github.com/komposable/dekorator/compare/v1.0.0...master
32
- [1.0.0]: https://github.com/komposable/dekorator/compare/v1.0.0...1.0.0.pre.1
43
+ [Unreleased]: https://github.com/komposable/dekorator/compare/v1.1.0...master
44
+ [1.1.0]: https://github.com/komposable/dekorator/compare/v1.0.0...v1.1.0
45
+ [1.0.0]: https://github.com/komposable/dekorator/compare/v1.0.0.pre.1...v1.0.0
data/README.md CHANGED
@@ -13,8 +13,8 @@ This gem has been inspired by our Rails development practices at [Pantographe](h
13
13
 
14
14
  ## Compatibility
15
15
 
16
- * Ruby 2.4+
17
- * Rails 5.0+
16
+ * Ruby 2.5+
17
+ * Rails 5.2+
18
18
 
19
19
  ## Installation
20
20
 
@@ -156,7 +156,8 @@ decorated_user.posts.first # => ArticleDecorator
156
156
 
157
157
  ### ActiveAdmin
158
158
 
159
- This gem is compatible with [`activeadmin`][activeadmin].
159
+ This gem is compatible with [`activeadmin`][activeadmin] ([2.8+](https://github.com/activeadmin/activeadmin/pull/6249)).
160
+ For `activeadmin` before `2.8`, use `dekorator` `1.0.*`.
160
161
 
161
162
  Simply use `#decorate_with`
162
163
 
@@ -96,8 +96,8 @@ end
96
96
 
97
97
  # Benchmark
98
98
  SCENARIOS = {
99
- "#summary" => :summary,
100
- "#comments" => :comments,
99
+ "#summary" => :summary,
100
+ "#comments" => :comments,
101
101
  }
102
102
 
103
103
  SCENARIOS.each_pair do |name, method|
@@ -37,11 +37,11 @@ Gem::Specification.new do |spec|
37
37
 
38
38
  spec.required_ruby_version = ">= 2.3"
39
39
 
40
- spec.add_runtime_dependency "actionview", ">= 5.0", "< 6.1"
41
- spec.add_runtime_dependency "activesupport", ">= 5.0", "< 6.1"
42
- spec.add_runtime_dependency "railties", ">= 5.0", "< 6.1"
40
+ spec.add_runtime_dependency "actionview", ">= 5.2", "< 6.2"
41
+ spec.add_runtime_dependency "activesupport", ">= 5.2", "< 6.2"
42
+ spec.add_runtime_dependency "railties", ">= 5.2", "< 6.2"
43
43
 
44
44
  spec.add_development_dependency "bundler", "~> 2.0"
45
- spec.add_development_dependency "rake", "~> 10.0"
45
+ spec.add_development_dependency "rake", ">= 12.3.3"
46
46
  spec.add_development_dependency "rspec", "~> 3.0"
47
47
  end
@@ -8,6 +8,7 @@ module Dekorator
8
8
  # @api private
9
9
  module Generators; end
10
10
 
11
+ # :nodoc:
11
12
  class DecoratorNotFound < ArgumentError; end
12
13
 
13
14
  # Base decorator.
@@ -15,31 +16,31 @@ module Dekorator
15
16
  class << self
16
17
  # Decorate an object with a decorator.
17
18
  #
18
- # @param object_or_collection [Object, Enumerable] the object or collection to decorate.
19
- # @option opts [Class] :with the decorator class to use. If empty a decorator will be guessed.
19
+ # @param object_or_enumerable [Object, Enumerable] the object or Enumerable to decorate.
20
+ # @param with [Class] the decorator class to use. If empty a decorator will be guessed.
20
21
  #
21
- # @return [Dekorator::Base, ActiveRecord::Relation, Enumerable] the obect or collection decorated.
22
+ # @return [Dekorator::Base] if object given.
23
+ # @return [Enumerable] if Enumerable given.
22
24
  #
23
25
  # @raise [DecoratorNotFound] if decorator is not found.
24
- def decorate(object_or_collection, with: nil)
25
- return object_or_collection if decorable_object?(object_or_collection)
26
+ def decorate(object_or_enumerable, with: nil)
27
+ return object_or_enumerable unless decorable?(object_or_enumerable)
26
28
 
27
- with ||= self if with != :__guess__ && self != Dekorator::Base
28
- with = _guess_decorator(object_or_collection) if with.nil? || with == :__guess__
29
+ with ||= _decorator_class
29
30
 
30
- object_or_collection = _decorate(object_or_collection, with: with)
31
+ object_or_enumerable = _decorate(object_or_enumerable, with: with)
31
32
 
32
33
  if block_given?
33
- yield object_or_collection
34
+ yield object_or_enumerable
34
35
  else
35
- object_or_collection
36
+ object_or_enumerable
36
37
  end
37
38
  end
38
39
 
39
40
  # Define that an association must be decorated.
40
41
  #
41
42
  # @param relation_name [String, Symbol] the association name to decorate.
42
- # @option opts [Class] :with the decorator class to use. If empty a decorator will be guessed.
43
+ # @param with [Class] the decorator class to use. If empty a decorator will be guessed.
43
44
  #
44
45
  # @example Define an association to decorate
45
46
  # class UserDecorator < Dekorator::Base
@@ -54,7 +55,7 @@ module Dekorator
54
55
  relation_name = relation_name.to_sym
55
56
 
56
57
  define_method(relation_name) do
57
- @decorated_associations[relation_name] ||= decorate(__getobj__.public_send(relation_name), with: with)
58
+ @_decorated_associations[relation_name] ||= decorate(__getobj__.public_send(relation_name), with: with)
58
59
  end
59
60
  end
60
61
 
@@ -62,54 +63,74 @@ module Dekorator
62
63
  #
63
64
  # @return [Class] the decorated object class.
64
65
  def base_class
65
- _safe_constantize(name.gsub("Decorator", ""))
66
+ _safe_constantize(name.sub("Decorator", ""))
66
67
  end
67
68
 
68
69
  private
69
70
 
70
- def _decorate(object_or_enumerable, with:)
71
- if !object_or_enumerable.is_a? Enumerable
72
- with.new(object_or_enumerable)
71
+ # @api private
72
+ def _decorate(object_or_enumerable, with: nil)
73
+ with = _guess_decorator(object_or_enumerable) if with.nil? || with == :__guess__
74
+
75
+ if object_or_enumerable.is_a? Enumerable
76
+ object_or_enumerable.lazy.map { |object| _decorate(object, with: with) }
73
77
  else
74
- if defined?(ActiveRecord::Relation) && object_or_enumerable.is_a?(ActiveRecord::Relation)
75
- Dekorator::DecoratedEnumerableProxy.new(with, object_or_enumerable)
76
- else object_or_enumerable.is_a? Enumerable
77
- object_or_enumerable.map { |object| _decorate(object, with: with) }
78
- end
78
+ with.new(object_or_enumerable)
79
79
  end
80
80
  end
81
81
 
82
+ # @api private
82
83
  def _guess_decorator(object_or_enumerable)
83
84
  object_or_enumerable = object_or_enumerable.first if object_or_enumerable.is_a? Enumerable
84
85
 
85
86
  _safe_constantize("#{object_or_enumerable.class}Decorator") \
86
- || raise(DecoratorNotFound, "Can't guess decorator for #{object_or_enumerable.class.name} object")
87
+ || raise(DecoratorNotFound, "Can't guess decorator for #{object_or_enumerable.class} object")
87
88
  end
88
89
 
89
- def decorable_object?(object_or_collection)
90
- (object_or_collection.respond_to?(:empty?) && object_or_collection.empty?) \
91
- || !object_or_collection \
92
- || object_or_collection.is_a?(Dekorator::Base) \
93
- || (defined?(ActiveRecord::Relation) && object_or_collection.is_a?(Dekorator::DecoratedEnumerableProxy))
90
+ # @api private
91
+ def decorable?(object_or_enumerable)
92
+ return false if object_or_enumerable.respond_to?(:empty?) && object_or_enumerable.empty?
93
+ return false if !object_or_enumerable
94
+ return false if object_or_enumerable.is_a?(Dekorator::Base)
95
+
96
+ true
94
97
  end
95
98
 
99
+ # @api private
96
100
  def _safe_constantize(class_name)
97
101
  Object.const_get(class_name)
98
- rescue NameError => _e
102
+ rescue NameError => _
99
103
  nil
100
104
  end
105
+
106
+ # @api private
107
+ def _decorator_class
108
+ return nil if self == Dekorator::Base
109
+
110
+ self
111
+ end
101
112
  end
102
113
 
103
- # :nodoc
114
+ # Decorate an object
115
+ #
116
+ # @param object [Object] object to decorate.
104
117
  def initialize(object)
105
- @decorated_associations = {}
118
+ @_decorated_associations = {}
106
119
 
107
120
  super(object)
108
121
  end
109
122
 
110
- # :nodoc
111
- def decorate(object_or_collection, with: :__guess__)
112
- self.class.decorate(object_or_collection, with: with)
123
+ # Decorate an object with a decorator.
124
+ #
125
+ # @param object_or_enumerable [Object, Enumerable] the object or Enumerable to decorate.
126
+ # @param with [Class] the decorator class to use. If empty a decorator will be guessed.
127
+ #
128
+ # @return [Dekorator::Base] if object given.
129
+ # @return [Enumerable] if Enumerable given.
130
+ #
131
+ # @raise [DecoratorNotFound] if decorator is not found.c
132
+ def decorate(object_or_enumerable, with: :__guess__)
133
+ self.class.decorate(object_or_enumerable, with: with)
113
134
  end
114
135
 
115
136
  # Returns the decorated object.
@@ -119,33 +140,6 @@ module Dekorator
119
140
  __getobj__
120
141
  end
121
142
  end
122
-
123
- if defined?(ActiveRecord::Relation)
124
- # DecoratedEnumerableProxy is strongly inspired from
125
- # https://github.com/kiote/activeadmin-poro-decorator/blob/master/lib/activeadmin-poro-decorator.rb#L65
126
- class DecoratedEnumerableProxy < DelegateClass(ActiveRecord::Relation)
127
- include Enumerable
128
-
129
- delegate :as_json, :collect, :map, :each, :[], :all?, :include?,
130
- :first, :last, :shift, to: :decorated_collection
131
- delegate :each, to: :to_ary
132
-
133
- def initialize(decorator_class, collection)
134
- super(collection)
135
-
136
- @decorator_class = decorator_class
137
- end
138
-
139
- def wrapped_collection
140
- __getobj__
141
- end
142
-
143
- def decorated_collection
144
- @decorated_collection ||= wrapped_collection.collect { |member| @decorator_class.new(member) }
145
- end
146
- alias to_ary decorated_collection
147
- end
148
- end
149
143
  end
150
144
 
151
145
  require "dekorator/railtie" if defined?(Rails)
@@ -10,8 +10,8 @@ module Dekorator
10
10
  helper_method :decorate
11
11
  end
12
12
 
13
- def decorate(object_or_collection, with: nil)
14
- Dekorator::Base.decorate(object_or_collection, with: with)
13
+ def decorate(object_or_enumerable, with: nil)
14
+ Dekorator::Base.decorate(object_or_enumerable, with: with)
15
15
  end
16
16
  end
17
17
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ task stats: "dekorator:statsetup"
4
+
5
+ namespace :dekorator do
6
+ task statsetup: :environment do
7
+ require "rails/code_statistics"
8
+
9
+ ::STATS_DIRECTORIES << ["Decorators", "app/decorators"]
10
+ end
11
+ end
@@ -4,12 +4,12 @@ module Dekorator
4
4
  require "dekorator/rails/controller"
5
5
 
6
6
  class Railtie < ::Rails::Railtie
7
- config.to_prepare do |_app|
8
- ActionController::Base.include Dekorator::Controller
7
+ rake_tasks do
8
+ load "dekorator/rails/tasks/dekorator.rake"
9
9
  end
10
10
 
11
- config.after_initialize do |app|
12
- app.config.paths.add "app/decorators", eager_load: true
11
+ config.to_prepare do |_app|
12
+ ActionController::Base.include Dekorator::Controller
13
13
  end
14
14
  end
15
15
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dekorator
4
- VERSION = "1.0.0".freeze
4
+ VERSION = "1.1.0".freeze
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dekorator
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pantographe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-12-02 00:00:00.000000000 Z
11
+ date: 2020-12-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionview
@@ -16,60 +16,60 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '5.0'
19
+ version: '5.2'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '6.1'
22
+ version: '6.2'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: '5.0'
29
+ version: '5.2'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '6.1'
32
+ version: '6.2'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: activesupport
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
- version: '5.0'
39
+ version: '5.2'
40
40
  - - "<"
41
41
  - !ruby/object:Gem::Version
42
- version: '6.1'
42
+ version: '6.2'
43
43
  type: :runtime
44
44
  prerelease: false
45
45
  version_requirements: !ruby/object:Gem::Requirement
46
46
  requirements:
47
47
  - - ">="
48
48
  - !ruby/object:Gem::Version
49
- version: '5.0'
49
+ version: '5.2'
50
50
  - - "<"
51
51
  - !ruby/object:Gem::Version
52
- version: '6.1'
52
+ version: '6.2'
53
53
  - !ruby/object:Gem::Dependency
54
54
  name: railties
55
55
  requirement: !ruby/object:Gem::Requirement
56
56
  requirements:
57
57
  - - ">="
58
58
  - !ruby/object:Gem::Version
59
- version: '5.0'
59
+ version: '5.2'
60
60
  - - "<"
61
61
  - !ruby/object:Gem::Version
62
- version: '6.1'
62
+ version: '6.2'
63
63
  type: :runtime
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
67
  - - ">="
68
68
  - !ruby/object:Gem::Version
69
- version: '5.0'
69
+ version: '5.2'
70
70
  - - "<"
71
71
  - !ruby/object:Gem::Version
72
- version: '6.1'
72
+ version: '6.2'
73
73
  - !ruby/object:Gem::Dependency
74
74
  name: bundler
75
75
  requirement: !ruby/object:Gem::Requirement
@@ -88,16 +88,16 @@ dependencies:
88
88
  name: rake
89
89
  requirement: !ruby/object:Gem::Requirement
90
90
  requirements:
91
- - - "~>"
91
+ - - ">="
92
92
  - !ruby/object:Gem::Version
93
- version: '10.0'
93
+ version: 12.3.3
94
94
  type: :development
95
95
  prerelease: false
96
96
  version_requirements: !ruby/object:Gem::Requirement
97
97
  requirements:
98
- - - "~>"
98
+ - - ">="
99
99
  - !ruby/object:Gem::Version
100
- version: '10.0'
100
+ version: 12.3.3
101
101
  - !ruby/object:Gem::Dependency
102
102
  name: rspec
103
103
  requirement: !ruby/object:Gem::Requirement
@@ -120,6 +120,7 @@ executables: []
120
120
  extensions: []
121
121
  extra_rdoc_files: []
122
122
  files:
123
+ - ".codeclimate.yml"
123
124
  - ".github/workflows/test.yml"
124
125
  - CHANGELOG.md
125
126
  - CODE_OF_CONDUCT.md
@@ -131,6 +132,7 @@ files:
131
132
  - dekorator.gemspec
132
133
  - lib/dekorator.rb
133
134
  - lib/dekorator/rails/controller.rb
135
+ - lib/dekorator/rails/tasks/dekorator.rake
134
136
  - lib/dekorator/railtie.rb
135
137
  - lib/dekorator/version.rb
136
138
  - lib/generators/decorator_generator.rb
@@ -165,7 +167,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
165
167
  - !ruby/object:Gem::Version
166
168
  version: '0'
167
169
  requirements: []
168
- rubygems_version: 3.0.6
170
+ rubygems_version: 3.2.2
169
171
  signing_key:
170
172
  specification_version: 4
171
173
  summary: An opinionated way of organizing model-view code in Ruby on Rails, based