wizardwerdna-pluggable 0.0.0 → 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.
- data/VERSION +1 -1
- data/lib/pluggable.rb +43 -11
- data/pluggable.gemspec +53 -0
- data/spec/pluggable_spec.rb +84 -28
- metadata +2 -1
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.1.0
|
data/lib/pluggable.rb
CHANGED
@@ -4,23 +4,34 @@ $:.unshift(File.dirname(__FILE__)) unless
|
|
4
4
|
require 'singleton'
|
5
5
|
require 'forwardable'
|
6
6
|
module Pluggable
|
7
|
-
VERSION = '0.0.1'
|
8
7
|
|
9
|
-
|
10
|
-
|
8
|
+
class Plugins < Array
|
9
|
+
extend Forwardable
|
10
|
+
def self.from_array_of_instance_and_name_pairs array
|
11
|
+
result = new
|
12
|
+
array.each do |each_pair|
|
13
|
+
result << each_pair[:instance]
|
14
|
+
result.instance_variable_set each_pair[:name], each_pair[:instance]
|
15
|
+
end
|
16
|
+
result
|
17
|
+
end
|
11
18
|
end
|
12
19
|
|
13
|
-
class
|
20
|
+
class PluginFactory < Array
|
14
21
|
include Singleton
|
15
|
-
|
16
|
-
|
17
|
-
|
22
|
+
def build_plugins
|
23
|
+
array_of_instance_and_name_pairs = map do |each|
|
24
|
+
instance = each.new
|
25
|
+
{:name => variable_name_for_plugin_instance(instance), :instance => instance}
|
26
|
+
end
|
27
|
+
Plugins.from_array_of_instance_and_name_pairs(array_of_instance_and_name_pairs)
|
28
|
+
end
|
29
|
+
def delegate_plugin_public_methods_to_plugins_class_except *excluded_methods
|
18
30
|
excluded_methods = excluded_methods.map{|each| each.to_s}
|
19
|
-
each do |instance|
|
31
|
+
build_plugins.each do |instance|
|
20
32
|
delegated_methods = instance.public_methods-Plugin.public_instance_methods-excluded_methods
|
21
33
|
variable_name = variable_name_for_plugin_instance instance
|
22
|
-
|
23
|
-
self.class.def_delegators variable_name, *delegated_methods
|
34
|
+
Plugins.def_delegators variable_name, *delegated_methods
|
24
35
|
end
|
25
36
|
end
|
26
37
|
private
|
@@ -31,7 +42,28 @@ module Pluggable
|
|
31
42
|
|
32
43
|
class Plugin
|
33
44
|
def self.inherited(klass)
|
34
|
-
|
45
|
+
PluginFactory.instance << klass
|
35
46
|
end
|
36
47
|
end
|
48
|
+
|
49
|
+
def install_plugins
|
50
|
+
instance_variable_set :@pluggable_module_plugins, PluginFactory.instance.build_plugins
|
51
|
+
end
|
52
|
+
|
53
|
+
def plugins
|
54
|
+
instance_variable_get :@pluggable_module_plugins
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.included(klass)
|
58
|
+
klass.extend ClassMethods
|
59
|
+
end
|
60
|
+
|
61
|
+
module ClassMethods
|
62
|
+
def plugin_factory
|
63
|
+
PluginFactory.instance
|
64
|
+
end
|
65
|
+
def delegate_plugin_public_methods_except *excluded_methods
|
66
|
+
PluginFactory.instance.delegate_plugin_public_methods_to_plugins_class_except *excluded_methods
|
67
|
+
end
|
68
|
+
end
|
37
69
|
end
|
data/pluggable.gemspec
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{pluggable}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Andrew C. Greenberg"]
|
12
|
+
s.date = %q{2009-08-20}
|
13
|
+
s.description = %q{TODO: longer description of your gem}
|
14
|
+
s.email = %q{wizardwerdna@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"lib/pluggable.rb",
|
27
|
+
"pluggable.gemspec",
|
28
|
+
"spec/pluggable_spec.rb",
|
29
|
+
"spec/spec_helper.rb"
|
30
|
+
]
|
31
|
+
s.homepage = %q{http://github.com/wizardwerdna/pluggable}
|
32
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
33
|
+
s.require_paths = ["lib"]
|
34
|
+
s.rubygems_version = %q{1.3.5}
|
35
|
+
s.summary = %q{TODO: one-line summary of your gem}
|
36
|
+
s.test_files = [
|
37
|
+
"spec/pluggable_spec.rb",
|
38
|
+
"spec/spec_helper.rb"
|
39
|
+
]
|
40
|
+
|
41
|
+
if s.respond_to? :specification_version then
|
42
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
43
|
+
s.specification_version = 3
|
44
|
+
|
45
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
46
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
47
|
+
else
|
48
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
49
|
+
end
|
50
|
+
else
|
51
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
52
|
+
end
|
53
|
+
end
|
data/spec/pluggable_spec.rb
CHANGED
@@ -2,47 +2,41 @@ require 'forwardable'
|
|
2
2
|
require File.dirname(__FILE__) + '/spec_helper.rb'
|
3
3
|
|
4
4
|
class Test
|
5
|
-
extend Forwardable
|
6
5
|
include Pluggable
|
6
|
+
def process
|
7
|
+
plugins.map{|each| each.process}
|
8
|
+
end
|
9
|
+
private
|
7
10
|
def method_missing symbol, *args
|
8
11
|
plugins.send(symbol, *args)
|
9
12
|
end
|
10
13
|
end
|
11
14
|
|
12
15
|
class Plugin1 < Test::Plugin
|
13
|
-
def foo
|
14
|
-
|
15
|
-
|
16
|
-
def
|
17
|
-
end
|
18
|
-
private
|
19
|
-
def exception_private
|
20
|
-
end
|
16
|
+
def foo; "foo"; end
|
17
|
+
def process; foo; end
|
18
|
+
private
|
19
|
+
def exception_private; end
|
21
20
|
end
|
22
21
|
|
23
22
|
class Plugin2 < Test::Plugin
|
24
|
-
def bar
|
25
|
-
|
26
|
-
end
|
27
|
-
def exception_public
|
28
|
-
end
|
23
|
+
def bar; "bar"; end
|
24
|
+
def process; bar; end
|
29
25
|
private
|
30
|
-
def exception_private
|
31
|
-
end
|
26
|
+
def exception_private; end
|
32
27
|
end
|
33
28
|
|
34
29
|
class Plugin3 < Test::Plugin
|
35
|
-
def baz
|
36
|
-
|
37
|
-
end
|
38
|
-
def exception_public
|
39
|
-
end
|
30
|
+
def baz; "baz"; end
|
31
|
+
def process; baz; end
|
40
32
|
private
|
41
|
-
def exception_private
|
42
|
-
|
33
|
+
def exception_private; end
|
34
|
+
end
|
35
|
+
|
36
|
+
if Test.respond_to? :delegate_plugin_public_methods_except
|
37
|
+
Test.delegate_plugin_public_methods_except :exception_public
|
43
38
|
end
|
44
39
|
|
45
|
-
Test.new.plugins.delegate_public_methods_to_plugins_except :exception_public
|
46
40
|
|
47
41
|
describe Pluggable, "when included in a class" do
|
48
42
|
|
@@ -50,16 +44,55 @@ describe Pluggable, "when included in a class" do
|
|
50
44
|
@test_instance = Test.new
|
51
45
|
end
|
52
46
|
|
53
|
-
it "
|
47
|
+
it "should install a class method #plugin_factory, an array of all the plugin classes" do
|
48
|
+
Test.should respond_to(:plugin_factory)
|
49
|
+
Test.plugin_factory.should have(3).items
|
50
|
+
Test.plugin_factory.should include(Plugin1, Plugin2, Plugin3)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should add a method #plugins that should be nil upon creation" do
|
54
54
|
@test_instance.should respond_to(:plugins)
|
55
|
-
@test_instance.plugins.should
|
55
|
+
@test_instance.plugins.should be_nil
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should add a method #install_plugins" do
|
59
|
+
Test.new.should respond_to(:install_plugins)
|
56
60
|
end
|
57
61
|
|
58
|
-
it "should
|
62
|
+
it "should install a class method #delegate_plugin_public_methods_except" do
|
63
|
+
Test.should respond_to(:delegate_plugin_public_methods_except)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe Pluggable, "after installing plugins" do
|
68
|
+
before(:each) do
|
69
|
+
@test_instance = Test.new
|
70
|
+
@test_instance.install_plugins
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should have #plugins answer an object containing a collection of new plugin instances after #install_plugins" do
|
74
|
+
@test_instance.should_not be_nil
|
75
|
+
@test_instance.plugins.should_not be_nil
|
76
|
+
@test_instance.plugins.should be_an_instance_of(Test::Plugins)
|
59
77
|
@test_instance.plugins.should have(3).items
|
60
78
|
@test_instance.plugins.map{|each| each.class}.should include(Plugin1, Plugin2, Plugin3)
|
61
79
|
end
|
62
80
|
|
81
|
+
it "should have #plugins answer an object containing a collection of new plugin instances after #install_plugins a second time" do
|
82
|
+
@test_instance.should_not be_nil
|
83
|
+
@test_instance.plugins.should_not be_nil
|
84
|
+
@test_instance.plugins.should be_an_instance_of(Test::Plugins)
|
85
|
+
@test_instance.plugins.should have(3).items
|
86
|
+
@test_instance.plugins.map{|each| each.class}.should include(Plugin1, Plugin2, Plugin3)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe Pluggable, "after Test has delegated all but excepted plugin public methods" do
|
91
|
+
before(:each) do
|
92
|
+
@test_instance = Test.new
|
93
|
+
@test_instance.install_plugins
|
94
|
+
end
|
95
|
+
|
63
96
|
it "should delegate public methods of plugins" do
|
64
97
|
@test_instance.plugins.should respond_to(:foo)
|
65
98
|
@test_instance.plugins.should respond_to(:bar)
|
@@ -80,10 +113,33 @@ describe Pluggable, "when included in a class" do
|
|
80
113
|
end
|
81
114
|
end
|
82
115
|
|
116
|
+
describe Test::PluginFactory, "instances" do
|
117
|
+
before(:each) do
|
118
|
+
@instance = Test::PluginFactory.instance
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should be an array of all the plugins" do
|
122
|
+
@instance.should have(3).items
|
123
|
+
@instance.should include(Plugin1, Plugin2, Plugin3)
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should build a Plugins object with fresh instances of each plugin" do
|
127
|
+
@installed_plugins = @instance.build_plugins
|
128
|
+
@installed_plugins.should be_a_kind_of(Test::Plugins)
|
129
|
+
@installed_plugins.should have(3).items
|
130
|
+
@installed_plugins.map{|each| each.class}.should include(Plugin1, Plugin2, Plugin3)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
83
134
|
describe Test, "when using message_missing to simulate delegation from the parent" do
|
84
135
|
|
85
136
|
before(:each) do
|
86
137
|
@test_instance = Test.new
|
138
|
+
@test_instance.install_plugins
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should properly process using all the plugins" do
|
142
|
+
@test_instance.process.should == ["foo", "bar", "baz"]
|
87
143
|
end
|
88
144
|
|
89
145
|
it "should delegate public methods of plugins" do
|
@@ -91,4 +147,4 @@ describe Test, "when using message_missing to simulate delegation from the paren
|
|
91
147
|
@test_instance.bar.should == "bar"
|
92
148
|
@test_instance.baz.should == "baz"
|
93
149
|
end
|
94
|
-
end
|
150
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wizardwerdna-pluggable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew C. Greenberg
|
@@ -39,6 +39,7 @@ files:
|
|
39
39
|
- Rakefile
|
40
40
|
- VERSION
|
41
41
|
- lib/pluggable.rb
|
42
|
+
- pluggable.gemspec
|
42
43
|
- spec/pluggable_spec.rb
|
43
44
|
- spec/spec_helper.rb
|
44
45
|
has_rdoc: false
|