sinclair 1.1.3 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ac0a266d5bf3934653eeb107bc0e7305bfffb80b1845be7abe617aef8b910be6
4
- data.tar.gz: 978c830d6045dc169d426f07a79e96bdafbd25482ca982636c8244d3348d69e8
3
+ metadata.gz: b1f884160da67fa0a41d2b19c5fb1f2186b6a5dfb8518e70d7e624667e7d7a35
4
+ data.tar.gz: aff0a41c90770ec096c19963abfcea8a6435ee0c725ad90a70dedad800b03646
5
5
  SHA512:
6
- metadata.gz: c62398491d7d08baa0134e5a5bbe0bfc7b964e2deb2e2c2f25db63788069c654d2636d07aa52ed1f653ee9ba9395f70425d5ab58116447f705ff2b54d0e4273e
7
- data.tar.gz: a8642cb8a8aaafab6c5ef20663f02bcb7ee629900f463f3dc385e3c27cf3ef8c272221987fac9b6cf26c165ad07e0fa9710fcb1d3fa884d94fabaa9c3602e3d7
6
+ metadata.gz: 455434bf9a034eb258b6cc52d0ff3f0a1f0d3671f9ca96c9f892d18ef1435946fc982821fcb34b077409b3f05265cbe493d2820e51804c79ca23da5e58d7ee12
7
+ data.tar.gz: 8360e97280c678e0326b2be9227b16401059c7a8b37b97e3a0b1ffaa2177ffc4bec7df7a01d8dc8eb2accb216a8c68ade20783c3d4b77ce75a7acff9368ac8a0
data/.rubocop.yml CHANGED
@@ -1,3 +1,4 @@
1
+ require: rubocop-rspec
1
2
  inherit_from: .rubocop_todo.yml
2
3
 
3
4
  AllCops:
@@ -9,3 +10,26 @@ Metrics/BlockLength:
9
10
 
10
11
  Metrics/LineLength:
11
12
  Max: 100
