ruby-features 1.1.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 27643cb1fa6b12baf10bf86fbc40226e2e70bc08
4
+ data.tar.gz: 2be53a6cc1404b1709b910fb8390663f4fc2d801
5
+ SHA512:
6
+ metadata.gz: c03d3cef6917da453e06c12184e31988366f42183ed170a6308049ce87dd8790dfafb3a41df9151a49672c7d1a161359634638f3873f11b60d0695cbdc89f6d0
7
+ data.tar.gz: 170853e803e73904e1755fc688e24032d45df28304a5f12427f4e9a3f259b3de9a6978afb6f67c36af5ee4da7fb12836a894a786abc078ccba58c22383ba8a44
data/README.md CHANGED
@@ -5,10 +5,10 @@ Ruby Features
5
5
  [![Climate](https://codeclimate.com/github/stokarenko/ruby-features/badges/gpa.svg)](https://codeclimate.com/github/stokarenko/ruby-features)
6
6
  [![Coverage](https://codeclimate.com/github/stokarenko/ruby-features/badges/coverage.svg)](https://codeclimate.com/github/stokarenko/ruby-features/coverage)
7
7
 
8
- Ruby Features makes the extending of Ruby classes and modules to be easy, safe and controlled.
8
+ Ruby Features allow the extending of Ruby classes and modules to become easy, safe and controlled.
9
9
 
10
10
  ## Why?
11
- Lets ask, is good to write the code like this:
11
+ Lets ask, is that good to write the code like this:
12
12
  ```ruby
13
13
  String.send :include, MyStringExtension
14
14
  ```
@@ -22,7 +22,7 @@ Object.class_eval do
22
22
  end
23
23
  ```
24
24
 
25
- The question is about motivation to write such things. Lets skip well-known reason like
25
+ The matter is in motivation to write such things. Lets skip the well-known reasons like
26
26
  > Because I can! That is Ruby baby, lets make some anarchy!
27
27
 
28
28
  but say:
@@ -37,12 +37,12 @@ library, infected by massive patches to core entities.
37
37
  Ruby Features goal is to take that under control.
38
38
 
39
39
  The main features are:
40
- * No any dependencies;
40
+ * No dependencies;
41
41
  * Built-in lazy load;
42
42
  * Supports ActiveSupport lazy load as well;
43
43
  * Stimulates the clear extending, but prevents monkey patching;
44
44
  * Gives the control what core extensions to apply;
45
- * Any moment gives the knowledge who and how exactly affected to programming entities.
45
+ * Gives the understading who and how exactly affected to programming entities.
46
46
 
47
47
  ## requirements
48
48
  * Ruby >= 1.9.3
@@ -68,7 +68,7 @@ to apply third-party features.
68
68
 
69
69
  ## Usage
70
70
  ### Feature definition
71
- Feature file name should ends with `_feature.rb`.
71
+ Feature file name should end with `_feature.rb`.
72
72
 
73
73
  Lets define the feature in `lib/features/something_useful_feature.rb`:
74
74
  ```ruby
@@ -80,6 +80,16 @@ RubyFeatures.define 'some_namespace/something_useful' do
80
80
  attr_accessor :useful_variable
81
81
  end
82
82
 
83
+ rewrite_instance_methods do
84
+ # rewrite instance methods
85
+ # call `super` to reach the rewritten method
86
+ def existing_instance_method
87
+ # some code before super
88
+ super
89
+ # some code after super
90
+ end
91
+ end
92
+
83
93
  instance_methods do
84
94
  # instance methods
85
95
  def useful_instance_method
@@ -91,17 +101,17 @@ RubyFeatures.define 'some_namespace/something_useful' do
91
101
  def useful_class_method
92
102
  end
93
103
  end
104
+ end
94
105
 
95
- apply_to 'ActiveRecord::Relation' do
96
- # feature can contain several apply_to definition
97
- end
98
-
106
+ apply_to 'ActiveRecord::Relation' do
107
+ # feature can contain several apply_to definition
99
108
  end
109
+
100
110
  end
101
111
  ```
102
112
 
103
113
  ### Dependencies
104
- The dependencies from other Ruby Features can be defined like:
114
+ The dependencies on other Ruby Features can be defined like:
105
115
  ```ruby
106
116
  RubyFeatures.define 'main_feature' do
107
117
  dependency 'dependent_feature1'
@@ -110,7 +120,7 @@ end
110
120
  ```
111
121
 
112
122
  ### Conditions
113
- Sometimes is required to apply different things, dependent on some criteria:
123
+ Sometimes it`s required to apply different things, depending on some criteria:
114
124
  ```ruby
115
125
  RubyFeatures.define 'some_namespace/something_useful' do
116
126
  apply_to 'ActiveRecord::Base' do
@@ -131,7 +141,7 @@ end
131
141
  ```
132
142
 
133
143
  It's bad to do like that, because the mixin applied by Ruby Features became to be not static.
134
- That cause not predictable behavior.
144
+ That causes unpredictable behavior.
135
145
 
136
146
  Ruby Features provides the `conditions` mechanism to avoid such problem:
137
147
  ```ruby
@@ -156,7 +166,7 @@ RubyFeatures.define 'some_namespace/something_useful' do
156
166
  end
157
167
  ```
158
168
 
159
- All feature definition helpers supports the conditions:
169
+ All DSL methods support the conditions:
160
170
  ```ruby
161
171
  apply_to 'ActiveRecord::Base', if: :first_criteria do; end
162
172
 
@@ -218,14 +228,14 @@ RubyFeatures.find_in_path(File.expand_path('../lib/features', __FILE__))
218
228
  ```
219
229
 
220
230
  ### Feature applying
221
- Feature can be applied immediately after it's definition:
231
+ Feature can be applied immediately after its definition:
222
232
  ```ruby
223
233
  RubyFeatures.define 'some_namespace/something_useful' do
224
234
  # definition
225
235
  end.apply
226
236
  ```
227
237
 
228
- Features can be applied right after loading from path:
238
+ Features can be applied immediately after loading from path:
229
239
  ```ruby
230
240
  RubyFeatures.find_in_path(File.expand_path('../lib/features', __FILE__)).apply_all
231
241
  ```
@@ -238,12 +248,12 @@ RubyFeatures.apply 'some_namespace/something_useful'
238
248
  ```
239
249
 
240
250
  ## Changes
251
+ ### v1.2.0
252
+ * Added rewrite_instance_methods.
253
+
241
254
  ### v1.1.0
242
255
  * Added conditions.
243
256
  * Added dependencies.
244
257
 
245
- ## TODO
246
- * ActionDispatch with ActiveSupport lazy_load
247
-
248
258
  ## License
249
259
  MIT License. Copyright (c) 2015 Sergey Tokarenko
@@ -33,18 +33,29 @@ module RubyFeatures
33
33
  _methods('Include', asserts, block)
34
34
  end
35
35
 
36
+ def rewrite_instance_methods(asserts = {}, &block)
37
+ _methods('RewriteInstance', asserts, block)
38
+ end
39
+
36
40
  def _apply_methods(target_class)
37
41
  constants.each do |constant|
38
- mixin_method, existing_methods_method = case(constant)
39
- when /^Extend/ then [:extend, :methods]
40
- when /^Include/ then [:include, :instance_methods]
42
+ mixin_method, existing_methods_method, existing_methods_check = case(constant)
43
+ when /^Extend/ then [:extend, :methods, :exclusion]
44
+ when /^Include/ then [:include, :instance_methods, :exclusion]
45
+ when /^RewriteInstance/ then [:prepend, :instance_methods, :inclusion]
41
46
  else raise ArgumentError.new("Wrong mixin constant: #{constant}")
42
47
  end
43
48
 
44
49
  mixin = const_get(constant)
45
50
 
46
- common_methods = target_class.public_send(existing_methods_method) & mixin.instance_methods
47
- raise NameError.new("Tried to #{mixin_method} already existing methods: #{common_methods.inspect}") unless common_methods.empty?
51
+ case(existing_methods_check)
52
+ when :exclusion
53
+ existing_methods = mixin.instance_methods & target_class.public_send(existing_methods_method)
54
+ raise NameError.new("Tried to #{mixin_method} already existing methods: #{existing_methods.inspect}") unless existing_methods.empty?
55
+ when :inclusion
56
+ not_existing_methods = mixin.instance_methods - target_class.public_send(existing_methods_method)
57
+ raise NameError.new("Tried to #{mixin_method} not existing methods: #{not_existing_methods.inspect}") unless not_existing_methods.empty?
58
+ end
48
59
 
49
60
  target_class.send(mixin_method, mixin)
50
61
  end
@@ -1,3 +1,3 @@
1
1
  module RubyFeatures
2
- VERSION = '1.1.2'.freeze
2
+ VERSION = '1.2.0'.freeze
3
3
  end
data/spec/define_spec.rb CHANGED
@@ -31,6 +31,28 @@ describe RubyFeatures::Concern::Feature do
31
31
  )
32
32
  end
33
33
 
34
+ it 'should apply rewrite instance methods' do
35
+ test_class.class_eval do
36
+ def test_rewrite_instance_method
37
+ 2
38
+ end
39
+ end
40
+
41
+ expect{
42
+ define_test_feature('rewrite_instance_methods_feature') do
43
+ rewrite_instance_methods do
44
+ def test_rewrite_instance_method
45
+ 3 * super
46
+ end
47
+ end
48
+ end.apply
49
+ }.to change{test_class.new.test_rewrite_instance_method}.from(2).to(6)
50
+
51
+ expect(test_class.included_modules).to include(
52
+ RubyFeatures::Mixins::DefineTestModule::DefineTestClass::RewriteInstanceMethodsFeature::DefineTestModule::DefineTestClass::RewriteInstance
53
+ )
54
+ end
55
+
34
56
  it 'should process applied block' do
35
57
  expect{
36
58
  define_test_feature('applied_block') do
@@ -75,4 +97,14 @@ describe RubyFeatures::Concern::Feature do
75
97
  }.to raise_error(/Tried to include already existing methods: \[:existing_instance_method\]/)
76
98
  end
77
99
 
100
+ it 'should raise error if target has no feature rewrite instance method' do
101
+ expect{
102
+ define_test_feature('not_existing_rewrite_instance_method') do
103
+ rewrite_instance_methods do
104
+ def not_existing_instance_method; end
105
+ end
106
+ end.apply
107
+ }.to raise_error(/Tried to prepend not existing methods: \[:not_existing_instance_method\]/)
108
+ end
109
+
78
110
  end
metadata CHANGED
@@ -1,30 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-features
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
5
- prerelease:
4
+ version: 1.2.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Sergey Tokarenko
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2015-06-01 00:00:00.000000000 Z
11
+ date: 2016-08-26 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: bundler
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :development
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - ">="
28
25
  - !ruby/object:Gem::Version
29
26
  version: '0'
30
27
  description: Makes extending of Ruby classes and modules to be easy, safe and controlled.
@@ -33,23 +30,23 @@ executables: []
33
30
  extensions: []
34
31
  extra_rdoc_files: []
35
32
  files:
33
+ - LICENSE
34
+ - README.md
36
35
  - lib/generators/ruby_features/install_generator.rb
37
36
  - lib/generators/ruby_features/templates/ruby-features.rb
37
+ - lib/ruby-features.rb
38
38
  - lib/ruby-features/concern/apply_to.rb
39
39
  - lib/ruby-features/concern/feature.rb
40
40
  - lib/ruby-features/conditions.rb
41
41
  - lib/ruby-features/container.rb
42
42
  - lib/ruby-features/lazy.rb
43
43
  - lib/ruby-features/mixins.rb
44
+ - lib/ruby-features/utils.rb
44
45
  - lib/ruby-features/utils/const_accessor_19.rb
45
46
  - lib/ruby-features/utils/const_accessor_20.rb
46
47
  - lib/ruby-features/utils/inflector.rb
47
48
  - lib/ruby-features/utils/inflector_active_support.rb
48
- - lib/ruby-features/utils.rb
49
49
  - lib/ruby-features/version.rb
50
- - lib/ruby-features.rb
51
- - LICENSE
52
- - README.md
53
50
  - spec/conditions_spec.rb
54
51
  - spec/define_spec.rb
55
52
  - spec/find_and_apply_spec.rb
@@ -62,27 +59,26 @@ files:
62
59
  homepage: https://github.com/stokarenko/ruby-features
63
60
  licenses:
64
61
  - MIT
62
+ metadata: {}
65
63
  post_install_message:
66
64
  rdoc_options: []
67
65
  require_paths:
68
66
  - lib
69
67
  required_ruby_version: !ruby/object:Gem::Requirement
70
- none: false
71
68
  requirements:
72
- - - ! '>='
69
+ - - ">="
73
70
  - !ruby/object:Gem::Version
74
- version: 1.9.3
71
+ version: 2.0.0
75
72
  required_rubygems_version: !ruby/object:Gem::Requirement
76
- none: false
77
73
  requirements:
78
- - - ! '>='
74
+ - - ">="
79
75
  - !ruby/object:Gem::Version
80
76
  version: '0'
81
77
  requirements: []
82
78
  rubyforge_project:
83
- rubygems_version: 1.8.23.2
79
+ rubygems_version: 2.5.1
84
80
  signing_key:
85
- specification_version: 3
81
+ specification_version: 4
86
82
  summary: Makes extending of Ruby classes and modules to be easy, safe and controlled.
87
83
  test_files:
88
84
  - spec/conditions_spec.rb