azeroth 0.10.1 → 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 +4 -4
- data/.circleci/config.yml +3 -3
- data/Dockerfile +1 -1
- data/README.md +43 -30
- data/azeroth.gemspec +8 -7
- data/config/check_specs.yml +1 -0
- data/lib/azeroth/decorator/class_methods.rb +249 -0
- data/lib/azeroth/decorator/hash_builder.rb +3 -1
- data/lib/azeroth/decorator/key_value_extractor.rb +3 -8
- data/lib/azeroth/decorator/method_builder.rb +23 -7
- data/lib/azeroth/decorator/options.rb +3 -1
- data/lib/azeroth/decorator.rb +30 -188
- data/lib/azeroth/params_builder.rb +11 -8
- data/lib/azeroth/request_handler/index.rb +7 -33
- data/lib/azeroth/request_handler/pagination.rb +53 -0
- data/lib/azeroth/request_handler.rb +8 -7
- data/lib/azeroth/resource_builder.rb +9 -10
- data/lib/azeroth/resourceable/builder.rb +15 -11
- data/lib/azeroth/routes_builder.rb +8 -10
- data/lib/azeroth/version.rb +1 -1
- data/spec/controllers/documents_with_error_controller_spec.rb +3 -1
- data/spec/dummy/app/models/website/decorator.rb +11 -0
- data/spec/dummy/app/models/website/with_location.rb +21 -0
- data/spec/dummy/app/models/website.rb +4 -0
- data/spec/dummy/config/environments/development.rb +1 -0
- data/spec/dummy/db/schema.rb +5 -1
- data/spec/integration/yard/azeroth/decorator_spec.rb +15 -0
- data/spec/lib/azeroth/decorator/key_value_extractor_spec.rb +3 -1
- data/spec/lib/azeroth/decorator/method_builder_spec.rb +61 -2
- data/spec/lib/azeroth/decorator_spec.rb +96 -3
- data/spec/lib/azeroth/params_builder_spec.rb +3 -1
- data/spec/lib/azeroth/request_handler/pagination_spec.rb +133 -0
- data/spec/lib/azeroth/resource_builder_spec.rb +3 -1
- data/spec/lib/azeroth/routes_builder_spec.rb +3 -1
- metadata +41 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7c8e0229917b320108b25371d2c30ca48f83663288d50d2e767b8cf45c037c95
|
4
|
+
data.tar.gz: 2e6fe774d10fa5b5ca3f22c0b4deac4828a28480ebd3ebb1cce370c84c0f359c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b517e33573aa729a94fee810f0f4cea17a39533359332017e1dea8a3d80c74aacaac1010754739d8ba312d42353c57bb93d0c172aa640453450383ea1ff99328
|
7
|
+
data.tar.gz: 7bdfbfce3bdc6f40c2c82ea904a5778b5d0e7cc037f4fbf73f2e7d5fe8a449b7dacbac41f55523afea298bea5de998cc5d442e395fbf4949e555775aeabccff4
|
data/.circleci/config.yml
CHANGED
@@ -22,7 +22,7 @@ workflows:
|
|
22
22
|
jobs:
|
23
23
|
test:
|
24
24
|
docker:
|
25
|
-
- image: darthjee/circleci_rails_gems:1.
|
25
|
+
- image: darthjee/circleci_rails_gems:1.2.0
|
26
26
|
environment:
|
27
27
|
PROJECT: azeroth
|
28
28
|
steps:
|
@@ -41,7 +41,7 @@ jobs:
|
|
41
41
|
command: cc-test-reporter after-build --exit-code $?
|
42
42
|
checks:
|
43
43
|
docker:
|
44
|
-
- image: darthjee/circleci_rails_gems:1.
|
44
|
+
- image: darthjee/circleci_rails_gems:1.2.0
|
45
45
|
environment:
|
46
46
|
PROJECT: azeroth
|
47
47
|
steps:
|
@@ -66,7 +66,7 @@ jobs:
|
|
66
66
|
command: check_specs
|
67
67
|
build-and-release:
|
68
68
|
docker:
|
69
|
-
- image: darthjee/circleci_rails_gems:1.
|
69
|
+
- image: darthjee/circleci_rails_gems:1.2.0
|
70
70
|
environment:
|
71
71
|
PROJECT: azeroth
|
72
72
|
steps:
|
data/Dockerfile
CHANGED
data/README.md
CHANGED
@@ -11,7 +11,7 @@ Azeroth
|
|
11
11
|
|
12
12
|
Yard Documentation
|
13
13
|
-------------------
|
14
|
-
[https://www.rubydoc.info/gems/azeroth/
|
14
|
+
[https://www.rubydoc.info/gems/azeroth/1.1.0](https://www.rubydoc.info/gems/azeroth/1.1.0)
|
15
15
|
|
16
16
|
Azeroth has been designed making the coding of controllers easier
|
17
17
|
as routes in controllers are usually copy, paste and replace of same
|
@@ -25,6 +25,10 @@ does not perform database operations
|
|
25
25
|
Future versions will enable `html` rendering to also perform
|
26
26
|
database operations.
|
27
27
|
|
28
|
+
Current Release: [1.1.0](https://github.com/darthjee/azeroth/tree/1.1.0)
|
29
|
+
|
30
|
+
[Next release](https://github.com/darthjee/azeroth/compare/1.1.0...master)
|
31
|
+
|
28
32
|
Installation
|
29
33
|
---------------
|
30
34
|
|
@@ -131,12 +135,50 @@ It accepts options
|
|
131
135
|
end
|
132
136
|
```
|
133
137
|
|
138
|
+
```ruby
|
139
|
+
class PaginatedDocumentsController < ApplicationController
|
140
|
+
include Azeroth::Resourceable
|
141
|
+
|
142
|
+
resource_for :document, only: 'index', paginated: true
|
143
|
+
end
|
144
|
+
|
145
|
+
30.times { create(:document) }
|
146
|
+
|
147
|
+
get '/paginated_documents.json'
|
148
|
+
|
149
|
+
# returns Array with 20 first documents
|
150
|
+
# returns in the headers pagination headers
|
151
|
+
# {
|
152
|
+
# 'pages' => 2,
|
153
|
+
# 'per_page' => 20,
|
154
|
+
# 'page' => 1
|
155
|
+
# }
|
156
|
+
|
157
|
+
get '/paginated_documents.json?page=2'
|
158
|
+
|
159
|
+
# returns Array with 10 next documents
|
160
|
+
# returns in the headers pagination headers
|
161
|
+
# {
|
162
|
+
# 'pages' => 2,
|
163
|
+
# 'per_page' => 20,
|
164
|
+
# 'page' => 2
|
165
|
+
# }
|
166
|
+
```
|
167
|
+
|
134
168
|
## Azeroth::Decorator
|
135
169
|
|
136
170
|
[Decorators](https://www.rubydoc.info/gems/azeroth/Azeroth/Decorator) are
|
137
171
|
used to define how an object is exposed as json on controller responses
|
138
172
|
defining which and how fields will be exposed
|
139
173
|
|
174
|
+
Exposing options:
|
175
|
+
|
176
|
+
- as: custom key to expose the value as
|
177
|
+
- if: method/block to be called checking if an attribute should or should not be exposed
|
178
|
+
- decorator: flag to use or not a decorator or decorator class to be used
|
179
|
+
- reader: Flag indicating if a reader to access the attribute should be created. usefull if you want method_missing to take over
|
180
|
+
- override: Flag indicating if an existing method should be overriden. This is useful when a method acessor was included from another module
|
181
|
+
|
140
182
|
```ruby
|
141
183
|
# pokemon/decorator.rb
|
142
184
|
|
@@ -172,35 +214,6 @@ defining which and how fields will be exposed
|
|
172
214
|
end
|
173
215
|
```
|
174
216
|
|
175
|
-
```ruby
|
176
|
-
class PaginatedDocumentsController < ApplicationController
|
177
|
-
include Azeroth::Resourceable
|
178
|
-
|
179
|
-
resource_for :document, only: 'index', paginated: true
|
180
|
-
end
|
181
|
-
|
182
|
-
30.times { create(:document) }
|
183
|
-
|
184
|
-
get '/paginated_documents.json'
|
185
|
-
|
186
|
-
# returns Array with 20 first documents
|
187
|
-
# returns in the headers pagination headers
|
188
|
-
{
|
189
|
-
'pages' => 2,
|
190
|
-
'per_page' => 20,
|
191
|
-
'page' => 1
|
192
|
-
}
|
193
|
-
|
194
|
-
get '/paginated_documents.json?page=2'
|
195
|
-
|
196
|
-
# returns Array with 10 next documents
|
197
|
-
# returns in the headers pagination headers
|
198
|
-
{
|
199
|
-
'pages' => 2,
|
200
|
-
'per_page' => 20,
|
201
|
-
'page' => 2
|
202
|
-
}
|
203
|
-
```
|
204
217
|
Exposing is done through the class method
|
205
218
|
[expose](https://www.rubydoc.info/gems/azeroth/Azeroth/Decorator#expose-class_method)
|
206
219
|
which accepts several options:
|
data/azeroth.gemspec
CHANGED
@@ -18,20 +18,20 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
19
|
gem.require_paths = ['lib']
|
20
20
|
|
21
|
-
gem.add_runtime_dependency 'activesupport', '~>
|
21
|
+
gem.add_runtime_dependency 'activesupport', '~> 7.0.x'
|
22
22
|
gem.add_runtime_dependency 'darthjee-active_ext', '>= 1.3.2'
|
23
23
|
gem.add_runtime_dependency 'jace', '>= 0.1.1'
|
24
|
-
gem.add_runtime_dependency 'sinclair', '>=
|
24
|
+
gem.add_runtime_dependency 'sinclair', '>= 2.0.0'
|
25
25
|
|
26
|
-
gem.add_development_dependency 'actionpack', '
|
27
|
-
gem.add_development_dependency 'activerecord', '
|
28
|
-
gem.add_development_dependency 'bundler', '~> 2.
|
26
|
+
gem.add_development_dependency 'actionpack', '7.0.4.3'
|
27
|
+
gem.add_development_dependency 'activerecord', '7.0.4.3'
|
28
|
+
gem.add_development_dependency 'bundler', '~> 2.4.8'
|
29
29
|
gem.add_development_dependency 'factory_bot', '6.2.1'
|
30
30
|
gem.add_development_dependency 'minitest', '5.16.2'
|
31
|
-
gem.add_development_dependency 'nokogiri', '1.13.
|
31
|
+
gem.add_development_dependency 'nokogiri', '1.13.8'
|
32
32
|
gem.add_development_dependency 'pry', '0.14.1'
|
33
33
|
gem.add_development_dependency 'pry-nav', '1.0.0'
|
34
|
-
gem.add_development_dependency 'rails', '
|
34
|
+
gem.add_development_dependency 'rails', '7.0.4.3'
|
35
35
|
gem.add_development_dependency 'rails-controller-testing', '1.0.5'
|
36
36
|
gem.add_development_dependency 'rake', '13.0.6'
|
37
37
|
gem.add_development_dependency 'reek', '6.0.3'
|
@@ -47,6 +47,7 @@ Gem::Specification.new do |gem|
|
|
47
47
|
gem.add_development_dependency 'rubycritic', '4.7.0'
|
48
48
|
gem.add_development_dependency 'shoulda-matchers', '4.3.0'
|
49
49
|
gem.add_development_dependency 'simplecov', '0.21.2'
|
50
|
+
gem.add_development_dependency 'sprockets-rails', '3.4.2'
|
50
51
|
gem.add_development_dependency 'sqlite3', '1.4.2'
|
51
52
|
gem.add_development_dependency 'tzinfo-data', '~> 1.2022.1'
|
52
53
|
gem.add_development_dependency 'yard', '0.9.27'
|
data/config/check_specs.yml
CHANGED
@@ -0,0 +1,249 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Azeroth
|
4
|
+
class Decorator
|
5
|
+
# @api private
|
6
|
+
# @author Darthjee
|
7
|
+
#
|
8
|
+
# Class methods added by {Decorator}
|
9
|
+
#
|
10
|
+
# @see ClassMethods#expose
|
11
|
+
module ClassMethods
|
12
|
+
# @api private
|
13
|
+
#
|
14
|
+
# All attributes exposed
|
15
|
+
#
|
16
|
+
# @return [Hash<Symbol,Hash>]
|
17
|
+
def attributes_map
|
18
|
+
@attributes_map ||= build_attributes_map
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
# @api private
|
24
|
+
# @private
|
25
|
+
#
|
26
|
+
# Initialize attributes to be exposed map
|
27
|
+
#
|
28
|
+
# When the class inherity from another
|
29
|
+
# decorator, the new class should expose the
|
30
|
+
# same attributes.
|
31
|
+
#
|
32
|
+
# @return [Hash<Symbol,Hash>]
|
33
|
+
def build_attributes_map
|
34
|
+
superclass.try(:attributes_map).dup || {}
|
35
|
+
end
|
36
|
+
|
37
|
+
# @visibility public
|
38
|
+
# @api (see Decorator.expose)
|
39
|
+
# @private
|
40
|
+
#
|
41
|
+
# Expose attributes on json decorated
|
42
|
+
#
|
43
|
+
# @param (see Decorator.expose)
|
44
|
+
# @option (see Decorator.expose)
|
45
|
+
#
|
46
|
+
# @return (see Decorator.expose)
|
47
|
+
#
|
48
|
+
# @example Simple usage
|
49
|
+
# class DummyModel
|
50
|
+
# include ActiveModel::Model
|
51
|
+
#
|
52
|
+
# attr_accessor :id, :first_name, :last_name, :age,
|
53
|
+
# :favorite_pokemon
|
54
|
+
#
|
55
|
+
# class Decorator < Azeroth::Decorator
|
56
|
+
# expose :name
|
57
|
+
# expose :age
|
58
|
+
# expose :favorite_pokemon, as: :pokemon
|
59
|
+
#
|
60
|
+
# def name
|
61
|
+
# [object.first_name, object.last_name].join(' ')
|
62
|
+
# end
|
63
|
+
# end
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# @example With relations
|
67
|
+
# # pokemon/decorator.rb
|
68
|
+
#
|
69
|
+
# class Pokemon::Decorator < Azeroth::Decorator
|
70
|
+
# expose :name
|
71
|
+
# expose :previous_form_name, as: :evolution_of, if: :evolution?
|
72
|
+
#
|
73
|
+
# def evolution?
|
74
|
+
# previous_form
|
75
|
+
# end
|
76
|
+
#
|
77
|
+
# def previous_form_name
|
78
|
+
# previous_form.name
|
79
|
+
# end
|
80
|
+
# end
|
81
|
+
#
|
82
|
+
# # pokemon/favorite_decorator.rb
|
83
|
+
#
|
84
|
+
# class Pokemon::FavoriteDecorator < Pokemon::Decorator
|
85
|
+
# expose :nickname
|
86
|
+
# end
|
87
|
+
#
|
88
|
+
# # pokemon_master/decorator.rb
|
89
|
+
#
|
90
|
+
# class PokemonMaster < ActiveRecord::Base
|
91
|
+
# has_one :favorite_pokemon, -> { where(favorite: true) },
|
92
|
+
# class_name: 'Pokemon'
|
93
|
+
# has_many :pokemons
|
94
|
+
# end
|
95
|
+
#
|
96
|
+
# # pokemon.rb
|
97
|
+
#
|
98
|
+
# class Pokemon < ActiveRecord::Base
|
99
|
+
# belongs_to :pokemon_master
|
100
|
+
# has_one :previous_form,
|
101
|
+
# class_name: 'Pokemon',
|
102
|
+
# foreign_key: :previous_form_id
|
103
|
+
# end
|
104
|
+
#
|
105
|
+
# # pokemon_master.rb
|
106
|
+
#
|
107
|
+
# class PokemonMaster::Decorator < Azeroth::Decorator
|
108
|
+
# expose :name
|
109
|
+
# expose :age
|
110
|
+
# expose :favorite_pokemon, decorator: Pokemon::FavoriteDecorator
|
111
|
+
# expose :pokemons
|
112
|
+
#
|
113
|
+
# def name
|
114
|
+
# [
|
115
|
+
# first_name,
|
116
|
+
# last_name
|
117
|
+
# ].compact.join(' ')
|
118
|
+
# end
|
119
|
+
# end
|
120
|
+
#
|
121
|
+
# # schema.rb
|
122
|
+
#
|
123
|
+
# ActiveRecord::Schema.define do
|
124
|
+
# self.verbose = false
|
125
|
+
#
|
126
|
+
# create_table :pokemon_masters, force: true do |t|
|
127
|
+
# t.string :first_name, null: false
|
128
|
+
# t.string :last_name
|
129
|
+
# t.integer :age, null: false
|
130
|
+
# end
|
131
|
+
#
|
132
|
+
# create_table :pokemons, force: true do |t|
|
133
|
+
# t.string :name, null: false
|
134
|
+
# t.string :nickname
|
135
|
+
# t.integer :pokemon_master_id
|
136
|
+
# t.boolean :favorite
|
137
|
+
# t.integer :previous_form_id
|
138
|
+
# t.index %i[pokemon_master_id favorite], unique: true
|
139
|
+
# end
|
140
|
+
#
|
141
|
+
# add_foreign_key 'pokemons', 'pokemon_masters'
|
142
|
+
# end
|
143
|
+
#
|
144
|
+
# # test.rb
|
145
|
+
#
|
146
|
+
# master = PokemonMaster.create(
|
147
|
+
# first_name: 'Ash',
|
148
|
+
# last_name: 'Ketchum',
|
149
|
+
# age: 10
|
150
|
+
# )
|
151
|
+
#
|
152
|
+
# master.create_favorite_pokemon(
|
153
|
+
# name: 'pikachu',
|
154
|
+
# nickname: 'Pikachu'
|
155
|
+
# )
|
156
|
+
#
|
157
|
+
# metapod = Pokemon.create(name: :metapod)
|
158
|
+
#
|
159
|
+
# master.pokemons.create(
|
160
|
+
# name: 'butterfree', previous_form: metapod
|
161
|
+
# )
|
162
|
+
# master.pokemons.create(name: 'squirtle')
|
163
|
+
#
|
164
|
+
# decorator = PokemonMaster::Decorator.new(master)
|
165
|
+
#
|
166
|
+
# decorator.as_json
|
167
|
+
# # returns
|
168
|
+
# # {
|
169
|
+
# # 'age' => 10,
|
170
|
+
# # 'name' => 'Ash Ketchum',
|
171
|
+
# # 'favorite_pokemon' => {
|
172
|
+
# # 'name' => 'pikachu',
|
173
|
+
# # 'nickname' => 'Pikachu'
|
174
|
+
# # },
|
175
|
+
# # 'pokemons' => [{
|
176
|
+
# # 'name' => 'butterfree',
|
177
|
+
# # 'evolution_of' => 'metapod'
|
178
|
+
# # }, {
|
179
|
+
# # 'name' => 'squirtle'
|
180
|
+
# # }, {
|
181
|
+
# # 'name' => 'pikachu'
|
182
|
+
# # }]
|
183
|
+
# # }
|
184
|
+
#
|
185
|
+
# @example With method building options
|
186
|
+
# ActiveRecord::Schema.define do
|
187
|
+
# self.verbose = false
|
188
|
+
#
|
189
|
+
# create_table :websites, force: true do |t|
|
190
|
+
# t.string :domain, null: false
|
191
|
+
# t.integer :port, limit: 2, unsigned: true
|
192
|
+
# t.string :protocol, limit: 5
|
193
|
+
# end
|
194
|
+
# end
|
195
|
+
#
|
196
|
+
# class Website < ActiveRecord::Base
|
197
|
+
# end
|
198
|
+
#
|
199
|
+
# class Website < ActiveRecord::Base
|
200
|
+
# module WithLocation
|
201
|
+
# def location
|
202
|
+
# "#{protocol}://#{domain}:#{port}"
|
203
|
+
# end
|
204
|
+
#
|
205
|
+
# def protocol
|
206
|
+
# website.protocol || '*'
|
207
|
+
# end
|
208
|
+
#
|
209
|
+
# def domain
|
210
|
+
# website.domain || '*'
|
211
|
+
# end
|
212
|
+
#
|
213
|
+
# def port
|
214
|
+
# website.port || '*'
|
215
|
+
# end
|
216
|
+
# end
|
217
|
+
# end
|
218
|
+
#
|
219
|
+
# class Website < ActiveRecord::Base
|
220
|
+
# class Decorator < Azeroth::Decorator
|
221
|
+
# include WithLocation
|
222
|
+
#
|
223
|
+
# expose :location, override: false
|
224
|
+
#
|
225
|
+
# alias website object
|
226
|
+
# end
|
227
|
+
# end
|
228
|
+
#
|
229
|
+
# website = Website.create(
|
230
|
+
# protocol: :http,
|
231
|
+
# domain: 'google.com'
|
232
|
+
# )
|
233
|
+
#
|
234
|
+
# decorator = Website::Decorator.new(website)
|
235
|
+
#
|
236
|
+
# decorator.as_json
|
237
|
+
#
|
238
|
+
# # returns
|
239
|
+
# # { 'location' => 'http://google.com:*' }
|
240
|
+
def expose(attribute, **options_hash)
|
241
|
+
options = Decorator::Options.new(options_hash)
|
242
|
+
|
243
|
+
MethodBuilder.build_reader(self, attribute, options)
|
244
|
+
|
245
|
+
attributes_map[attribute] = options
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
@@ -25,7 +25,9 @@ module Azeroth
|
|
25
25
|
# @return [Hash]
|
26
26
|
def as_json
|
27
27
|
attributes_map.inject({}) do |hash, (method, options)|
|
28
|
-
new_hash = KeyValueExtractor.new(
|
28
|
+
new_hash = KeyValueExtractor.new(
|
29
|
+
decorator: decorator, attribute: method, options: options
|
30
|
+
).as_json
|
29
31
|
hash.merge!(new_hash)
|
30
32
|
end
|
31
33
|
end
|
@@ -11,18 +11,14 @@ module Azeroth
|
|
11
11
|
#
|
12
12
|
# A decorator is infered for the value / attribute
|
13
13
|
# or used from the options given
|
14
|
-
class KeyValueExtractor
|
14
|
+
class KeyValueExtractor < Sinclair::Model
|
15
|
+
initialize_with(:decorator, :attribute, :options)
|
15
16
|
# @param decorator [Decorator] decorator object
|
16
17
|
# @param attribute [Symbol] attribute to be used on output hash
|
17
18
|
# @param options [Decorator::Options] decoration options
|
18
19
|
# @option options if [Proc,Symbol] conditional to be
|
19
20
|
# checked when exposing field
|
20
21
|
# (see {Decorator::Options#if})
|
21
|
-
def initialize(decorator, attribute, options)
|
22
|
-
@decorator = decorator
|
23
|
-
@attribute = attribute
|
24
|
-
@options = options
|
25
|
-
end
|
26
22
|
|
27
23
|
# Return hash for attribute
|
28
24
|
#
|
@@ -38,9 +34,8 @@ module Azeroth
|
|
38
34
|
}
|
39
35
|
end
|
40
36
|
|
41
|
-
|
37
|
+
private
|
42
38
|
|
43
|
-
attr_reader :decorator, :attribute, :options
|
44
39
|
# @method decorator
|
45
40
|
# @api private
|
46
41
|
# @private
|
@@ -7,20 +7,36 @@ module Azeroth
|
|
7
7
|
# Responsible for building readers for attributes
|
8
8
|
# @api private
|
9
9
|
class MethodBuilder < Sinclair
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
10
|
+
class << self
|
11
|
+
# Builds reader
|
12
|
+
#
|
13
|
+
# reaader delegate method calls to @object
|
14
|
+
#
|
15
|
+
# @return [Array<Sinclair::MethodDefinition>]
|
16
|
+
def build_reader(klass, attribute, options)
|
17
|
+
new(klass, options).build_reader(attribute)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(klass, options)
|
22
|
+
super(klass)
|
23
|
+
@options = options
|
17
24
|
end
|
18
25
|
|
19
26
|
# (see MethodBuilder.build_reader)
|
20
27
|
def build_reader(attribute)
|
28
|
+
return if skip_creation?(attribute)
|
29
|
+
|
21
30
|
add_method(attribute, "@object.#{attribute}")
|
22
31
|
build
|
23
32
|
end
|
33
|
+
|
34
|
+
def skip_creation?(attribute)
|
35
|
+
return true unless options.reader
|
36
|
+
return false unless klass.method_defined?(attribute)
|
37
|
+
|
38
|
+
!options.override
|
39
|
+
end
|
24
40
|
end
|
25
41
|
end
|
26
42
|
end
|