much-mixin 0.0.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 -0
- data/.gitignore +19 -0
- data/Gemfile +12 -0
- data/LICENSE +22 -0
- data/README.md +131 -0
- data/bench/script.rb +27 -0
- data/lib/much-mixin.rb +96 -0
- data/lib/much-mixin/version.rb +5 -0
- data/lib/much-plugin.rb +3 -0
- data/log/.gitkeep +0 -0
- data/much-mixin.gemspec +25 -0
- data/test/helper.rb +12 -0
- data/test/support/factory.rb +7 -0
- data/test/system/much-mixin_tests.rb +56 -0
- data/test/system/much-plugin_tests.rb +56 -0
- data/test/unit/much-mixin_tests.rb +124 -0
- metadata +80 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 28fac94ed0a9f228774a872d2a0300825f5eb92c0e7b382af265936f21abd30b
|
|
4
|
+
data.tar.gz: 42992da0c84c834ac2b864fb08a02fa9dd4c252d143512052cdc9cfbde46e8e4
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: c2229eca4fda26cb23d960904055554436682e86a7bf2c760042727024f65d84691d721313a67c35226af2032034ae89065cd8a7105294644ddc19e0cc592f7e
|
|
7
|
+
data.tar.gz: c3acfab039cea2a7de5177b46fa4e47603626f0890927960dd59bbb4c38d1292b69188b2d783a52bd4f077a8c14c576e60fc159ae00602ee5c3108f11a6dbae8
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2015-Present Kelly Redding and Collin Redding
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# MuchMixin
|
|
2
|
+
|
|
3
|
+
Enhanced mix-in API.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
requre "much-mixin"
|
|
9
|
+
|
|
10
|
+
module MyMuchMixin
|
|
11
|
+
include MuchMixin
|
|
12
|
+
|
|
13
|
+
mixin_included do
|
|
14
|
+
# do some stuff ...
|
|
15
|
+
# - will be class eval'd in the scope of the receiver of `MyMuchMixin`
|
|
16
|
+
# - will only be executed once per receiver, no matter how many times
|
|
17
|
+
# `MyMuchMixin` is included in that receiver
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Mix `MuchMixin` in on other mixins that act as "plugins" to other components. Define included hooks using `mixin_included` that will be class eval'd in the scope of the receiver.
|
|
23
|
+
|
|
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.
|
|
25
|
+
|
|
26
|
+
### `mixin_class_methods` / `mixin_instance_methods`
|
|
27
|
+
|
|
28
|
+
MuchMixin provides convenience methods for defining instance/class methods on plugin receivers:
|
|
29
|
+
|
|
30
|
+
```ruby
|
|
31
|
+
requre "much-mixin"
|
|
32
|
+
|
|
33
|
+
module MyMuchMixin
|
|
34
|
+
include MuchMixin
|
|
35
|
+
|
|
36
|
+
mixin_class_methods do
|
|
37
|
+
# define some methods ...
|
|
38
|
+
# - these methods will become class methods on the receiver
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
mixin_instance_methods do
|
|
42
|
+
# define some methods ...
|
|
43
|
+
# - these methods will become instance methods on the receiver
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### `after_mixin_included`
|
|
49
|
+
|
|
50
|
+
These hooks work just like the `mixin_included` hooks, except they are evaluated _after_ any plugin class/instance methods have been evaluated. E.g. use this to call a class method that the plugin defines.
|
|
51
|
+
|
|
52
|
+
```ruby
|
|
53
|
+
requre "much-mixin"
|
|
54
|
+
|
|
55
|
+
module MyMuchMixin
|
|
56
|
+
include MuchMixin
|
|
57
|
+
|
|
58
|
+
after_mixin_included do
|
|
59
|
+
configure_the_plugin
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
mixin_class_methods do
|
|
63
|
+
def configure_the_plugin
|
|
64
|
+
# ...
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Example
|
|
71
|
+
|
|
72
|
+
```ruby
|
|
73
|
+
requre "much-mixin"
|
|
74
|
+
|
|
75
|
+
module AnotherMixin
|
|
76
|
+
def another
|
|
77
|
+
"another"
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
module MyMuchMixin
|
|
82
|
+
include MuchMixin
|
|
83
|
+
|
|
84
|
+
mixin_included do
|
|
85
|
+
include AnotherMixin
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
mixin_class_methods do
|
|
89
|
+
def a_class_method
|
|
90
|
+
"a-class-method"
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
mixin_instance_methods do
|
|
95
|
+
def an_instance_method
|
|
96
|
+
"an-instance-method"
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
class MyClass
|
|
102
|
+
include MyMuchMixin
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
my_class = MyClass.new
|
|
106
|
+
my_class.another # => "another"
|
|
107
|
+
my_class.an_instance_method # => "an-instance-method"
|
|
108
|
+
MyClass.a_class_method # => "a-class-method"
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Installation
|
|
112
|
+
|
|
113
|
+
Add this line to your application's Gemfile:
|
|
114
|
+
|
|
115
|
+
gem "much-mixin"
|
|
116
|
+
|
|
117
|
+
And then execute:
|
|
118
|
+
|
|
119
|
+
$ bundle
|
|
120
|
+
|
|
121
|
+
Or install it yourself as:
|
|
122
|
+
|
|
123
|
+
$ gem install much-mixin
|
|
124
|
+
|
|
125
|
+
## Contributing
|
|
126
|
+
|
|
127
|
+
1. Fork it
|
|
128
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
129
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
|
130
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
131
|
+
5. Create new Pull Request
|
data/bench/script.rb
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require "much-mixin"
|
|
2
|
+
require "benchmark"
|
|
3
|
+
|
|
4
|
+
module Methods; end
|
|
5
|
+
|
|
6
|
+
module MyMixin
|
|
7
|
+
def self.included(receiver)
|
|
8
|
+
receiver.class_eval{ include Methods }
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
module MyMuchMixin
|
|
13
|
+
include MuchMixin
|
|
14
|
+
|
|
15
|
+
mixin_included do
|
|
16
|
+
include Methods
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
Benchmark.bmbm do |x|
|
|
21
|
+
x.report("MyMixin") do
|
|
22
|
+
10_000.times{ Class.new{ include MyMixin } }
|
|
23
|
+
end
|
|
24
|
+
x.report("MyMuchMixin") do
|
|
25
|
+
10_000.times{ Class.new{ include MyMuchMixin } }
|
|
26
|
+
end
|
|
27
|
+
end
|
data/lib/much-mixin.rb
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "much-mixin/version"
|
|
4
|
+
|
|
5
|
+
module MuchMixin
|
|
6
|
+
def self.included(receiver)
|
|
7
|
+
receiver.class_eval{ extend ClassMethods }
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
module ClassMethods
|
|
11
|
+
# install an included block that first checks if this plugin's receiver mixin
|
|
12
|
+
# has already been included. If it has not been, include the receiver mixin
|
|
13
|
+
# and run all of the `mixin_included` blocks
|
|
14
|
+
def included(plugin_receiver)
|
|
15
|
+
return if plugin_receiver.include?(self.much_mixin_included_detector)
|
|
16
|
+
plugin_receiver.send(:include, self.much_mixin_included_detector)
|
|
17
|
+
|
|
18
|
+
self.much_mixin_included_blocks.each do |block|
|
|
19
|
+
plugin_receiver.class_eval(&block)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
self.much_plugin_class_method_blocks.each do |block|
|
|
23
|
+
self.much_mixin_class_methods_module.class_eval(&block)
|
|
24
|
+
end
|
|
25
|
+
plugin_receiver.send(:extend, self.much_mixin_class_methods_module)
|
|
26
|
+
|
|
27
|
+
self.much_plugin_instance_method_blocks.each do |block|
|
|
28
|
+
self.much_mixin_instance_methods_module.class_eval(&block)
|
|
29
|
+
end
|
|
30
|
+
plugin_receiver.send(:include, self.much_mixin_instance_methods_module)
|
|
31
|
+
|
|
32
|
+
self.much_plugin_after_included_blocks.each do |block|
|
|
33
|
+
plugin_receiver.class_eval(&block)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# the included detector is an empty module that is only used to detect if
|
|
38
|
+
# the plugin has been included or not, it doesn't add any behavior or
|
|
39
|
+
# methods to the object receiving the plugin; we use `const_set` to name the
|
|
40
|
+
# module so if its seen in the ancestors it doesn't look like some random
|
|
41
|
+
# module and it can be tracked back to much-mixin
|
|
42
|
+
def much_mixin_included_detector
|
|
43
|
+
@much_mixin_included_detector ||= Module.new.tap do |m|
|
|
44
|
+
self.const_set("MuchMixinIncludedDetector", m)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def much_mixin_class_methods_module
|
|
49
|
+
@much_mixin_class_methods_module ||= Module.new.tap do |m|
|
|
50
|
+
self.const_set("MuchMixinClassMethods", m)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def much_mixin_instance_methods_module
|
|
55
|
+
@much_mixin_instance_methods_module ||= Module.new.tap do |m|
|
|
56
|
+
self.const_set("MuchMixinInstanceMethods", m)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def much_mixin_included_blocks
|
|
61
|
+
@much_mixin_included_blocks ||= []
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def much_plugin_after_included_blocks
|
|
65
|
+
@much_plugin_after_included_blocks ||= []
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def much_plugin_class_method_blocks
|
|
69
|
+
@much_plugin_class_method_blocks ||= []
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def much_plugin_instance_method_blocks
|
|
73
|
+
@much_plugin_instance_method_blocks ||= []
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def mixin_included(&block)
|
|
77
|
+
self.much_mixin_included_blocks << block
|
|
78
|
+
end
|
|
79
|
+
alias_method :plugin_included, :mixin_included
|
|
80
|
+
|
|
81
|
+
def after_mixin_included(&block)
|
|
82
|
+
self.much_plugin_after_included_blocks << block
|
|
83
|
+
end
|
|
84
|
+
alias_method :after_plugin_included, :after_mixin_included
|
|
85
|
+
|
|
86
|
+
def mixin_class_methods(&block)
|
|
87
|
+
self.much_plugin_class_method_blocks << block
|
|
88
|
+
end
|
|
89
|
+
alias_method :plugin_class_methods, :mixin_class_methods
|
|
90
|
+
|
|
91
|
+
def mixin_instance_methods(&block)
|
|
92
|
+
self.much_plugin_instance_method_blocks << block
|
|
93
|
+
end
|
|
94
|
+
alias_method :plugin_instance_methods, :mixin_instance_methods
|
|
95
|
+
end
|
|
96
|
+
end
|
data/lib/much-plugin.rb
ADDED
data/log/.gitkeep
ADDED
|
File without changes
|
data/much-mixin.gemspec
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
lib = File.expand_path("../lib", __FILE__)
|
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
|
+
require "much-mixin/version"
|
|
6
|
+
|
|
7
|
+
Gem::Specification.new do |gem|
|
|
8
|
+
gem.name = "much-mixin"
|
|
9
|
+
gem.version = MuchMixin::VERSION
|
|
10
|
+
gem.authors = ["Kelly Redding", "Collin Redding"]
|
|
11
|
+
gem.email = ["kelly@kellyredding.com", "collin.redding@me.com"]
|
|
12
|
+
gem.summary = %q{Enhanced mix-in API.}
|
|
13
|
+
gem.description = %q{Enhanced mix-in API.}
|
|
14
|
+
gem.homepage = "http://github.com/redding/much-mixin"
|
|
15
|
+
gem.license = "MIT"
|
|
16
|
+
|
|
17
|
+
gem.files = `git ls-files`.split($/)
|
|
18
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
|
19
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
|
20
|
+
gem.require_paths = ["lib"]
|
|
21
|
+
|
|
22
|
+
gem.required_ruby_version = "~> 2.5"
|
|
23
|
+
|
|
24
|
+
gem.add_development_dependency("assert", ["~> 2.19.2"])
|
|
25
|
+
end
|
data/test/helper.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# this file is automatically required when you run `assert`
|
|
4
|
+
# put any test helpers here
|
|
5
|
+
|
|
6
|
+
# add the root dir to the load path
|
|
7
|
+
$LOAD_PATH.unshift(File.expand_path("../..", __FILE__))
|
|
8
|
+
|
|
9
|
+
# require pry for debugging (`binding.pry`)
|
|
10
|
+
require "pry"
|
|
11
|
+
|
|
12
|
+
require "test/support/factory"
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "assert"
|
|
4
|
+
require "much-mixin"
|
|
5
|
+
|
|
6
|
+
module MuchMixin
|
|
7
|
+
class SystemTests < Assert::Context
|
|
8
|
+
desc "MuchMixin"
|
|
9
|
+
setup do
|
|
10
|
+
@my_class = MyClass.new
|
|
11
|
+
end
|
|
12
|
+
subject{ @my_class }
|
|
13
|
+
|
|
14
|
+
should "class eval the plugin included block on MyClass" do
|
|
15
|
+
assert_equal "another", subject.another
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
should "add the plugin class methods to MyClass" do
|
|
19
|
+
assert_equal "a-class-method", MyClass.a_class_method
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
should "add the plugin instance methods to MyClass" do
|
|
23
|
+
assert_equal "an-instance-method", subject.an_instance_method
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
module AnotherMixin
|
|
27
|
+
def another
|
|
28
|
+
"another"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
module MyMuchMixin
|
|
33
|
+
include MuchMixin
|
|
34
|
+
|
|
35
|
+
mixin_included do
|
|
36
|
+
include AnotherMixin
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
mixin_class_methods do
|
|
40
|
+
def a_class_method
|
|
41
|
+
"a-class-method"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
mixin_instance_methods do
|
|
46
|
+
def an_instance_method
|
|
47
|
+
"an-instance-method"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
class MyClass
|
|
53
|
+
include MyMuchMixin
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "assert"
|
|
4
|
+
require "much-plugin"
|
|
5
|
+
|
|
6
|
+
module MuchMixin
|
|
7
|
+
class SystemTests < Assert::Context
|
|
8
|
+
desc "MuchMixin"
|
|
9
|
+
setup do
|
|
10
|
+
@my_class = MyClass.new
|
|
11
|
+
end
|
|
12
|
+
subject{ @my_class }
|
|
13
|
+
|
|
14
|
+
should "class eval the plugin included block on MyClass" do
|
|
15
|
+
assert_equal "another", subject.another
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
should "add the plugin class methods to MyClass" do
|
|
19
|
+
assert_equal "a-class-method", MyClass.a_class_method
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
should "add the plugin instance methods to MyClass" do
|
|
23
|
+
assert_equal "an-instance-method", subject.an_instance_method
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
module AnotherMixin
|
|
27
|
+
def another
|
|
28
|
+
"another"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
module MyMuchMixin
|
|
33
|
+
include MuchMixin
|
|
34
|
+
|
|
35
|
+
mixin_included do
|
|
36
|
+
include AnotherMixin
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
mixin_class_methods do
|
|
40
|
+
def a_class_method
|
|
41
|
+
"a-class-method"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
mixin_instance_methods do
|
|
46
|
+
def an_instance_method
|
|
47
|
+
"an-instance-method"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
class MyClass
|
|
53
|
+
include MyMuchMixin
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "assert"
|
|
4
|
+
require "much-mixin"
|
|
5
|
+
|
|
6
|
+
module MuchMixin
|
|
7
|
+
class UnitTests < Assert::Context
|
|
8
|
+
desc "MuchMixin"
|
|
9
|
+
setup do
|
|
10
|
+
@block1 = proc{ 1 }
|
|
11
|
+
@block2 = proc{ 2 }
|
|
12
|
+
|
|
13
|
+
@muchmixin = Module.new{ include MuchMixin }
|
|
14
|
+
end
|
|
15
|
+
subject{ @muchmixin }
|
|
16
|
+
|
|
17
|
+
should have_imeths :much_mixin_included_detector, :much_mixin_included_blocks
|
|
18
|
+
should have_imeths :mixin_included, :after_mixin_included
|
|
19
|
+
|
|
20
|
+
should "know its included detector" do
|
|
21
|
+
mixin = subject.much_mixin_included_detector
|
|
22
|
+
assert_instance_of Module, mixin
|
|
23
|
+
assert_same mixin, subject.much_mixin_included_detector
|
|
24
|
+
exp = subject::MuchMixinIncludedDetector
|
|
25
|
+
assert_same exp, subject.much_mixin_included_detector
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
should "have no plugin included blocks by default" do
|
|
29
|
+
assert_empty subject.much_mixin_included_blocks
|
|
30
|
+
assert_empty subject.much_plugin_after_included_blocks
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
should "append blocks" do
|
|
34
|
+
subject.mixin_included(&@block1)
|
|
35
|
+
subject.mixin_included(&@block2)
|
|
36
|
+
|
|
37
|
+
assert_equal @block1, subject.much_mixin_included_blocks.first
|
|
38
|
+
assert_equal @block2, subject.much_mixin_included_blocks.last
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
class MixedInTests < UnitTests
|
|
43
|
+
desc "when mixed in"
|
|
44
|
+
setup do
|
|
45
|
+
@receiver = Class.new do
|
|
46
|
+
def self.inc_block1; @block1_count ||= 0; @block1_count += 1; end
|
|
47
|
+
def self.block1_count; @block1_count ||= 0; end
|
|
48
|
+
def self.inc_block2; @block2_count ||= 0; @block2_count += 1; end
|
|
49
|
+
def self.block2_count; @block2_count ||= 0; end
|
|
50
|
+
|
|
51
|
+
def self.do_something_count; @do_something_count ||= 0; end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
should "call the plugin included blocks" do
|
|
56
|
+
assert_equal 0, @receiver.block1_count
|
|
57
|
+
assert_equal 0, @receiver.block2_count
|
|
58
|
+
assert_equal 0, @receiver.do_something_count
|
|
59
|
+
|
|
60
|
+
@receiver.send(:include, TestMuchMixin)
|
|
61
|
+
|
|
62
|
+
assert_equal 1, @receiver.block1_count
|
|
63
|
+
assert_equal 1, @receiver.block2_count
|
|
64
|
+
assert_equal 1, @receiver.do_something_count
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
should "call blocks only once no matter even if previously mixed in" do
|
|
68
|
+
@receiver.send(:include, TestMuchMixin)
|
|
69
|
+
|
|
70
|
+
assert_equal 1, @receiver.block1_count
|
|
71
|
+
assert_equal 1, @receiver.block2_count
|
|
72
|
+
assert_equal 1, @receiver.do_something_count
|
|
73
|
+
|
|
74
|
+
@receiver.send(:include, TestMuchMixin)
|
|
75
|
+
|
|
76
|
+
assert_equal 1, @receiver.block1_count
|
|
77
|
+
assert_equal 1, @receiver.block2_count
|
|
78
|
+
assert_equal 1, @receiver.do_something_count
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
should "call blocks only once even if mixed in by a 3rd party" do
|
|
82
|
+
third_party = Module.new do
|
|
83
|
+
def self.included(receiver)
|
|
84
|
+
receiver.send(:include, TestMuchMixin)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
@receiver.send(:include, third_party)
|
|
88
|
+
|
|
89
|
+
assert_equal 1, @receiver.block1_count
|
|
90
|
+
assert_equal 1, @receiver.block2_count
|
|
91
|
+
assert_equal 1, @receiver.do_something_count
|
|
92
|
+
|
|
93
|
+
@receiver.send(:include, TestMuchMixin)
|
|
94
|
+
|
|
95
|
+
assert_equal 1, @receiver.block1_count
|
|
96
|
+
assert_equal 1, @receiver.block2_count
|
|
97
|
+
assert_equal 1, @receiver.do_something_count
|
|
98
|
+
|
|
99
|
+
@receiver.send(:include, third_party)
|
|
100
|
+
|
|
101
|
+
assert_equal 1, @receiver.block1_count
|
|
102
|
+
assert_equal 1, @receiver.block2_count
|
|
103
|
+
assert_equal 1, @receiver.do_something_count
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
TestMuchMixin =
|
|
108
|
+
Module.new do
|
|
109
|
+
include MuchMixin
|
|
110
|
+
|
|
111
|
+
mixin_included{ inc_block1 }
|
|
112
|
+
after_mixin_included{
|
|
113
|
+
inc_block2
|
|
114
|
+
do_something
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
mixin_class_methods do
|
|
118
|
+
def do_something
|
|
119
|
+
@do_something_count ||= 0
|
|
120
|
+
@do_something_count += 1
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: much-mixin
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Kelly Redding
|
|
8
|
+
- Collin Redding
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2021-01-05 00:00:00.000000000 Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: assert
|
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
|
17
|
+
requirements:
|
|
18
|
+
- - "~>"
|
|
19
|
+
- !ruby/object:Gem::Version
|
|
20
|
+
version: 2.19.2
|
|
21
|
+
type: :development
|
|
22
|
+
prerelease: false
|
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
24
|
+
requirements:
|
|
25
|
+
- - "~>"
|
|
26
|
+
- !ruby/object:Gem::Version
|
|
27
|
+
version: 2.19.2
|
|
28
|
+
description: Enhanced mix-in API.
|
|
29
|
+
email:
|
|
30
|
+
- kelly@kellyredding.com
|
|
31
|
+
- collin.redding@me.com
|
|
32
|
+
executables: []
|
|
33
|
+
extensions: []
|
|
34
|
+
extra_rdoc_files: []
|
|
35
|
+
files:
|
|
36
|
+
- ".gitignore"
|
|
37
|
+
- Gemfile
|
|
38
|
+
- LICENSE
|
|
39
|
+
- README.md
|
|
40
|
+
- bench/script.rb
|
|
41
|
+
- lib/much-mixin.rb
|
|
42
|
+
- lib/much-mixin/version.rb
|
|
43
|
+
- lib/much-plugin.rb
|
|
44
|
+
- log/.gitkeep
|
|
45
|
+
- much-mixin.gemspec
|
|
46
|
+
- test/helper.rb
|
|
47
|
+
- test/support/factory.rb
|
|
48
|
+
- test/system/much-mixin_tests.rb
|
|
49
|
+
- test/system/much-plugin_tests.rb
|
|
50
|
+
- test/unit/much-mixin_tests.rb
|
|
51
|
+
- tmp/.gitkeep
|
|
52
|
+
homepage: http://github.com/redding/much-mixin
|
|
53
|
+
licenses:
|
|
54
|
+
- MIT
|
|
55
|
+
metadata: {}
|
|
56
|
+
post_install_message:
|
|
57
|
+
rdoc_options: []
|
|
58
|
+
require_paths:
|
|
59
|
+
- lib
|
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
61
|
+
requirements:
|
|
62
|
+
- - "~>"
|
|
63
|
+
- !ruby/object:Gem::Version
|
|
64
|
+
version: '2.5'
|
|
65
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
66
|
+
requirements:
|
|
67
|
+
- - ">="
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: '0'
|
|
70
|
+
requirements: []
|
|
71
|
+
rubygems_version: 3.1.2
|
|
72
|
+
signing_key:
|
|
73
|
+
specification_version: 4
|
|
74
|
+
summary: Enhanced mix-in API.
|
|
75
|
+
test_files:
|
|
76
|
+
- test/helper.rb
|
|
77
|
+
- test/support/factory.rb
|
|
78
|
+
- test/system/much-mixin_tests.rb
|
|
79
|
+
- test/system/much-plugin_tests.rb
|
|
80
|
+
- test/unit/much-mixin_tests.rb
|