active_helper 0.1.0 → 0.1.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.
- data/README.textile +7 -0
- data/lib/active_helper/base.rb +34 -9
- data/lib/active_helper/version.rb +1 -1
- data/lib/active_helper.rb +32 -14
- data/test/active_helper_test.rb +31 -3
- metadata +2 -2
data/README.textile
CHANGED
@@ -17,6 +17,13 @@ methods are _delegated_ to the helper instances
|
|
17
17
|
|
18
18
|
Note that ActiveHelper is a generic helper framework. Not coupled to anything like Rails or Merb. Not providing any concrete helpers. Feel free to use clean helpers in _any_ framework (including Rails and friends)!
|
19
19
|
|
20
|
+
h2. Installation
|
21
|
+
|
22
|
+
<pre>
|
23
|
+
> gem install active_helper
|
24
|
+
</pre>
|
25
|
+
|
26
|
+
|
20
27
|
h2. Example
|
21
28
|
|
22
29
|
Let's use the bloody MVC-View example as we find in Rails or Merb (Sinatra, too?).
|
data/lib/active_helper/base.rb
CHANGED
@@ -11,15 +11,39 @@ module ActiveHelper
|
|
11
11
|
|
12
12
|
class << self
|
13
13
|
# Add public methods to the helper's interface. Only methods listed here will
|
14
|
-
# be
|
14
|
+
# be imported into the target.
|
15
|
+
#
|
16
|
+
# Example:
|
17
|
+
# class UrlHelper < ActiveHelper::Base
|
18
|
+
# provides :url_for, :link_to
|
15
19
|
def provides(*methods)
|
16
20
|
helper_methods.push(*methods)
|
17
21
|
end
|
18
22
|
|
23
|
+
# Define a dependency to another ActiveHelper. All provided methods by the needed
|
24
|
+
# helper will be imported into the helper that called needs.
|
25
|
+
#
|
26
|
+
# Example:
|
27
|
+
# class UrlHelper < ActiveHelper::Base
|
28
|
+
# needs TagHelper
|
29
|
+
#
|
30
|
+
# will import #tag into UrlHelper.
|
19
31
|
def needs(*methods)
|
20
32
|
parent_readers.push(*methods).uniq!
|
21
33
|
end
|
22
34
|
|
35
|
+
# Define a dependency to methods in target. Calls to that methods will be delegated
|
36
|
+
# simply back to target.
|
37
|
+
#
|
38
|
+
# Note: This can also be used to call a helper method from a non-ActiveHelper, which
|
39
|
+
# was preliminary included in target.
|
40
|
+
#
|
41
|
+
# Example:
|
42
|
+
# class UrlHelper < ActiveHelper::Base
|
43
|
+
# uses controller
|
44
|
+
#
|
45
|
+
# will deletegate calls to #controller to target (i.e. the view instance that #use's
|
46
|
+
# UrlHelper).
|
23
47
|
def uses(*classes)
|
24
48
|
class_helpers.push(*classes).uniq!
|
25
49
|
end
|
@@ -31,23 +55,24 @@ module ActiveHelper
|
|
31
55
|
|
32
56
|
def initialize(parent=nil)
|
33
57
|
@parent = parent
|
34
|
-
|
35
|
-
|
36
|
-
|
58
|
+
setup_delegator_strategy! # in GenericMethods.
|
59
|
+
delegate_parent_readers!
|
60
|
+
use_class_helpers!
|
37
61
|
end
|
38
62
|
|
39
|
-
def use(
|
40
|
-
use_for(
|
63
|
+
def use(*classes)
|
64
|
+
use_for(classes, parent) # in GenericMethods.
|
41
65
|
end
|
42
66
|
|
43
67
|
protected
|
44
68
|
# Delegates methods declared with #needs back to parent.
|
45
|
-
def
|
69
|
+
def delegate_parent_readers!
|
46
70
|
return if @parent.blank? or self.class.parent_readers.blank?
|
47
|
-
|
71
|
+
delegate_methods_to(self.class.parent_readers, :@parent) # in GenericMethods.
|
48
72
|
end
|
49
73
|
|
50
|
-
|
74
|
+
# Imports foreign methods from other use'd helpers.
|
75
|
+
def use_class_helpers!
|
51
76
|
self.class.class_helpers.each { |helper| use helper }
|
52
77
|
end
|
53
78
|
end
|
data/lib/active_helper.rb
CHANGED
@@ -4,20 +4,28 @@ require 'forwardable'
|
|
4
4
|
|
5
5
|
module ActiveHelper
|
6
6
|
module GenericMethods
|
7
|
-
def use_for(
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
helper_class.helper_methods.each do |meth|
|
15
|
-
def_delegator helper_ivar_name, meth
|
7
|
+
def use_for(classes, target)
|
8
|
+
classes.each do |helper_class|
|
9
|
+
helper_ivar_name = ivar_name_for(helper_class)
|
10
|
+
helper_instance = helper_class.new(target)
|
11
|
+
|
12
|
+
instance_variable_set(helper_ivar_name, helper_instance)
|
13
|
+
delegate_methods_to(helper_class.helper_methods, helper_ivar_name)
|
16
14
|
end
|
17
15
|
end
|
18
16
|
|
19
17
|
protected
|
20
|
-
|
18
|
+
def setup_delegator_strategy!
|
19
|
+
extend SingleForwardable
|
20
|
+
end
|
21
|
+
|
22
|
+
# Implements the actual delegation.
|
23
|
+
def delegate_methods_to(methods, ivar)
|
24
|
+
return if methods.blank?
|
25
|
+
def_delegators ivar, *methods
|
26
|
+
end
|
27
|
+
|
28
|
+
# Unique ivar name for the helper instance in the expanding target.
|
21
29
|
def ivar_name_for(object)
|
22
30
|
('@__active_helper_'+("#{object.to_s}".underscore.gsub(/[\/<>@#:]/, ""))).to_sym
|
23
31
|
end
|
@@ -25,10 +33,20 @@ module ActiveHelper
|
|
25
33
|
|
26
34
|
|
27
35
|
include GenericMethods
|
28
|
-
#
|
29
|
-
#
|
30
|
-
|
31
|
-
|
36
|
+
# Imports the provided methods from +classes+ into the target *instance* (the receiver).
|
37
|
+
# All new methods in the target will be delegated back to the helpers.
|
38
|
+
#
|
39
|
+
# Note: Imports only into the helped instance itself, not the class.
|
40
|
+
#
|
41
|
+
# Example:
|
42
|
+
# class View
|
43
|
+
# end
|
44
|
+
#
|
45
|
+
# view = View.new
|
46
|
+
# view.use UrlHelper, DataMapperHelper
|
47
|
+
def use (*classes)
|
48
|
+
setup_delegator_strategy!
|
49
|
+
use_for(classes, self)
|
32
50
|
end
|
33
51
|
end
|
34
52
|
|
data/test/active_helper_test.rb
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/test_helper'
|
2
2
|
|
3
3
|
class ActiveHelperTest < Test::Unit::TestCase
|
4
|
+
class GreedyHelper < ::ActiveHelper::Base
|
5
|
+
provides :eat
|
6
|
+
end
|
7
|
+
|
8
|
+
class ThirstyHelper < ::ActiveHelper::Base
|
9
|
+
provides :drink, :booze
|
10
|
+
end
|
11
|
+
|
12
|
+
|
4
13
|
def helper_mock(*args)
|
5
14
|
Class.new(::ActiveHelper::Base).new(*args)
|
6
15
|
end
|
@@ -136,7 +145,7 @@ class ActiveHelperTest < Test::Unit::TestCase
|
|
136
145
|
assert_respond_to @helper.class, :uses
|
137
146
|
assert ! @helper.respond_to?(:eat)
|
138
147
|
|
139
|
-
|
148
|
+
|
140
149
|
end
|
141
150
|
|
142
151
|
context "#use" do
|
@@ -151,6 +160,20 @@ class ActiveHelperTest < Test::Unit::TestCase
|
|
151
160
|
@helper.use GreedyHelper
|
152
161
|
assert_equal @target, helper_in(GreedyHelper, @helper).parent # parent of used handler is target, not the using handler!
|
153
162
|
end
|
163
|
+
|
164
|
+
should "accept multiple helper classes" do
|
165
|
+
@helper.use GreedyHelper, ThirstyHelper
|
166
|
+
assert_respond_to @helper, :eat
|
167
|
+
assert_respond_to @helper, :drink
|
168
|
+
assert_respond_to @helper, :booze
|
169
|
+
end
|
170
|
+
|
171
|
+
should "accept empty helpers with no methods" do
|
172
|
+
@empty_helper = helper_mock
|
173
|
+
@helper.use @empty_helper.class
|
174
|
+
assert helper_in(@empty_helper.class, @helper)
|
175
|
+
end
|
176
|
+
|
154
177
|
end
|
155
178
|
|
156
179
|
context "#uses" do
|
@@ -209,8 +232,6 @@ class ActiveHelperTest < Test::Unit::TestCase
|
|
209
232
|
|
210
233
|
@target = @target_class.new
|
211
234
|
assert ! @target.respond_to?(:eat)
|
212
|
-
|
213
|
-
class GreedyHelper < ::ActiveHelper::Base; provides :eat; end
|
214
235
|
end
|
215
236
|
|
216
237
|
context "#use" do
|
@@ -223,6 +244,13 @@ class ActiveHelperTest < Test::Unit::TestCase
|
|
223
244
|
@target.use GreedyHelper
|
224
245
|
assert_equal @target, helper_in(GreedyHelper, @target).parent
|
225
246
|
end
|
247
|
+
|
248
|
+
should "accept multiple helper classes" do
|
249
|
+
@target.use GreedyHelper, ThirstyHelper
|
250
|
+
assert_respond_to @target, :eat
|
251
|
+
assert_respond_to @target, :drink
|
252
|
+
assert_respond_to @target, :booze
|
253
|
+
end
|
226
254
|
end
|
227
255
|
|
228
256
|
#context "#uses" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_helper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Sutterer
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-
|
12
|
+
date: 2010-04-01 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|