super_module 1.3.1 → 1.4.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: 6f7d062de77d91c8bd5fd0e87e4c140fcadfc3ae81f6a91a0673a133aa26cd99
4
- data.tar.gz: 80d078ac51cd2a8d3f89dd37941a84de73b2c790f36b3d4fdadf2d4d2d63ed79
3
+ metadata.gz: a4faa73d0b49aef392b5dd1c26df10e4fc7ae5f9c528284503cd68df38c2381b
4
+ data.tar.gz: 9c48055a31b17ae2cdd554314cc3dbbf4d10e6eb2a93d4f21636663ce0f0a6c5
5
5
  SHA512:
6
- metadata.gz: e2701d71b39ed35ff6005d48c7ad076205bee6c6f3540aa76c8d48fd4f04ae8d6a73f230a7c1ab6dbfb092341c48fb2d05413954eb7800f3e760a0215c19bab3
7
- data.tar.gz: 9ef86a39a120bd5ba2e65e8026b6672234705ae6833b79ae8ef460d70121eb28bf1c05708a1dcfe820dfe67c82327d6f01352256da34c4e981bead9d8d82b783
6
+ metadata.gz: 37e9470e3ebe8977cf24425169ac7976304ba4d4eb1c0ca8069fa761813184d24e182235cc57ae01674f09189e22fe2681bd0b3a580e23aff50e323cc47ef435
7
+ data.tar.gz: 998e4a95be965413b20f49d2dad072a3458b61fd13e34eb33db601bd96ee3f7581c015ccb0e8872b8f3ef329a585dea902cccc165ac7921e58c503a6b2396892
@@ -1,5 +1,10 @@
1
1
  # Change Log
2
2
 
3
+ ## 1.4.0
4
+
5
+ - Support aliased methods
6
+ - Support safely calling self.included(base) in super module via super_module_included {|base| ... }
7
+
3
8
  ## 1.3.1
4
9
 
5
10
  - Fixed issue with super module containing class methods with default arguments
data/README.md CHANGED
@@ -94,7 +94,7 @@ end
94
94
  ```
95
95
  By including `SuperModule` (following Ruby's basic convention of relying on a module), developers can directly add class method invocations and definitions inside the module's body, and [`SuperModule`](https://github.com/AndyObtiva/super_module) takes care of automatically mixing them into classes that include the module.
96
96
 
97
- As a result, [SuperModule](https://rubygems.org/gems/super_module) collapses the difference between extending a super class and including a super module, thus encouraging developers to write simpler code while making better Object-Oriented Design decisions.
97
+ As a result, [SuperModule](https://rubygems.org/gems/super_module) collapses the difference between extending a super class and including a [super module](#glossary-and-definitions), thus encouraging developers to write simpler code while making better Object-Oriented Design decisions.
98
98
 
99
99
  In other words, [SuperModule](https://rubygems.org/gems/super_module) furthers Ruby's goal of making programmers happy.
100
100
 
@@ -104,7 +104,7 @@ In other words, [SuperModule](https://rubygems.org/gems/super_module) furthers R
104
104
 
105
105
  <b>Using [Bundler](http://bundler.io/)</b>
106
106
 
107
- Add the following to Gemfile: <pre>gem 'super_module', '1.3.1'</pre>
107
+ Add the following to Gemfile: <pre>gem 'super_module', '1.4.0'</pre>
108
108
 
109
109
  And run the following command: <pre>bundle</pre>
110
110
 
@@ -118,7 +118,7 @@ Run the following command: <pre>gem install super_module</pre>
118
118
 
119
119
  Add the following at the top of your [Ruby](https://www.ruby-lang.org/en/) file: <pre>require 'super_module'</pre>
120
120
 
121
- #### 2) Simply include SuperModule in your module (just like you would do any other Ruby module)
121
+ #### 2) Simply include SuperModule at the top of your module definition before anything else.
122
122
 
123
123
  ```ruby
124
124
  module UserIdentifiable
@@ -138,7 +138,9 @@ module UserIdentifiable
138
138
  end
139
139
  ```
140
140
 
141
- #### 3) Mix newly defined module into a class or another super module
141
+ Note: Even if you are including another [super module](#glossary-and-definitions) in your new [super module](#glossary-and-definitions), you must `include SuperModule` at the top of your module definition before anything else.
142
+
143
+ #### 3) Mix newly defined module into a class or another [super module](#glossary-and-definitions)
142
144
 
143
145
  ```ruby
