Permalink
Browse files

add #expose

  • Loading branch information...
1 parent 7793d4c commit 3a9b34627f99a684ea2b73394b3c7ed4a6c2bc45 @jonleighton committed May 3, 2012
Showing with 93 additions and 29 deletions.
  1. +7 −4 README.md
  2. +14 −0 lib/focused_controller/mixin.rb
  3. +17 −25 test/app/app/controllers/posts_controller.rb
  4. +55 −0 test/unit/mixin_test.rb
View
@@ -91,10 +91,13 @@ module PostsController
# implementation inherited from `FocusedController::Mixin` is an
# empty method.
class Show < Action
- def post
- @post ||= Post.find params[:id]
- end
- helper_method :post
+ # Here's a shorter way to declare a method that is also a
+ # helper_method
+ expose(:post) { Post.find params[:id] }
+
+ # You can also call expose without a block, in which case an
+ # attr_reader and a helper_method are declared
+ expose :first_comment
end
end
```
@@ -20,6 +20,20 @@ def controller_path
def call(env)
action(FocusedController.action_name).call(env)
end
+
+ def expose(name, &block)
+ define_method(name) do |*args|
+ ivar = "@#{name}"
+
+ if instance_variable_defined?(ivar)
+ instance_variable_get(ivar)
+ else
+ instance_variable_set(ivar, instance_exec(block, *args, &block))
+ end
+ end
+
+ helper_method name
+ end
end
def action_name
@@ -3,35 +3,17 @@ class Action < ApplicationController
end
class Index < Action
- def posts
- @posts ||= Post.all
- end
- helper_method :posts
- end
-
- class Singular < Action
- def post
- @post ||= begin
- if params[:id]
- Post.find(params[:id])
- else
- Post.new(params[:post])
- end
- end
- end
- helper_method :post
- end
-
- class Show < Singular
+ expose(:posts) { Post.all }
end
- class New < Singular
+ class Initializer < Action
+ expose(:post) { Post.new params[:post] }
end
- class Edit < Singular
+ class New < Initializer
end
- class Create < Singular
+ class Create < Initializer
def run
if post.save
redirect_to post, :notice => 'Post was successfully created.'
@@ -41,7 +23,17 @@ def run
end
end
- class Update < Singular
+ class Finder < Action
+ expose(:post) { Post.find params[:id] }
+ end
+
+ class Show < Finder
+ end
+
+ class Edit < Finder
+ end
+
+ class Update < Finder
def run
if post.update_attributes(params[:post])
redirect_to post, :notice => 'Post was successfully updated.'
@@ -51,7 +43,7 @@ def run
end
end
- class Destroy < Singular
+ class Destroy < Finder
def run
post.destroy
redirect_to posts_url
View
@@ -66,5 +66,60 @@ def klass.action(name)
subject.run.must_equal nil
end
end
+
+ describe '.expose' do
+ subject do
+ @klass = Class.new do
+ include FocusedController::Mixin
+
+ @helper_methods = []
+
+ class << self
+ attr_reader :helper_methods
+
+ def helper_method(name)
+ @helper_methods << name
+ end
+ end
+ end
+ end
+
+ it 'defines a method' do
+ subject.expose(:foo) { 'bar' }
+ subject.new.foo.must_equal 'bar'
+ end
+
+ it 'declares the method a helper method' do
+ subject.expose(:foo) { 'bar' }
+ subject.helper_methods.must_equal [:foo]
+ end
+
+ it 'memoizes the result' do
+ count = 0
+ counter = proc { count += 1 }
+ subject.expose(:foo) { counter.call }
+
+ obj = subject.new
+ obj.foo.must_equal 1
+ obj.foo.must_equal 1
+ end
+
+ it 'it memoizes falsey values' do
+ val = true
+ meth = proc { val = !val }
+ subject.expose(:foo) { meth.call }
+
+ obj = subject.new
+ obj.foo.must_equal false
+ obj.foo.must_equal false
+ end
+
+ it 'instance evals the block' do
+ subject.expose(:foo) { @bar }
+ obj = subject.new
+ obj.instance_variable_set('@bar', 'bar')
+ obj.foo.must_equal 'bar'
+ end
+ end
end
end

0 comments on commit 3a9b346

Please sign in to comment.