much-plugin 0.2.0 → 0.2.1
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 +7 -7
- data/Gemfile +3 -0
- data/README.md +65 -5
- data/lib/much-plugin.rb +46 -10
- data/lib/much-plugin/version.rb +1 -1
- data/much-plugin.gemspec +2 -2
- data/test/support/factory.rb +1 -1
- data/test/system/much-plugin_tests.rb +54 -0
- data/test/unit/much-plugin_tests.rb +35 -39
- metadata +37 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
5
|
-
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: baebd1ccaff9c505af4deac64f758ccad4a5f41a8bc5e94ad3fd3bdcc6a6a8cb
|
4
|
+
data.tar.gz: 8da8eca30eb1766bb3d3c5b0beab9a271a0b27ac7c2d281d169b0f7b4be0110f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 66e7398810226de3fda5cc76e8c298f15a8e38b1b56647e6abd9751c9469fd2f2919fbfd668747807e68b274304ecc3f08035c0341c596abcf2a45458cb2d56f
|
7
|
+
data.tar.gz: dbdaf8782afdad32471fdf75eba18e7ac05f1dc423167808fdb4794ae1c2a3cf924d2009685fcaf353c74fc15bcc519d660f351c302c2072de2223e827f9078f
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -5,20 +5,17 @@ An API to ensure mixin included logic (the "plugin") only runs once.
|
|
5
5
|
## Usage
|
6
6
|
|
7
7
|
```ruby
|
8
|
-
requre
|
8
|
+
requre "much-plugin"
|
9
9
|
|
10
10
|
module MyPluginMixin
|
11
11
|
include MuchPlugin
|
12
12
|
|
13
13
|
plugin_included do
|
14
|
-
|
15
|
-
# ... do some stuff ...
|
14
|
+
# do some stuff ...
|
16
15
|
# - will be class eval'd in the scope of the receiver of `MyPluginMixin`
|
17
16
|
# - will only be executed once per receiver, no matter how many times
|
18
17
|
# `MyPluginMixin` is included in that receiver
|
19
|
-
|
20
18
|
end
|
21
|
-
|
22
19
|
end
|
23
20
|
```
|
24
21
|
|
@@ -26,6 +23,69 @@ Mix `MuchPlugin` in on other mixins that act as "plugins" to other components.
|
|
26
23
|
|
27
24
|
This allows you to define multiple hooks separately and ensures each hook will only be executed once - even if your plugin is mixed in multiple times on the same receiver.
|
28
25
|
|
26
|
+
### `plugin_class_methods` / `plugin_instance_methods`
|
27
|
+
|
28
|
+
MuchPlugin provides convenience methods for defining instance/class methods on plugin receivers:
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
requre "much-plugin"
|
32
|
+
|
33
|
+
module MyPluginMixin
|
34
|
+
include MuchPlugin
|
35
|
+
|
36
|
+
plugin_class_methods do
|
37
|
+
# define some methods ...
|
38
|
+
# - these methods will become class methods on the receiver
|
39
|
+
end
|
40
|
+
|
41
|
+
plugin_instance_methods do
|
42
|
+
# define some methods ...
|
43
|
+
# - these methods will become instance methods on the receiver
|
44
|
+
end
|
45
|
+
end
|
46
|
+
```
|
47
|
+
|
48
|
+
## Example
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
requre "much-plugin"
|
52
|
+
|
53
|
+
module AnotherMixin
|
54
|
+
def another
|
55
|
+
"another"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
module MyPlugin
|
60
|
+
include MuchPlugin
|
61
|
+
|
62
|
+
plugin_included do
|
63
|
+
include AnotherMixin
|
64
|
+
end
|
65
|
+
|
66
|
+
plugin_class_methods do
|
67
|
+
def a_class_method
|
68
|
+
"a-class-method"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
plugin_instance_methods do
|
73
|
+
def an_instance_method
|
74
|
+
"an-instance-method"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
class MyClass
|
80
|
+
include MyPlugin
|
81
|
+
end
|
82
|
+
|
83
|
+
my_class = MyClass.new
|
84
|
+
my_class.another # => "another"
|
85
|
+
my_class.an_instance_method # => "an-instance-method"
|
86
|
+
MyClass.a_class_method # => "a-class-method"
|
87
|
+
```
|
88
|
+
|
29
89
|
## Installation
|
30
90
|
|
31
91
|
Add this line to your application's Gemfile:
|
data/lib/much-plugin.rb
CHANGED
@@ -1,23 +1,31 @@
|
|
1
1
|
require "much-plugin/version"
|
2
2
|
|
3
3
|
module MuchPlugin
|
4
|
-
|
5
4
|
def self.included(receiver)
|
6
5
|
receiver.class_eval{ extend ClassMethods }
|
7
6
|
end
|
8
7
|
|
9
8
|
module ClassMethods
|
10
|
-
|
11
|
-
# install an included hook that first checks if this plugin's receiver mixin
|
9
|
+
# install an included block that first checks if this plugin's receiver mixin
|
12
10
|
# has already been included. If it has not been, include the receiver mixin
|
13
|
-
# and run all of the `plugin_included`
|
11
|
+
# and run all of the `plugin_included` blocks
|
14
12
|
def included(plugin_receiver)
|
15
13
|
return if plugin_receiver.include?(self.much_plugin_included_detector)
|
16
14
|
plugin_receiver.send(:include, self.much_plugin_included_detector)
|
17
15
|
|
18
|
-
self.
|
19
|
-
plugin_receiver.class_eval(&
|
16
|
+
self.much_plugin_included_blocks.each do |block|
|
17
|
+
plugin_receiver.class_eval(&block)
|
18
|
+
end
|
19
|
+
|
20
|
+
self.much_plugin_class_method_blocks.each do |block|
|
21
|
+
self.much_plugin_class_methods_module.class_eval(&block)
|
22
|
+
end
|
23
|
+
plugin_receiver.send(:extend, self.much_plugin_class_methods_module)
|
24
|
+
|
25
|
+
self.much_plugin_instance_method_blocks.each do |block|
|
26
|
+
self.much_plugin_instance_methods_module.class_eval(&block)
|
20
27
|
end
|
28
|
+
plugin_receiver.send(:include, self.much_plugin_instance_methods_module)
|
21
29
|
end
|
22
30
|
|
23
31
|
# the included detector is an empty module that is only used to detect if
|
@@ -31,12 +39,40 @@ module MuchPlugin
|
|
31
39
|
end
|
32
40
|
end
|
33
41
|
|
34
|
-
def
|
42
|
+
def much_plugin_class_methods_module
|
43
|
+
@much_plugin_class_methods_module ||= Module.new.tap do |m|
|
44
|
+
self.const_set("MuchPluginClassMethods", m)
|
45
|
+
end
|
46
|
+
end
|
35
47
|
|
36
|
-
def
|
37
|
-
|
48
|
+
def much_plugin_instance_methods_module
|
49
|
+
@much_plugin_instance_methods_module ||= Module.new.tap do |m|
|
50
|
+
self.const_set("MuchPluginInstanceMethods", m)
|
51
|
+
end
|
38
52
|
end
|
39
53
|
|
40
|
-
|
54
|
+
def much_plugin_included_blocks
|
55
|
+
@much_plugin_included_blocks ||= []
|
56
|
+
end
|
41
57
|
|
58
|
+
def much_plugin_class_method_blocks
|
59
|
+
@much_plugin_class_method_blocks ||= []
|
60
|
+
end
|
61
|
+
|
62
|
+
def much_plugin_instance_method_blocks
|
63
|
+
@much_plugin_instance_method_blocks ||= []
|
64
|
+
end
|
65
|
+
|
66
|
+
def plugin_included(&block)
|
67
|
+
self.much_plugin_included_blocks << block
|
68
|
+
end
|
69
|
+
|
70
|
+
def plugin_class_methods(&block)
|
71
|
+
self.much_plugin_class_method_blocks << block
|
72
|
+
end
|
73
|
+
|
74
|
+
def plugin_instance_methods(&block)
|
75
|
+
self.much_plugin_instance_method_blocks << block
|
76
|
+
end
|
77
|
+
end
|
42
78
|
end
|
data/lib/much-plugin/version.rb
CHANGED
data/much-plugin.gemspec
CHANGED
@@ -5,7 +5,7 @@ require "much-plugin/version"
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |gem|
|
7
7
|
gem.name = "much-plugin"
|
8
|
-
gem.version =
|
8
|
+
gem.version = MuchPlugin::VERSION
|
9
9
|
gem.authors = ["Kelly Redding", "Collin Redding"]
|
10
10
|
gem.email = ["kelly@kellyredding.com", "collin.redding@me.com"]
|
11
11
|
gem.summary = %q{An API to ensure mixin included logic (the "plugin") only runs once.}
|
@@ -18,6 +18,6 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
19
|
gem.require_paths = ["lib"]
|
20
20
|
|
21
|
-
gem.add_development_dependency("assert", ["~> 2.
|
21
|
+
gem.add_development_dependency("assert", ["~> 2.17.0"])
|
22
22
|
|
23
23
|
end
|
data/test/support/factory.rb
CHANGED
@@ -0,0 +1,54 @@
|
|
1
|
+
require "assert"
|
2
|
+
require "much-plugin"
|
3
|
+
|
4
|
+
module MuchPlugin
|
5
|
+
class SystemTests < Assert::Context
|
6
|
+
desc "MuchPlugin"
|
7
|
+
setup do
|
8
|
+
@my_class = MyClass.new
|
9
|
+
end
|
10
|
+
subject{ @my_class }
|
11
|
+
|
12
|
+
should "class eval the plugin included block on MyClass" do
|
13
|
+
assert_equal "another", subject.another
|
14
|
+
end
|
15
|
+
|
16
|
+
should "add the plugin class methods to MyClass" do
|
17
|
+
assert_equal "a-class-method", MyClass.a_class_method
|
18
|
+
end
|
19
|
+
|
20
|
+
should "add the plugin instance methods to MyClass" do
|
21
|
+
assert_equal "an-instance-method", subject.an_instance_method
|
22
|
+
end
|
23
|
+
|
24
|
+
module AnotherMixin
|
25
|
+
def another
|
26
|
+
"another"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
module MyPlugin
|
31
|
+
include MuchPlugin
|
32
|
+
|
33
|
+
plugin_included do
|
34
|
+
include AnotherMixin
|
35
|
+
end
|
36
|
+
|
37
|
+
plugin_class_methods do
|
38
|
+
def a_class_method
|
39
|
+
"a-class-method"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
plugin_instance_methods do
|
44
|
+
def an_instance_method
|
45
|
+
"an-instance-method"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class MyClass
|
51
|
+
include MyPlugin
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -1,19 +1,18 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "assert"
|
2
|
+
require "much-plugin"
|
3
3
|
|
4
4
|
module MuchPlugin
|
5
|
-
|
6
5
|
class UnitTests < Assert::Context
|
7
6
|
desc "MuchPlugin"
|
8
7
|
setup do
|
9
|
-
@
|
10
|
-
@
|
8
|
+
@block1 = proc{ 1 }
|
9
|
+
@block2 = proc{ 2 }
|
11
10
|
|
12
11
|
@plugin = Module.new{ include MuchPlugin }
|
13
12
|
end
|
14
13
|
subject{ @plugin }
|
15
14
|
|
16
|
-
should have_imeths :much_plugin_included_detector, :
|
15
|
+
should have_imeths :much_plugin_included_detector, :much_plugin_included_blocks
|
17
16
|
should have_imeths :plugin_included
|
18
17
|
|
19
18
|
should "know its included detector" do
|
@@ -24,54 +23,53 @@ module MuchPlugin
|
|
24
23
|
assert_same exp, subject.much_plugin_included_detector
|
25
24
|
end
|
26
25
|
|
27
|
-
should "have no plugin included
|
28
|
-
assert_empty subject.
|
26
|
+
should "have no plugin included blocks by default" do
|
27
|
+
assert_empty subject.much_plugin_included_blocks
|
29
28
|
end
|
30
29
|
|
31
|
-
should "append
|
32
|
-
subject.plugin_included(&@
|
33
|
-
subject.plugin_included(&@
|
30
|
+
should "append blocks" do
|
31
|
+
subject.plugin_included(&@block1)
|
32
|
+
subject.plugin_included(&@block2)
|
34
33
|
|
35
|
-
assert_equal @
|
36
|
-
assert_equal @
|
34
|
+
assert_equal @block1, subject.much_plugin_included_blocks.first
|
35
|
+
assert_equal @block2, subject.much_plugin_included_blocks.last
|
37
36
|
end
|
38
|
-
|
39
37
|
end
|
40
38
|
|
41
39
|
class MixedInTests < UnitTests
|
42
40
|
desc "when mixed in"
|
43
41
|
setup do
|
44
42
|
@receiver = Class.new do
|
45
|
-
def self.
|
46
|
-
def self.
|
47
|
-
def self.
|
48
|
-
def self.
|
43
|
+
def self.inc_block1; @block1_count ||= 0; @block1_count += 1; end
|
44
|
+
def self.block1_count; @block1_count ||= 0; end
|
45
|
+
def self.inc_block2; @block2_count ||= 0; @block2_count += 1; end
|
46
|
+
def self.block2_count; @block2_count ||= 0; end
|
49
47
|
end
|
50
48
|
end
|
51
49
|
|
52
|
-
should "call the plugin included
|
53
|
-
assert_equal 0, @receiver.
|
54
|
-
assert_equal 0, @receiver.
|
50
|
+
should "call the plugin included blocks" do
|
51
|
+
assert_equal 0, @receiver.block1_count
|
52
|
+
assert_equal 0, @receiver.block2_count
|
55
53
|
|
56
54
|
@receiver.send(:include, TestPlugin)
|
57
55
|
|
58
|
-
assert_equal 1, @receiver.
|
59
|
-
assert_equal 1, @receiver.
|
56
|
+
assert_equal 1, @receiver.block1_count
|
57
|
+
assert_equal 1, @receiver.block2_count
|
60
58
|
end
|
61
59
|
|
62
|
-
should "call
|
60
|
+
should "call blocks only once no matter even if previously mixed in" do
|
63
61
|
@receiver.send(:include, TestPlugin)
|
64
62
|
|
65
|
-
assert_equal 1, @receiver.
|
66
|
-
assert_equal 1, @receiver.
|
63
|
+
assert_equal 1, @receiver.block1_count
|
64
|
+
assert_equal 1, @receiver.block2_count
|
67
65
|
|
68
66
|
@receiver.send(:include, TestPlugin)
|
69
67
|
|
70
|
-
assert_equal 1, @receiver.
|
71
|
-
assert_equal 1, @receiver.
|
68
|
+
assert_equal 1, @receiver.block1_count
|
69
|
+
assert_equal 1, @receiver.block2_count
|
72
70
|
end
|
73
71
|
|
74
|
-
should "call
|
72
|
+
should "call blocks only once even if mixed in by a 3rd party" do
|
75
73
|
third_party = Module.new do
|
76
74
|
def self.included(receiver)
|
77
75
|
receiver.send(:include, TestPlugin)
|
@@ -79,27 +77,25 @@ module MuchPlugin
|
|
79
77
|
end
|
80
78
|
@receiver.send(:include, third_party)
|
81
79
|
|
82
|
-
assert_equal 1, @receiver.
|
83
|
-
assert_equal 1, @receiver.
|
80
|
+
assert_equal 1, @receiver.block1_count
|
81
|
+
assert_equal 1, @receiver.block2_count
|
84
82
|
|
85
83
|
@receiver.send(:include, TestPlugin)
|
86
84
|
|
87
|
-
assert_equal 1, @receiver.
|
88
|
-
assert_equal 1, @receiver.
|
85
|
+
assert_equal 1, @receiver.block1_count
|
86
|
+
assert_equal 1, @receiver.block2_count
|
89
87
|
|
90
88
|
@receiver.send(:include, third_party)
|
91
89
|
|
92
|
-
assert_equal 1, @receiver.
|
93
|
-
assert_equal 1, @receiver.
|
90
|
+
assert_equal 1, @receiver.block1_count
|
91
|
+
assert_equal 1, @receiver.block2_count
|
94
92
|
end
|
95
93
|
|
96
94
|
TestPlugin = Module.new do
|
97
95
|
include MuchPlugin
|
98
96
|
|
99
|
-
plugin_included{
|
100
|
-
plugin_included{
|
97
|
+
plugin_included{ inc_block1 }
|
98
|
+
plugin_included{ inc_block2 }
|
101
99
|
end
|
102
|
-
|
103
100
|
end
|
104
|
-
|
105
101
|
end
|
metadata
CHANGED
@@ -1,39 +1,39 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: much-plugin
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
|
-
authors:
|
6
|
+
authors:
|
7
7
|
- Kelly Redding
|
8
8
|
- Collin Redding
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2019-09-03 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
16
15
|
name: assert
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
version: 2.16.1
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 2.17.0
|
23
21
|
type: :development
|
24
|
-
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: 2.17.0
|
25
28
|
description: An API to ensure mixin included logic (the "plugin") only runs once.
|
26
|
-
email:
|
29
|
+
email:
|
27
30
|
- kelly@kellyredding.com
|
28
31
|
- collin.redding@me.com
|
29
32
|
executables: []
|
30
|
-
|
31
33
|
extensions: []
|
32
|
-
|
33
34
|
extra_rdoc_files: []
|
34
|
-
|
35
|
-
|
36
|
-
- .gitignore
|
35
|
+
files:
|
36
|
+
- ".gitignore"
|
37
37
|
- Gemfile
|
38
38
|
- LICENSE
|
39
39
|
- README.md
|
@@ -44,35 +44,35 @@ files:
|
|
44
44
|
- much-plugin.gemspec
|
45
45
|
- test/helper.rb
|
46
46
|
- test/support/factory.rb
|
47
|
+
- test/system/much-plugin_tests.rb
|
47
48
|
- test/unit/much-plugin_tests.rb
|
48
49
|
- tmp/.gitkeep
|
49
50
|
homepage: http://github.com/redding/much-plugin
|
50
|
-
licenses:
|
51
|
+
licenses:
|
51
52
|
- MIT
|
52
53
|
metadata: {}
|
53
|
-
|
54
54
|
post_install_message:
|
55
55
|
rdoc_options: []
|
56
|
-
|
57
|
-
require_paths:
|
56
|
+
require_paths:
|
58
57
|
- lib
|
59
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
60
|
-
requirements:
|
61
|
-
-
|
62
|
-
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
58
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
68
|
requirements: []
|
69
|
-
|
70
69
|
rubyforge_project:
|
71
|
-
rubygems_version: 2.
|
70
|
+
rubygems_version: 2.7.7
|
72
71
|
signing_key:
|
73
72
|
specification_version: 4
|
74
73
|
summary: An API to ensure mixin included logic (the "plugin") only runs once.
|
75
|
-
test_files:
|
74
|
+
test_files:
|
76
75
|
- test/helper.rb
|
77
76
|
- test/support/factory.rb
|
77
|
+
- test/system/much-plugin_tests.rb
|
78
78
|
- test/unit/much-plugin_tests.rb
|