proxy_method 0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d326c1e11ed5cd4cc667d4687a7290d0fb157284a51d19a8fbf08ba1f97c65cf
4
+ data.tar.gz: 986f2c19ece82f97e8f28c6d846f14661e2ba400d28983f28ce04c786052bcb9
5
+ SHA512:
6
+ metadata.gz: da246a3fd150d0f55649db524a7b0f68205aaaa59885b382b42ee3fb8705512e0093138760a827f677401483778c5dda94d1a87982171216a47e34f91813261e
7
+ data.tar.gz: daefa8c60fe9e5bf4f29cac4cf87ae8aaf80e1c4f9f7fef4ef91d3a3a7e699d883b8990ce7a294901bbd08ec9643897e0f03a3d56b4f774382320c08a9e34156
data/README.md ADDED
@@ -0,0 +1,118 @@
1
+ # proxy_method
2
+
3
+ Prevent running an inherited method directly.
4
+
5
+ The purpose of this gem is to prevent directly running the inherited
6
+ methods you choose to block, and instead raise a custom Error message.
7
+ The original method can still be called under a different name.
8
+
9
+ This was created to help enforce the use of interactors over directly
10
+ calling ActiveRecord methods like create, save, and update. One downside
11
+ of interactors is that they require top-of-mind awareness in order to use
12
+ them, and by default new/forgetful/overworked developers will create
13
+ ActiveRecord instances all willy nilly until society crumbles.
14
+
15
+ While this was created for ActiveRecord models specifically, it works
16
+ with *any* inherited methods. The method being proxied has to already
17
+ exist, or it can't be overridden.
18
+
19
+ ## Usage
20
+
21
+ Given these basic classes:
22
+
23
+ class Animal
24
+ def self.create
25
+ 'created'
26
+ end
27
+
28
+ def save
29
+ 'saved'
30
+ end
31
+
32
+ def update
33
+ 'updated'
34
+ end
35
+ end
36
+
37
+ class Turtle < Animal
38
+ include ProxyMethod
39
+
40
+ proxy_class_method :create
41
+ proxy_instance_method :save
42
+
43
+ # for instance methods, you can also just call "proxy_method"
44
+ proxy_method :update
45
+ end
46
+
47
+ You can do this:
48
+
49
+ Turtle.create
50
+ # => RuntimeError: Disabled by proxy_method
51
+
52
+ Turtle.new.save
53
+ # => RuntimeError: Disabled by proxy_method
54
+
55
+ Turtle.proxied_create
56
+ # => 'created'
57
+
58
+ Turtle.new.proxied_save
59
+ # => 'saved'
60
+
61
+ Specify a custom error message:
62
+
63
+ class CustomCow < Animal
64
+ include ProxyMethod
65
+
66
+ proxy_method :save, message: "Don't save here, use an interactor!"
67
+ end
68
+
69
+ CustomCow.new.save
70
+ # => RunTimeError: Don't save here, use an interactor!
71
+
72
+ Specify multiple methods at once:
73
+
74
+ class MultiMonkey < Animal
75
+ include ProxyMethod
76
+
77
+ proxy_method [:save, :update], message: "Use an interactor!"
78
+ end
79
+
80
+ MultiMonkey.new.save
81
+ # => RunTimeError: Use an interactor!
82
+
83
+ MultiMonkey.new.update
84
+ # => RunTimeError: Use an interactor!
85
+
86
+ Supply your own prefix for the original, unproxied method:
87
+
88
+ class PrefixPelican < Animal
89
+ include ProxyMethod
90
+
91
+ proxy_method :save, prefix: 'pelican'
92
+ end
93
+
94
+ PrefixPelican.new.pelican_save
95
+ # => 'saved'
96
+
97
+ ## Installation
98
+ Add this line to your application's Gemfile:
99
+
100
+ ```ruby
101
+ gem 'proxy_method'
102
+ ```
103
+
104
+ And then execute:
105
+ ```bash
106
+ $ bundle
107
+ ```
108
+
109
+ Or install it yourself as:
110
+ ```bash
111
+ $ gem install proxy_method
112
+ ```
113
+
114
+ ## Contributing
115
+ Feel free to fork and create a pull request.
116
+
117
+ ## License
118
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.libs << 'test'
5
+ end
6
+
7
+ desc "Run tests"
8
+ task :default => :test
@@ -0,0 +1,32 @@
1
+ module ProxyMethod
2
+ module ClassMethods
3
+ DEFAULT_PROXY_MESSAGE = 'Disabled by proxy_method'
4
+ DEFAULT_PREFIX = 'unproxied_'
5
+
6
+ def proxy_class_method(original_method_names, options = {})
7
+ error_message = options[:message] || DEFAULT_PROXY_MESSAGE
8
+ prefix = options[:prefix] || DEFAULT_PREFIX
9
+
10
+ Array(original_method_names).each do |original_method_name|
11
+ self.singleton_class.send(:alias_method, :"#{prefix}#{original_method_name}", original_method_name)
12
+ define_singleton_method(original_method_name){ raise error_message }
13
+ end
14
+ end
15
+
16
+ def proxy_instance_method(original_method_names, options = {})
17
+ error_message = options[:message] || DEFAULT_PROXY_MESSAGE
18
+ prefix = options[:prefix] || DEFAULT_PREFIX
19
+
20
+ Array(original_method_names).each do |original_method_name|
21
+ alias_method :"#{prefix}#{original_method_name}", original_method_name
22
+ define_method(original_method_name){ raise error_message }
23
+ end
24
+ end
25
+
26
+ alias_method :proxy_method, :proxy_instance_method
27
+ end
28
+
29
+ def self.included(base)
30
+ base.extend ClassMethods
31
+ end
32
+ end
@@ -0,0 +1,3 @@
1
+ module ProxyMethod
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,171 @@
1
+ require 'minitest/autorun'
2
+ require 'proxy_method'
3
+
4
+ class Animal
5
+ def self.create
6
+ 'created'
7
+ end
8
+
9
+ def self.destroy_all
10
+ 'destroyed'
11
+ end
12
+
13
+ def save
14
+ 'saved'
15
+ end
16
+
17
+ def update
18
+ 'updated'
19
+ end
20
+ end
21
+
22
+ class Turtle < Animal
23
+ include ProxyMethod
24
+
25
+ proxy_class_method :create, message: "Don't Create directly, use Interactor!"
26
+ proxy_instance_method :update, message: "Don't Update directly, use Interactor!"
27
+ proxy_method :save, message: "Don't Save directly, use Interactor!"
28
+ end
29
+
30
+ class DefaultDuck < Animal
31
+ include ProxyMethod
32
+
33
+ proxy_class_method :create
34
+ proxy_method :save
35
+ end
36
+
37
+ class MultiMonkey < Animal
38
+ include ProxyMethod
39
+
40
+ proxy_class_method [:create, :destroy_all]
41
+ proxy_method [:save, :update]
42
+ end
43
+
44
+ class PrefixPelican < Animal
45
+ include ProxyMethod
46
+
47
+ proxy_class_method :create, prefix: 'pelican_'
48
+ proxy_method :save, prefix: 'pelican_'
49
+ end
50
+
51
+ class ProxyMethodTest < MiniTest::Test
52
+ describe "proxying class methods" do
53
+ it "does not allow original method name to be called" do
54
+ exception = assert_raises StandardError do
55
+ Turtle.create
56
+ end
57
+
58
+ assert_equal "Don't Create directly, use Interactor!", exception.message
59
+ end
60
+
61
+ it "allows proxied method name to be called" do
62
+ assert 'created', Turtle.unproxied_create
63
+ end
64
+
65
+ it "does not confuse proxied class method with instance method" do
66
+ assert_raises NoMethodError do
67
+ Turtle.save
68
+ end
69
+
70
+ assert_raises NoMethodError do
71
+ Turtle.unproxied_save
72
+ end
73
+ end
74
+
75
+ it "provides default error message" do
76
+ exception = assert_raises StandardError do
77
+ DefaultDuck.create
78
+ end
79
+
80
+ assert_equal "Disabled by proxy_method", exception.message
81
+ end
82
+
83
+ it "allows for multiple methods to be proxied in one call" do
84
+ exception = assert_raises StandardError do
85
+ MultiMonkey.create
86
+ end
87
+
88
+ assert_equal "Disabled by proxy_method", exception.message
89
+
90
+ exception = assert_raises StandardError do
91
+ MultiMonkey.destroy_all
92
+ end
93
+
94
+ assert_equal "Disabled by proxy_method", exception.message
95
+ end
96
+
97
+ it "allows for a custom prefix" do
98
+ exception = assert_raises StandardError do
99
+ PrefixPelican.create
100
+ end
101
+
102
+ assert_equal "Disabled by proxy_method", exception.message
103
+
104
+ assert 'created', PrefixPelican.pelican_create
105
+ end
106
+ end
107
+
108
+ describe "proxying instance methods" do
109
+ it "does not allow original method name to be called" do
110
+ exception = assert_raises StandardError do
111
+ Turtle.new.save
112
+ end
113
+
114
+ assert_equal "Don't Save directly, use Interactor!", exception.message
115
+ end
116
+
117
+ it "allows proxied method name to be called" do
118
+ assert 'saved', Turtle.new.unproxied_save
119
+ end
120
+
121
+ it "does not confuse proxied class method with instance method" do
122
+ assert_raises NoMethodError do
123
+ Turtle.new.create
124
+ end
125
+
126
+ assert_raises NoMethodError do
127
+ Turtle.new.unproxied_create
128
+ end
129
+ end
130
+
131
+ it "aliases proxy_method to proxy_instance_method" do
132
+ exception = assert_raises StandardError do
133
+ Turtle.new.update
134
+ end
135
+
136
+ assert_equal "Don't Update directly, use Interactor!", exception.message
137
+ end
138
+
139
+ it "provides default error message" do
140
+ exception = assert_raises StandardError do
141
+ DefaultDuck.new.save
142
+ end
143
+
144
+ assert_equal "Disabled by proxy_method", exception.message
145
+ end
146
+
147
+ it "allows for multiple methods to be proxied in one call" do
148
+ exception = assert_raises StandardError do
149
+ MultiMonkey.new.save
150
+ end
151
+
152
+ assert_equal "Disabled by proxy_method", exception.message
153
+
154
+ exception = assert_raises StandardError do
155
+ MultiMonkey.new.update
156
+ end
157
+
158
+ assert_equal "Disabled by proxy_method", exception.message
159
+ end
160
+
161
+ it "allows for a custom prefix" do
162
+ exception = assert_raises StandardError do
163
+ PrefixPelican.new.save
164
+ end
165
+
166
+ assert_equal "Disabled by proxy_method", exception.message
167
+
168
+ assert 'saved', PrefixPelican.new.pelican_save
169
+ end
170
+ end
171
+ end
metadata ADDED
@@ -0,0 +1,54 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: proxy_method
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jaime Bellmyer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-12-18 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: |2
14
+ The purpose of this gem is to prevent directly running the inherited
15
+ methods you choose to block, and instead raise a custom Error message.
16
+ The original method can still be called under a different name.
17
+
18
+ This was created to help enforce the use of interactors over directly
19
+ calling ActiveRecord methods like create, save, and update.
20
+ email:
21
+ - online@bellmyer.com
22
+ executables: []
23
+ extensions: []
24
+ extra_rdoc_files: []
25
+ files:
26
+ - README.md
27
+ - Rakefile
28
+ - lib/proxy_method.rb
29
+ - lib/proxy_method/version.rb
30
+ - test/test_proxy_method.rb
31
+ homepage: https://rubygems.org/gems/proxy_method
32
+ licenses:
33
+ - MIT
34
+ metadata: {}
35
+ post_install_message:
36
+ rdoc_options: []
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ requirements: []
50
+ rubygems_version: 3.0.1
51
+ signing_key:
52
+ specification_version: 4
53
+ summary: Prevent running an inherited method directly
54
+ test_files: []