sinclair 1.1.3 → 1.2.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: 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
  #