144
146
  class ClubParticipation < ActiveRecord::Base
@@ -166,22 +168,21 @@ ClubParticipation.create(club_id: club.id, user_id: user.id).slug
166
168
  CourseEnrollment.new(course_id: course.id).valid?
167
169
  ```
168
170
 
169
- ## Glossary and Definitions
171
+ ## Usage Notes
170
172
 
171
- * SuperModule: name of the library and Ruby module that provides functionality via mixin
172
- * Super module: any Ruby module that mixes in SuperModule
173
- * Singleton class: also known as the [metaclass](https://rubymonk.com/learning/books/4-ruby-primer-ascent/chapters/39-ruby-s-object-model/lessons/131-singleton-methods-and-metaclasses) or [eigenclass](http://eigenjoy.com/2008/05/29/railsconf08-meta-programming-ruby-for-fun-and-profit/), it is the object-instance-associated class copy available to every object in Ruby (e.g. every `Object.new` instance has a singleton class that is a copy of the `Object` class, which can house instance-specific behavior if needed)
174
- * Singleton method: an instance method defined on an object's singleton class. Often used to refer to a class or module method defined on the [Ruby class object or module object singleton class](http://ruby-doc.com/docs/ProgrammingRuby/html/classes.html) via `def self.method_name(...)` or `class << self` enclosing `def method_name(...)`
175
- * Class method invocation: Inherited Ruby class or module method invoked in the body of a class or module (e.g. <code>validates :username, presence: true</code>)
176
- * Code-time: Time of writing code in a Ruby file as opposed to Run-time
177
- * Run-time: Time of executing Ruby code
173
+ * SuperModule must always be included at the top of a module's body at [code-time](#glossary-and-definitions)
174
+ * SuperModule inclusion can be optionally followed by other basic or [super module](#glossary-and-definitions) inclusions
175
+ * A [super module](#glossary-and-definitions) can only be included in a class or another [super module](#glossary-and-definitions)
178
176
 
179
- ## Usage Details
177
+ ## Glossary and Definitions
180
178
 
181
- * SuperModule must always be included at the top of a module's body at code-time
182
- * SuperModule inclusion can be optionally followed by other basic or super module inclusions
183
- * A super module can only be included in a class or another super module
184
- * SuperModule adds <b>zero cost</b> to instantiation of including classes and invocation of included methods (both class and instance)
179
+ * SuperModule: name of the library and Ruby module that provides functionality via mixin
180
+ * Super module: any Ruby module that mixes in SuperModule
181
+ * Singleton class: also known as the [metaclass](https://rubymonk.com/learning/books/4-ruby-primer-ascent/chapters/39-ruby-s-object-model/lessons/131-singleton-methods-and-metaclasses) or [eigenclass](http://eigenjoy.com/2008/05/29/railsconf08-meta-programming-ruby-for-fun-and-profit/), it is the object-instance-associated class copy available to every object in Ruby (e.g. every `Object.new` instance has a singleton class that is a copy of the `Object` class, which can house instance-specific behavior if needed)
182
+ * Singleton method: an instance method defined on an object's singleton class. Often used to refer to a class or module method defined on the [Ruby class object or module object singleton class](http://ruby-doc.com/docs/ProgrammingRuby/html/classes.html) via `def self.method_name(...)` or `class << self` enclosing `def method_name(...)`
183
+ * Class method invocation: Inherited Ruby class or module method invoked in the body of a class or module (e.g. <code>validates :username, presence: true</code>)
184
+ * Code-time: Time of writing code in a Ruby file as opposed to Run-time
185
+ * Run-time: Time of executing Ruby code
185
186
 
186
187
  ## IRB Example
187
188
 
@@ -192,25 +193,25 @@ require 'rubygems' # to be backwards compatible with Ruby 1.8.7
192
193
  require 'super_module'
193
194
 
194
195
  module RequiresAttributes
195
- include SuperModule
196
+ include SuperModule
196
197
 
197
- def self.requires(*attributes)
198
- attributes.each {|attribute| required_attributes << attribute}
199
- end
198
+ def self.requires(*attributes)
199
+ attributes.each {|attribute| required_attributes << attribute}
200
+ end
200
201
 
201
- def self.required_attributes
202
- @required_attributes ||= []
203
- end
202
+ def self.required_attributes
203
+ @required_attributes ||= []
204
+ end
204
205
 
205
- def requirements_satisfied?
206
- !!self.class.required_attributes.reduce(true) { |result, required_attribute| result && send(required_attribute) }
207
- end
206
+ def requirements_satisfied?
207
+ !!self.class.required_attributes.reduce(true) { |result, required_attribute| result && send(required_attribute) }
208
+ end
208
209
  end
209
210
 
210
211
  class MediaAuthorization
211
- include RequiresAttributes
212
- attr_accessor :user_id, :credit_card_id
213
- requires :user_id, :credit_card_id
212
+ include RequiresAttributes
213
+ attr_accessor :user_id, :credit_card_id
214
+ requires :user_id, :credit_card_id
214
215
  end
215
216
  ```