13
+
14
+ Lint/AmbiguousBlockAssociation:
15
+ Exclude:
16
+ - 'spec/**/*_spec.rb'
17
+
18
+ RSpec/AlignLeftLetBrace:
19
+ Enabled: true
20
+
21
+ RSpec/InstanceVariable:
22
+ Exclude:
23
+ - 'spec/integration/yard/sinclair/method_definition_spec.rb'
24
+ - 'spec/lib/sinclair/method_definition_spec.rb'
25
+
26
+ RSpec/MultipleExpectations:
27
+ Exclude:
28
+ - spec/integration/yard/sinclair/method_definition_spec.rb
29
+ - spec/lib/sinclair_spec.rb
30
+ - spec/integration/readme/my_model_spec.rb
31
+
32
+ RSpec/NestedGroups:
33
+ Max: 4
34
+ Exclude:
35
+ - spec/integration/yard/**/*.rb
data/.rubocop_todo.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2018-07-10 13:04:21 +0000 using RuboCop version 0.57.2.
3
+ # on 2019-03-29 10:57:21 +0000 using RuboCop version 0.58.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
data/README.md CHANGED
@@ -3,33 +3,34 @@ Sinclair
3
3
  [![Code Climate](https://codeclimate.com/github/darthjee/sinclair/badges/gpa.svg)](https://codeclimate.com/github/darthjee/sinclair)
4
4
  [![Test Coverage](https://codeclimate.com/github/darthjee/sinclair/badges/coverage.svg)](https://codeclimate.com/github/darthjee/sinclair/coverage)
5
5
  [![Issue Count](https://codeclimate.com/github/darthjee/sinclair/badges/issue_count.svg)](https://codeclimate.com/github/darthjee/sinclair)
6
+ [![Gem Version](https://badge.fury.io/rb/sinclair.svg)](https://badge.fury.io/rb/sinclair)
6
7
 
7
8
 
8
9
  ![sinclair](https://raw.githubusercontent.com/darthjee/sinclair/master/sinclair.jpg)
9
10
 
10
11
  This gem helps the creation of complex concern with class methods
11
12
 
13
+ Yard Documentation
14
+ -------------------
15
+ https://www.rubydoc.info/gems/sinclair/1.2.0
16
+
12
17
  Installation
13
18
  ---------------
14
19
  - Install it
15
20
 
16
- ```ruby
17
- gem install sinclair
18
- ```
21
+ ```ruby
22
+ gem install sinclair
23
+ ```
19
24
 
20
25
  - Or add Sinclairn to your `Gemfile` and `bundle install`:
21
26
 
22
- ```ruby
23
- gem 'sinclair'
24
- ```
25
-
26
- ```bash
27
- bundle install sinclair
28
- ```
27
+ ```ruby
28
+ gem 'sinclair'
29
+ ```
29
30
 
30
- Yard Documentation
31
- -------------------
32
- https://www.rubydoc.info/gems/sinclair/1.1.3
31
+ ```bash
32
+ bundle install sinclair
33
+ ```
33
34
 
34
35
  Usage
35
36
  ---------------
@@ -38,93 +39,87 @@ adding methods to your class or by extending it for more complex logics
38
39
 
39
40
  - Stand Alone usage:
40
41
 
41
- ```ruby
42
-
43
- class Clazz
44
- end
42
+ ```ruby
45
43
 
46
- builder = Sinclair.new(Clazz)
47
-
48
- builder.add_method(:twenty, '10 + 10')
49
- builder.add_method(:eighty) { 4 * twenty }
50
- builder.build
44
+ class Clazz
45
+ end
51
46
 
52
- instance = Clazz.new
47
+ builder = Sinclair.new(Clazz)
53
48
 
54
- puts "Twenty => #{instance.twenty}"
55
- puts "Eighty => #{instance.eighty}"
56
- ```
49
+ builder.add_method(:twenty, '10 + 10')
50
+ builder.add_method(:eighty) { 4 * twenty }
51
+ builder.build
57
52
 
58
- ```string
53
+ instance = Clazz.new
59
54
 
60
- Twenty => 20
61
- Eighty => 80
62
- ```
55
+ puts "Twenty => #{instance.twenty}" # Twenty => 20
56
+ puts "Eighty => #{instance.eighty}" # Eighty => 80
57
+ ```
63
58
 
64
59
  - Extending the builder
65
60
 
66
- ```ruby
61
+ ```ruby
67
62
 
68
- class ValidationBuilder < Sinclair
69
- delegate :expected, to: :options_object
70
-
71
- def initialize(klass, options={})
72
- super
73
- end
63
+ class ValidationBuilder < Sinclair
64
+ delegate :expected, to: :options_object
74
65
 
75
- def add_validation(field)
76
- add_method("#{field}_valid?", "#{field}.is_a?#{expected}")
77
- end
66
+ def initialize(klass, options={})
67
+ super
68
+ end
78
69
 
79
- def add_accessors(fields)
80
- klass.send(:attr_accessor, *fields)
81
- end
70
+ def add_validation(field)
71
+ add_method("#{field}_valid?", "#{field}.is_a?#{expected}")
82
72
  end
83
73
 
84
- module MyConcern
85
- extend ActiveSupport::Concern
74
+ def add_accessors(fields)
75
+ klass.send(:attr_accessor, *fields)
76
+ end
77
+ end
86
78
 
87
- class_methods do
88
- def validate(*fields, expected_class)
89
- builder = ::ValidationBuilder.new(self, expected: expected_class)
79
+ module MyConcern
80
+ extend ActiveSupport::Concern
90
81
 
91
- validatable_fields.concat(fields)
92
- builder.add_accessors(fields)
82
+ class_methods do
83
+ def validate(*fields, expected_class)
84
+ builder = ::ValidationBuilder.new(self, expected: expected_class)
93
85
 
94
- fields.each do |field|
95
- builder.add_validation(field)
96
- end
86
+ validatable_fields.concat(fields)
87
+ builder.add_accessors(fields)
97
88
 
98
- builder.build
89
+ fields.each do |field|
90
+ builder.add_validation(field)
99
91
  end
100
92
 
101
- def validatable_fields
102
- @validatable_fields ||= []
103
- end
93
+ builder.build
104
94
  end
105
95
 
106
- def valid?
107
- self.class.validatable_fields.all? do |field|
108
- public_send("#{field}_valid?")
109
- end
96
+ def validatable_fields
97
+ @validatable_fields ||= []
110
98
  end
111
99
  end
112
100
 
113
- class MyClass
114
- include MyConcern
115
- validate :name, :surname, String
116
- validate :age, :legs, Integer
117
-
118
- def initialize(name: nil, surname: nil, age: nil, legs: nil)
119
- @name = name
120
- @surname = surname
121
- @age = age
122
- @legs = legs
101
+ def valid?
102
+ self.class.validatable_fields.all? do |field|
103
+ public_send("#{field}_valid?")
123
104
  end
124
105
  end
106
+ end
125
107
 
126
- instance = MyClass.new
127
- ```
108
+ class MyClass
109
+ include MyConcern
110
+ validate :name, :surname, String
111
+ validate :age, :legs, Integer
112
+
113
+ def initialize(name: nil, surname: nil, age: nil, legs: nil)
114
+ @name = name
115
+ @surname = surname
116
+ @age = age
117
+ @legs = legs
118
+ end
119
+ end
120
+
121
+ instance = MyClass.new
122
+ ```
128
123
 
129
124
  the instance will respond to the methods
130
125
  ```name``` ```name=``` ```name_valid?```
@@ -133,34 +128,62 @@ adding methods to your class or by extending it for more complex logics
133
128
  ```legs``` ```legs=``` ```legs_valid?```
134
129
  ```valid?```.
135
130
 
136
- ```ruby
131
+ ```ruby
132
+ valid_object = MyClass.new(
133
+ name: :name,
134
+ surname: 'surname',
135
+ age: 20,
136
+ legs: 2
137
+ )
138
+ valid_object.valid? # returns true
139
+ ```
140
+
141
+ ```ruby
142
+
143
+ invalid_object = MyClass.new(
144
+ name: 'name',
145
+ surname: 'surname',
146
+ age: 20,
147
+ legs: 2
148
+ )
149
+ invalid_object.valid? # returns false
150
+ ```
151
+
152
+ - Caching the result
153
+ If wanted, the result of the method can be stored in an
154
+ instance variable with the same name
155
+
156
+ ```ruby
157
+ class MyModel
158
+ attr_accessor :base, :expoent
159
+ end
160
+
161
+ builder = Sinclair.new(MyModel)
162
+
163
+ builder.add_method(:cached_power, cached: true) do
164
+ base ** expoent
165
+ end
166
+
167
+ # equivalent of builder.add_method(:cached_power) do
168
+ # @cached_power ||= base ** expoent
169
+ # end
137
170
 
138
- valid_object = MyClass.new(
139
- name: :name,
140
- surname: 'surname',
141
- age: 20,
142
- legs: 2
143
- )
144
- valid_object.valid? # returns true
145
- ```
171
+ builder.build
146
172
 
147
- ```ruby
173
+ model.base = 3
174
+ model.expoent = 2
148
175
 
149
- invalid_object = MyClass.new(
150
- name: 'name',
151
- surname: 'surname',
152
- age: 20,
153
- legs: 2
154
- )
155
- invalid_object.valid? # returns false
156
- ```
176
+ model.cached_power # returns 9
177
+ model.expoent = 3
178
+ model.cached_power # returns 9 (from cache)
179
+ ```
157
180
 
158
181
  RSspec matcher
159
182
  ---------------
160
183
 
161
184
  You can use the provided matcher to check that your builder is adding a method correctly
162
185
 
163
- ```ruby
186
+ ```ruby
164
187
 
165
188
  class DefaultValue
166
189
  delegate :build, to: :builder
@@ -209,19 +232,19 @@ You can use the provided matcher to check that your builder is adding a method c
209
232
  end
210
233
  end
211
234
  end
212
- ```
235
+ ```
213
236
 
214
- ```bash
237
+ ```bash
215
238
 
216
- > bundle exec rspec
217
- ```
239
+ > bundle exec rspec
240
+ ```
218
241
 
219
- ```string
242
+ ```string
220
243
 
221
- DefaultValue
222
- when the builder runs
223
- should add method 'the_method' to #<Class:0x0000000146c160> instances
224
- when the builder runs
225
- should add method 'the_method' to #<Class:0x0000000143a1b0> instances
244
+ DefaultValue
245
+ when the builder runs
246
+ should add method 'the_method' to #<Class:0x0000000146c160> instances
247
+ when the builder runs
248
+ should add method 'the_method' to #<Class:0x0000000143a1b0> instances
226
249
 
227
- ```
250
+ ```
data/lib/sinclair.rb CHANGED
@@ -8,7 +8,7 @@ require 'active_support/all'
8
8
  #
9
9
  # Builder that add instance methods to a class
10
10
  #
11
- # @example
11
+ # @example Stand alone usage
12
12
  # class MyModel
13
13
  # end
14
14
  #
@@ -38,7 +38,7 @@ class Sinclair
38
38
  # @param options [Hash] open hash options to be used by builders inheriting from Sinclair
39
39
  # through the Sinclair::OptionsParser concern
40
40
  #
41
- # @example
41
+ # @example Preparing builder
42
42
  #
43
43
  # class Purchase
44
44
  # def initialize(value, quantity)
@@ -49,9 +49,39 @@ class Sinclair
49
49
  #
50
50
  # builder = Sinclair.new(Purchase)
51
51
  #
52
- # @example
52
+ # @example Passing building options (Used on subclasses)
53
53
  #
54
- # builder = Sinclair.new(Purchase, rescue_error: true)
54
+ # class MyBuilder < Sinclair
55
+ # def add_methods
56
+ # if options_object.rescue_error
57
+ # add_safe_method
58
+ # else
59
+ # add_method(:symbolize) { @variable.to_sym }
60
+ # end
61
+ # end
62
+ #
63
+ # def add_safe_method
64
+ # add_method(:symbolize) do
65
+ # begin
66
+ # @variable.to_sym
67
+ # rescue StandardError
68
+ # :default
69
+ # end
70
+ # end
71
+ # end
72
+ # end
73
+ #
74
+ # class MyModel
75
+ # end
76
+ #
77
+ # builder = MyBuilder.new(MyModel, rescue_error: true)
78
+ #
79
+ # builder.add_method
80
+ # builder.build
81
+ #
82
+ # instance = MyModel.new
83
+ #
84
+ # instance.symbolize # returns :default
55
85
  def initialize(klass, options = {})
56
86
  @klass = klass
57
87
  @options = options
@@ -59,7 +89,7 @@ class Sinclair
59
89
 
60
90
  # builds all the methods added into the klass
61
91
  #
62
- # @example
92
+ # @example Adding a default value method
63
93
  #
64
94
  # class MyModel
65
95
  # end
@@ -114,13 +144,13 @@ class Sinclair
114
144
  #
115
145
  # Person.new('john', 'wick').bond_name # returns 'wick, john wick'
116
146
  # @return [Array<MethodDefinition>]
117
- def add_method(name, code = nil, &block)
118
- definitions << MethodDefinition.new(name, code, &block)
147
+ def add_method(name, code = nil, **options, &block)
148
+ definitions << MethodDefinition.new(name, code, **options, &block)
119
149
  end
120
150
 
121
151
  # Evaluetes a block which will result in a String, the method code
122
152
  #
123
- # @example
153
+ # @example Building a initial value class method
124
154
  #
125
155
  # module InitialValuer
126
156
  # extend ActiveSupport::Concern
@@ -147,7 +177,7 @@ class Sinclair
147
177
  # object.age = 30
148
178
  # object.age # 30
149
179
  #
150
- # @example
180
+ # @example Adding option for rescue
151
181
  #
152
182
  # class Purchase
153
183
  # def initialize(value, quantity)
@@ -168,7 +198,7 @@ class Sinclair
168
198
  #
169
199
  # Purchase.new(2.3, 5).total_price # raises error
170
200
  #
171
- # @example
201
+ # @example Using option for rescue
172
202
  #
173
203
  # builder = Sinclair.new(Purchase, rescue_error: true)
174
204
  #