216
217
 
@@ -256,40 +257,121 @@ media_authorization.requirements_satisfied?
256
257
  ```
257
258
  => true
258
259
 
259
- ## How Does It Work?
260
-
261
- V2 has a much simpler algorithm than V1 that goes as follows:
260
+ ## Overriding `self.included(base)`
262
261
 
263
- 1. Handle invocation of `super_module(name, &super_module_body)` method anywhere in the Ruby code where the block it receives represents the super module body, including instance methods, and class methods, and class body invocations.
264
- 2. Clone `SuperModule` and store in it the passed in `super_module_body` block
265
- 3. Assign the cloned `SuperModule` to a new constant as defined by name (e.g. 'Utilities::Printer') under a class, module, or the top-level Ruby scope
266
- 4. When calling `include` on the module later on, its stored super_module_body attribute is retrieved and run in the including class or module body via `class_eval`
262
+ With `SuperModule`, hooking into `self.included(base)` is no longer needed for most cases. Still, there rare exceptions where that might be needed to execute some meta-programmatic logic. Fortunately, `SuperModule` offers a mechanism to do so.
267
263
 
268
- ## Warnings
264
+ `SuperModule` relies on `self.included(base)`, so modules mixing it in must refrain from implementing `self.included(base)` directly (`SuperModule` will automatically prevent that by providing instructions should one attempt to do so).
269
265
 
270
- 1) [SuperModule](https://rubygems.org/gems/super_module) by definition has been designed to be used only in the initial code declaration of a module, not later mixing or re-opening of a module.
266
+ In order for a [super module](#glossary-and-definitions) to hook into `self.included(base)` and add extra logic, it must do so via `super_module_included {|base| ... }` instead, which safely appends that logic to the work of `SuperModule` as well as other nested [super module](#glossary-and-definitions)s.
271
267
 
272
- 2) Given [SuperModule](https://rubygems.org/gems/super_module)'s implementation relies on `self.included(base)`, sub-modules must not hook into it.
268
+ Example:
273
269
 
274
- In very rare occasions when an including module needs to redefine <code>self.included(base)</code> for meta-programming purposes, you may do so at your own peril by first invoking <code>self.included_super_module(base)</code> like in this example:
275
270
  ```ruby
276
- module AdminIdentifiable
277
- include SuperModule
278
- include UserIdentifiable
279
-
280
- class << self
281
- def included(base)
282
- included_super_module(base)
283
- # do some extra rare meta-programming work
284
- # like conditional inclusion of other modules
285
- # or conditional definition of methods
286
- end
271
+ module V1::SummarizedActiveModel
272
+ include SuperModule
273
+
274
+ super_module_included do |klass|
275
+ if klass.name.split(/::/).last.start_with?('Fake')
276
+ klass.extend(FakeClassMethods1)
277
+ end
278
+ end
279
+
280
+ module FakeClassMethods1
281
+ def fake_summary
282
+ 'This is a fake summary.'
283
+ end
284
+ end
285
+
286
+ class << self
287
+ def self.validates(attribute, options = {})
288
+ validations << [attribute, options]
289
+ end
290
+
291
+ def self.validations
292
+ @validations ||= []
293
+ end
294
+
295
+ def summary
296
+ validations.flatten.map(&:to_s).join("/")
297
+ end
298
+ end
299
+ end
300
+
301
+ module V1::ExtraSummarizedActiveModel
302
+ include SuperModule
303
+
304
+ include ::V1::SummarizedActiveModel
305
+
306
+ super_module_included do |klass|
307
+ if klass.name.split(/::/).last.start_with?('Fake')
308
+ klass.extend(FakeClassMethods2)
309
+ end
310
+ end
311
+
312
+ module FakeClassMethods2
313
+ def fake_extra
314
+ 'This is fake extra.'
315
+ end
316
+ end
317
+
318
+ class << self
319
+ def extra
320
+ "This is extra."
287
321
  end
322
+ end
288
323
  end
324
+
325
+ class V1::SummarizedActiveRecord
326
+ include ::V1::SummarizedActiveModel
327
+ end
328
+
329
+ class V1::FakeSummarizedActiveRecord
330
+ include ::V1::SummarizedActiveModel
331
+ end
332
+
333
+ class V1::ExtraSummarizedActiveRecord
334
+ include ::V1::ExtraSummarizedActiveModel
335
+ end
336
+
337
+ class V1::FakeExtraSummarizedActiveRecord
338
+ include ::V1::ExtraSummarizedActiveModel
339
+ end
340
+
341
+ V1::SummarizedActiveRecord.validates 'foo', {:presence => true}
342
+ V1::SummarizedActiveRecord.validates 'bar', {:presence => true}
343
+ puts V1::SummarizedActiveRecord.summary
344
+ # prints 'foo/{:presence=>true}/bar/{:presence=>true}'
345
+
346
+ V1::FakeSummarizedActiveRecord.validates 'foo', {:presence => true}
347
+ V1::FakeSummarizedActiveRecord.validates 'bar', {:presence => true}
348
+ puts V1::FakeSummarizedActiveRecord.summary
349
+ # prints 'foo/{:presence=>true}/bar/{:presence=>true}'
350
+ puts V1::FakeSummarizedActiveRecord.fake_summary
351
+ # prints 'This is a fake summary.'
352
+
353
+ V1::ExtraSummarizedActiveRecord.validates 'foo', {:presence => true}
354
+ V1::ExtraSummarizedActiveRecord.validates 'bar', {:presence => true}
355
+ puts V1::ExtraSummarizedActiveRecord.summary
356
+ # prints 'foo/{:presence=>true}/bar/{:presence=>true}'
357
+ puts V1::ExtraSummarizedActiveRecord.extra
358
+ # prints 'This is extra.'
359
+
360
+ V1::FakeExtraSummarizedActiveRecord.validates 'foo', {:presence => true}
361
+ V1::FakeExtraSummarizedActiveRecord.validates 'bar', {:presence => true}
362
+ puts V1::FakeExtraSummarizedActiveRecord.summary
363
+ # prints 'foo/{:presence=>true}/bar/{:presence=>true}'
364
+ puts V1::FakeExtraSummarizedActiveRecord.fake_summary
365
+ # prints 'This is a fake summary.'
366
+ puts V1::FakeExtraSummarizedActiveRecord.extra
367
+ # prints 'This is extra.'
368
+ puts V1::FakeExtraSummarizedActiveRecord.fake_extra
369
+ # prints 'This is fake extra.'
289
370
  ```
290
- This does not work for all cases (like multiple levels of super module nesting), and is not recommended, likely causing problems.
291
371
 
292
- Avoid hooking into `self.included(base)` at all costs.
372
+ ## Limitations
373
+
374
+ 1) [SuperModule](https://rubygems.org/gems/super_module) by definition has been designed to be used only in the initial code declaration of a module, not later mixing or re-opening of a module.
293
375
 
294
376
  ## Change Log
295
377
 
@@ -309,10 +391,9 @@ The library is quite new and can use all the feedback and help it can get. So, p
309
391
 
310
392
  ## TODO
311
393
 
312
- - Fix issue where class methods cannot get called from super_module directly (when used with "CONSTANT = super_module do" approach)
313
- - Fix issue where a super module (declared with super_module) can get included in one class only where class methods work, but the next class that includes the super module does not have class methods work
394
+ None
314
395
 
315
396
  ## Copyright
316
397
 
317
- Copyright (c) 2014-2016 Andy Maleh. See LICENSE.txt for
398
+ Copyright (c) 2014-2020 Andy Maleh. See LICENSE.txt for
318
399
  further details.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.3.1
1
+ 1.4.0
@@ -5,6 +5,7 @@ module SuperModule
5
5
  module V1
6
6
  class << self
7
7
  def included(original_base)
8
+ # TODO maybe avoid class_eval by extending/including instead
8
9
  original_base.class_eval do
9
10
  extend SuperModule::V1::ModuleBodyMethodCallRecorder
10
11
  extend SuperModule::V1::SingletonMethodDefinitionStore
@@ -27,8 +28,21 @@ module SuperModule
27
28
  def included(base)
28
29
  __define_super_module_singleton_methods(base)
29
30
  __invoke_module_body_method_calls(base)
31
+ super_module_included.each {|block| block.call(base)}
32
+ if base.ancestors.include?(SuperModule) && !base.is_a?(Class)
33
+ super_module_included.reverse.each do |block|
34
+ base.super_module_included.unshift(block)
35
+ end
36
+ end
37
+ end
38
+
39
+ def super_module_included(&block)
40
+ if block_given?
41
+ super_module_included << block
42
+ else
43
+ @super_module_included_blocks ||= []
44
+ end
30
45
  end
31
- alias included_super_module included
32
46
  end
33
47
  end
34
48
  end
@@ -4,7 +4,7 @@ module SuperModule
4
4
  def __super_module_singleton_methods_excluded_from_call_recording
5
5
  @__super_module_singleton_methods_excluded_from_call_recording ||= [
6
6
  :__record_method_call,
7
- :__method_signature
7
+ :__method_signature,
8
8
  ]
9
9
  end
10
10
 
@@ -16,7 +16,6 @@ module SuperModule
16
16
  "#{method_name}(#{args.to_a.map(&:to_s).join(",")})"
17
17
  end
18
18
 
19
- #TODO handle case of a method call being passed a block (e.g. validates do custom validator end )
20
19
  def __record_method_call(method_name, *args, &block)
21
20
  return if self.is_a?(Class)
22
21
  __module_body_method_calls << [method_name, args, block]
@@ -27,10 +27,9 @@ module SuperModule
27
27
  :dbg_puts, #debugger library friendly exclusion
28
28
  :define,
29
29
  :included,
30
- :included_super_module,
30
+ :super_module_included,
31
31
  :included_super_modules,
32
32
  :singleton_method_added,
33
- :super_module_body
34
33
  ]
35
34
  end
36
35
 
@@ -70,11 +69,14 @@ module SuperModule
70
69
  end
71
70
 
72
71
  def __build_singleton_method_body_source(method_name)
73
- method_body = self.method(method_name).source
74
- method_args = __singleton_method_args(method_name, method_body)
72
+ the_method = self.method(method_name)
73
+ method_body = the_method.source
74
+ method_original_name = the_method.original_name
75
+ aliased = method_original_name != method_name
76
+ method_args = __singleton_method_args(method_original_name, method_body)
75
77
  method_body = "def #{method_name}\n#{method_body}\nend" if method_args.nil?
76
78
  class_self_method_def_enclosure = "class << self\n#{__singleton_method_access_level(method_name)}\ndef #{method_name}(#{method_args})\n#{__singleton_method_call_recorder(method_name, method_args)}\n"
77
- method_body.sub(__singleton_method_definition_regex(method_name), class_self_method_def_enclosure) + "\nend\n"
79
+ method_body.sub(__singleton_method_definition_regex(method_original_name), class_self_method_def_enclosure) + "\nend\n"
78
80
  end
79
81
 
80
82
  def __singleton_method_body(method_name)
@@ -90,6 +92,9 @@ module SuperModule
90
92
  end
91
93
 
92
94
  def singleton_method_added(method_name)
95
+ if method_name.to_s == 'included' && !method(method_name).source_location.first.include?('super_module/v1')
96
+ raise 'Do not implement "self.included(base)" hook for a super module! Use "super_module_included {|base| ... }" instead.'
97
+ end
93
98
  unless __super_module_singleton_methods_excluded_from_base_definition.include?(method_name)
94
99
  method_body = __singleton_method_body(method_name)
95
100
  __super_module_singleton_methods << [method_name, method_body]
@@ -98,7 +103,7 @@ module SuperModule
98
103
  end
99
104
 
100
105
  def self.extended(base)
101
- base.extend(SuperModule::ModuleBodyMethodCallRecorder) unless base.respond_to?(:__record_method_call)
106
+ base.extend(SuperModule::V1::ModuleBodyMethodCallRecorder) unless base.is_a?(SuperModule::V1::ModuleBodyMethodCallRecorder)
102
107
  base.singleton_method_added(:__method_signature)
103
108
  base.singleton_method_added(:__record_method_call)
104
109
  end
@@ -19,28 +19,53 @@ end
19
19
  module V1::SummarizedActiveModel
20
20
  include SuperModule
21
21
 
22
- def self.included(klass)
23
- included_super_module(klass)
22
+ super_module_included do |klass|
24
23
  if klass.name.split(/::/).last.start_with?('Fake')
25
- klass.extend(FakeClassMethods)
24
+ klass.extend(FakeClassMethods1)
26
25
  end
27
26
  end
28
-
29
- def self.validates(attribute, options)
30
- super # test that singleton class inheritance works
27
+
28
+ module FakeClassMethods1
29
+ def fake_summary
30
+ 'This is a fake summary.'
31
+ end
32
+ end
33
+
34
+ class << self
35
+ def validates(attribute, options)
36
+ super # test that singleton class inheritance works
37
+ end
38
+
39
+ def validations
40
+ super # test that singleton class inheritance works
41
+ end
42
+
43
+ def summary
44
+ validations.flatten.map(&:to_s).join("/")
45
+ end
31
46
  end
47
+ end
48
+
49
+ module V1::ExtraSummarizedActiveModel
50
+ include SuperModule
32
51
 
33
- def self.validations
34
- super # test that singleton class inheritance works
52
+ include ::V1::SummarizedActiveModel
53
+
54
+ super_module_included do |klass|
55
+ if klass.name.split(/::/).last.start_with?('Fake')
56
+ klass.extend(FakeClassMethods2)
57
+ end
35
58
  end
36
59
 
37
- def self.summary
38
- validations.flatten.map(&:to_s).join("/")
60
+ module FakeClassMethods2
61
+ def fake_extra
62
+ 'This is fake extra.'
63
+ end
39
64
  end
40
65
 
41
- module FakeClassMethods
42
- def fake_summary
43
- 'This is a fake summary.'
66
+ class << self
67
+ def extra
68
+ "This is extra."
44
69
  end
45
70
  end
46
71
  end
@@ -53,6 +78,14 @@ class V1::FakeSummarizedActiveRecord < V1::FakeActiveRecord
53
78
  include ::V1::SummarizedActiveModel
54
79
  end
55
80
 
81
+ class V1::ExtraSummarizedActiveRecord < V1::FakeActiveRecord
82
+ include ::V1::ExtraSummarizedActiveModel
83
+ end
84
+
85
+ class V1::FakeExtraSummarizedActiveRecord < V1::FakeActiveRecord
86
+ include ::V1::ExtraSummarizedActiveModel
87
+ end
88
+
56
89
  describe SuperModule do
57
90
  context V1 do
58
91
  context "standalone module usage" do
@@ -62,6 +95,16 @@ describe SuperModule do
62
95
  subject.validates 'foo', {:presence => true}
63
96
  expect(subject.validations).to include(['foo', {:presence => true}])
64
97
  end
98
+
99
+ it 'raises error if super module implements self.included(base)' do
100
+ expect do
101
+ module SomeSuperModule
102
+ include SuperModule
103
+ def self.included(base)
104
+ end
105
+ end
106
+ end.to raise_error('Do not implement "self.included(base)" hook for a super module! Use "super_module_included {|base| ... }" instead.')
107
+ end
65
108
  end
66
109
 
67
110
  context "included by a module (Foo) that is included by a class (FooActiveRecord)" do
@@ -252,6 +295,22 @@ describe SuperModule do
252
295
  expect(V1::FakeSummarizedActiveRecord.summary).to eq('foo/{:presence=>true}/bar/{:presence=>true}')
253
296
  expect(V1::FakeSummarizedActiveRecord.fake_summary).to eq('This is a fake summary.')
254
297
  end
298
+ it 'returns extra' do
299
+ V1::ExtraSummarizedActiveRecord.validates 'foo', {:presence => true}
300
+ V1::ExtraSummarizedActiveRecord.validates 'bar', {:presence => true}
301
+ expect(V1::ExtraSummarizedActiveRecord.summary).to eq('foo/{:presence=>true}/bar/{:presence=>true}')
302
+ expect{V1::ExtraSummarizedActiveRecord.fake_summary}.to raise_error
303
+ expect(V1::ExtraSummarizedActiveRecord.extra).to eq('This is extra.')
304
+ expect{V1::ExtraSummarizedActiveRecord.fake_extra}.to raise_error
305
+ end
306
+ it 'returns fake extra' do
307
+ V1::FakeExtraSummarizedActiveRecord.validates 'foo', {:presence => true}
308
+ V1::FakeExtraSummarizedActiveRecord.validates 'bar', {:presence => true}
309
+ expect(V1::FakeExtraSummarizedActiveRecord.summary).to eq('foo/{:presence=>true}/bar/{:presence=>true}')
310
+ expect(V1::FakeExtraSummarizedActiveRecord.fake_summary).to eq('This is a fake summary.')
311
+ expect(V1::FakeExtraSummarizedActiveRecord.extra).to eq('This is extra.')
312
+ expect(V1::FakeExtraSummarizedActiveRecord.fake_extra).to eq('This is fake extra.')
313
+ end
255
314
  end
256
315
  end
257
316
  end
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: super_module 1.3.1 ruby lib
5
+ # stub: super_module 1.4.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "super_module".freeze
9
- s.version = "1.3.1"
9
+ s.version = "1.4.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
13
  s.authors = ["Andy Maleh".freeze]
14
- s.date = "2020-03-28"
14
+ s.date = "2020-04-06"
15
15
  s.description = "SuperModule allows defining class methods and method invocations the same way a super class does without using def included(base). This also succeeds ActiveSupport::Concern by offering lighter syntax".freeze
16
16
  s.extra_rdoc_files = [
17
17
  "CHANGELOG.md",
@@ -46,7 +46,7 @@ Gem::Specification.new do |s|
46
46
  s.specification_version = 4
47
47
 
48
48
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
49
- s.add_runtime_dependency(%q<method_source>.freeze, [">= 0.8.2"])
49
+ s.add_runtime_dependency(%q<method_source>.freeze, [">= 0.8.2", "< 1.1.0"])
50
50
  s.add_development_dependency(%q<jeweler>.freeze, ["~> 2.3.0"])
51
51
  s.add_development_dependency(%q<rdoc>.freeze, ["~> 4.2.0"])
52
52
  s.add_development_dependency(%q<rspec>.freeze, ["~> 3.2.0"])
@@ -57,7 +57,7 @@ Gem::Specification.new do |s|
57
57
  s.add_development_dependency(%q<tins>.freeze, ["~> 1.6.0"])
58
58
  s.add_development_dependency(%q<term-ansicolor>.freeze, ["~> 1.3.2"])
59
59
  else
60
- s.add_dependency(%q<method_source>.freeze, [">= 0.8.2"])
60
+ s.add_dependency(%q<method_source>.freeze, [">= 0.8.2", "< 1.1.0"])
61
61
  s.add_dependency(%q<jeweler>.freeze, ["~> 2.3.0"])
62
62
  s.add_dependency(%q<rdoc>.freeze, ["~> 4.2.0"])
63
63
  s.add_dependency(%q<rspec>.freeze, ["~> 3.2.0"])
@@ -69,7 +69,7 @@ Gem::Specification.new do |s|
69
69
  s.add_dependency(%q<term-ansicolor>.freeze, ["~> 1.3.2"])
70
70
  end
71
71
  else
72
- s.add_dependency(%q<method_source>.freeze, [">= 0.8.2"])
72
+ s.add_dependency(%q<method_source>.freeze, [">= 0.8.2", "< 1.1.0"])
73
73
  s.add_dependency(%q<jeweler>.freeze, ["~> 2.3.0"])
74
74
  s.add_dependency(%q<rdoc>.freeze, ["~> 4.2.0"])
75
75
  s.add_dependency(%q<rspec>.freeze, ["~> 3.2.0"])
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: super_module
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Maleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-28 00:00:00.000000000 Z
11
+ date: 2020-04-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: method_source
@@ -17,6 +17,9 @@ dependencies:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 0.8.2
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: 1.1.0
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -24,6 +27,9 @@ dependencies:
24
27
  - - ">="
25
28
  - !ruby/object:Gem::Version
26
29
  version: 0.8.2
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: 1.1.0
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: jeweler
29
35
  requirement: !ruby/object:Gem::Requirement