active_presenters 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ # require 'active_presenters'
data/lib/ac_hooks.rb ADDED
@@ -0,0 +1,33 @@
1
+ # module ActionController
2
+ # class Base
3
+ # alias_method :ac_render, :render
4
+ #
5
+ # def render(options = nil, deprecated_status = nil, &block)
6
+ # puts "in active_presenter render"
7
+ # self.instance_variables.each do |v|
8
+ # puts "v = #{v}"
9
+ # var = self.instance_variable_get(v)
10
+ # puts "var = #{var.class}"
11
+ # puts "var.is_presentable? = #{var.is_presentable?}"
12
+ # if var.is_presentable?
13
+ # if var.is_a? Array
14
+ # presenters = []
15
+ # var.each do |a|
16
+ # if a.is_presentable?
17
+ # presenter = a.build_presenter(self)
18
+ # presenters << presenter
19
+ # end
20
+ # end
21
+ # self.instance_variable_set("#{v.singularize}_presenters".to_sym, presenters)
22
+ # else
23
+ # presenter = var.build_presenter(self)
24
+ # # puts "presenter = #{presenter.inspect}"
25
+ # self.instance_variable_set("#{v.singularize}_presenter".to_sym, presenter)
26
+ # end
27
+ # end
28
+ # end
29
+ # ac_render(options, deprecated_status, &block)
30
+ # end
31
+ #
32
+ # end
33
+ # end
@@ -0,0 +1,30 @@
1
+ require 'fileutils'
2
+ require 'find'
3
+ path = File.expand_path(RAILS_ROOT + "/app/presenters")
4
+ puts path
5
+
6
+ FileUtils.mkdir_p(path) unless File.exists?(path)
7
+
8
+ require 'presentable'
9
+ require 'proxy'
10
+ require 'base'
11
+
12
+ Find.find(path) do |f|
13
+ if FileTest.directory?(f) and f =~ /\.svn/
14
+ Find.prune
15
+ else
16
+ if FileTest.file?(f)
17
+ f.gsub!(path, "")
18
+ m = f.match(/\/[a-zA\-Z-_]*.rb/)
19
+ if m
20
+ model = m.to_s
21
+ x = model.gsub('/', '').gsub('.rb', '')
22
+ begin
23
+ require "#{path}/#{x}"
24
+ rescue => ex
25
+ puts ex
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
data/lib/ar_hooks.rb ADDED
@@ -0,0 +1,13 @@
1
+ # class << ActiveRecord::Base
2
+ #
3
+ # alias_method :ar_find, :find
4
+ #
5
+ # def find(*args)
6
+ # res = ar_find(*args)
7
+ # if res.is_a? Array
8
+ # res.is_presentable = true
9
+ # end
10
+ # res
11
+ # end
12
+ #
13
+ # end
data/lib/base.rb ADDED
@@ -0,0 +1,142 @@
1
+ module ActivePresenter
2
+
3
+ REST_VERBS = {
4
+ :index => :get,
5
+ :show => :get,
6
+ :new => :get,
7
+ :create => :post,
8
+ :edit => :get,
9
+ :update => :put,
10
+ :destroy => :delete
11
+ }
12
+
13
+ class Base
14
+
15
+ include ActionView::Helpers::TagHelper # link_to
16
+ include ActionView::Helpers::UrlHelper # url_for
17
+ include ActionController::UrlWriter # named routes
18
+ include ActionView::Helpers::TextHelper # link_to
19
+ include ActionView::Helpers::FormHelper
20
+ include ActionView::Helpers::FormTagHelper
21
+ include ActionView::Helpers::FormOptionsHelper
22
+ attr_accessor :options
23
+ attr_accessor :model_underscore # => debate_side
24
+ attr_accessor :model_camelcase # => DebateSide
25
+
26
+ def initialize(source, options = {})
27
+ self.model_underscore = source.class.to_s.underscore
28
+ self.model_camelcase = source.class.to_s
29
+ eval %{alias :#{self.model_underscore} :model}
30
+ @model = source
31
+ self.options = options || {}
32
+ if source.is_a? ActiveRecord::Base
33
+ if source.is_restful?
34
+ build_common_ar_resource_methods
35
+ build_ar_resource_methods
36
+ else
37
+ #build_ar_non_resource_methods
38
+ end
39
+ end
40
+ end
41
+
42
+ def model
43
+ @model
44
+ end
45
+
46
+ protected
47
+
48
+ def build_common_ar_resource_methods
49
+
50
+ instance_eval do
51
+ unless method_defined?(:destroy_link_options)
52
+ def destroy_link_options
53
+ {:confirm => 'Are you sure?', :method => :delete}
54
+ end
55
+ end
56
+ end
57
+
58
+ REST_VERBS.each_pair do |verb, meth|
59
+ instance_eval %{
60
+ unless method_defined?(:#{verb}_link_text)
61
+ def #{verb}_link_text
62
+ "#{verb}"
63
+ end
64
+ end
65
+
66
+ unless method_defined?(:#{verb}_link_options)
67
+ def #{verb}_link_options
68
+ {:method => :#{meth}}
69
+ end
70
+ end
71
+
72
+ unless method_defined?(:#{verb}_link)
73
+ def #{verb}_link(name = #{verb}_link_text, options = {}, html_options = nil, *args)
74
+ options = #{verb}_link_options.merge(options)
75
+ link_to(h(name), #{verb}_path, options, html_options, *args)
76
+ end
77
+ end
78
+ }
79
+ end
80
+ end
81
+
82
+ def build_ar_resource_methods
83
+ instance_eval %{
84
+ unless method_defined?(:index_path)
85
+ def index_path
86
+ #{self.plural}_path#{self.model.nested_resource.nil? ? '' : "(self.model.nested_resource)"}
87
+ end
88
+ end
89
+
90
+ unless method_defined?(:show_path)
91
+ def show_path
92
+ #{self.singular}_path(#{self.model.nested_resource.nil? ? '' : "self.model.nested_resource, "}self.model)
93
+ end
94
+ end
95
+
96
+ unless method_defined?(:new_path)
97
+ def new_path
98
+ new_#{self.singular}_path#{self.model.nested_resource.nil? ? '' : "(self.model.nested_resource)"}
99
+ end
100
+ end
101
+
102
+ unless method_defined?(:create_path)
103
+ def create_path
104
+ #{self.plural}_path#{self.model.nested_resource.nil? ? '' : "(self.model.nested_resource)"}
105
+ end
106
+ end
107
+
108
+ unless method_defined?(:edit_path)
109
+ def edit_path
110
+ edit_#{self.singular}_path(#{self.model.nested_resource.nil? ? '' : "self.model.nested_resource, "}self.model)
111
+ end
112
+ end
113
+
114
+ unless method_defined?(:update_path)
115
+ def update_path
116
+ #{self.singular}_path(#{self.model.nested_resource.nil? ? '' : "self.model.nested_resource, "}self.model)
117
+ end
118
+ end
119
+
120
+ unless method_defined?(:destroy_path)
121
+ def destroy_path
122
+ #{self.singular}_path(#{self.model.nested_resource.nil? ? '' : "self.model.nested_resource, "}self.model)
123
+ end
124
+ end
125
+ }
126
+ end
127
+
128
+ def plural
129
+ self.model_underscore.pluralize
130
+ end
131
+
132
+ def singular
133
+ self.model_underscore.singularize
134
+ end
135
+
136
+ def method_defined?(meth)
137
+ self.methods.include?("#{meth}")
138
+ end
139
+
140
+ end
141
+
142
+ end
@@ -0,0 +1,83 @@
1
+ class Object
2
+
3
+ def is_presentable?
4
+ false
5
+ end
6
+
7
+ end
8
+
9
+ module ActivePresenter
10
+
11
+ module Presentable
12
+
13
+ module ClassMethods
14
+
15
+ def use_presenter(name = self.class.to_s)
16
+ name = name.to_s.underscore
17
+ name << "_presenter" unless name.match(/_presenter/)
18
+ # puts "name = #{name}"
19
+ instance_eval do
20
+ define_method("presenter_name") do
21
+ name
22
+ end
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+ def self.included(base) # :nodoc:
29
+ # puts "base = #{base.inspect}"
30
+ # puts "self = #{self.inspect}"
31
+ base.extend ClassMethods
32
+ end
33
+
34
+ def is_presentable?
35
+ true
36
+ end
37
+
38
+ def is_restful?
39
+ return self.is_a? ActiveRecord::Base
40
+ end
41
+
42
+ attr_accessor :nested_resource
43
+
44
+ def presenter_name
45
+ unless @presenter_name
46
+ @presenter_name = self.class.to_s.underscore + "_presenter"
47
+ end
48
+ @presenter_name
49
+ end
50
+
51
+ def presenter
52
+ unless @presenter
53
+ @presenter = build_presenter(presenter_options)
54
+ end
55
+ @presenter
56
+ end
57
+
58
+ def presenter_options
59
+ {}
60
+ end
61
+
62
+ private
63
+ def build_presenter(options = {})
64
+ # puts "build: #{self}, #{options.inspect}"
65
+ name = self.presenter_name.camelcase
66
+ begin
67
+ @presenter = name.constantize.new(self, options)
68
+ rescue => ex
69
+ @presenter = ActivePresenter::Base.new(self, options)
70
+ end
71
+ puts "built: #{presenter.class.name} for #{self.class.name}"
72
+ self.presenter
73
+ end
74
+
75
+ end
76
+
77
+ end
78
+
79
+ begin
80
+ ActiveRecord::Base.send(:include, ActivePresenter::Presentable)
81
+ rescue Exception => e
82
+ # Just in case you're using this in a non-ActiveRecord way.
83
+ end
data/lib/proxy.rb ADDED
@@ -0,0 +1,52 @@
1
+ module ActivePresenter
2
+ class Proxy
3
+
4
+ def initialize(options = {}, &block)
5
+ if options.is_a? Hash
6
+ unless options.empty?
7
+ options.each_pair {|k,v| self.send("#{k}=", v)}
8
+ end
9
+ end
10
+ yield self if block_given?
11
+ end
12
+
13
+ def method_missing(sym, *args)
14
+ syms = sym.to_s
15
+ if syms.match(/.=$/)
16
+ key = syms.chop
17
+ gen_methods(key)
18
+ self.send("#{key}=", args.from_args)
19
+ else
20
+ key = sym.to_s
21
+ gen_methods(key)
22
+ self.send("#{key}", args.from_args)
23
+ end
24
+
25
+ end
26
+
27
+ def create_method(name, &block)
28
+ self.class.send(:define_method, name, &block)
29
+ end
30
+
31
+ private
32
+ def gen_methods(key)
33
+ eval %{
34
+
35
+ def #{key}=(x)
36
+ @#{key} = x
37
+ end
38
+
39
+ def #{key}(x = nil, &block)
40
+ if @#{key}.nil?
41
+ val = x
42
+ else
43
+ val = @#{key}
44
+ end
45
+ yield val if block_given?
46
+ val
47
+ end
48
+ }
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,5 @@
1
+ --- !ruby/object:RubyForgeConfig
2
+ gem_name: active_presenters
3
+ package: active_presenters
4
+ project: magrathea
5
+ version: 1.0.0
@@ -0,0 +1,93 @@
1
+ require 'test/unit'
2
+ ENV["RAILS_ENV"] = "test"
3
+ require File.expand_path(File.dirname(__FILE__) + "/../../../../config/environment")
4
+ require File.expand_path(File.dirname(__FILE__) + "/../init")
5
+ require File.expand_path(File.dirname(__FILE__) + "/models")
6
+ require File.expand_path(File.dirname(__FILE__) + "/presenters")
7
+
8
+ ActionController::Routing::Routes.draw do |map|
9
+ map.resources :blog_posts
10
+ map.resources :blog_users
11
+ map.resources :blog_comments
12
+ end
13
+
14
+ class ActivePresentersTest < Test::Unit::TestCase
15
+ include ActionView::Helpers::TagHelper # link_to
16
+ include ActionView::Helpers::UrlHelper # url_for
17
+ include ActionController::UrlWriter # named routes
18
+ include ActionView::Helpers::TextHelper # link_to
19
+ include ActionView::Helpers::FormHelper
20
+ include ActionView::Helpers::FormTagHelper
21
+ include ActionView::Helpers::FormOptionsHelper
22
+
23
+ def test_base_presenter_built
24
+ bp = BlogPost.build_new
25
+ p = bp.presenter
26
+ assert_presenter_basics(bp, p)
27
+ end
28
+
29
+ def test_default_presenter_built
30
+ bc = BlogComment.build_new
31
+ p = bc.presenter
32
+ assert_presenter_basics(bc, p)
33
+ assert p.is_a?(BlogCommentPresenter)
34
+ end
35
+
36
+ def test_custom_presenter_built
37
+ bu = BlogUser.build_new
38
+ p = bu.presenter
39
+ assert_presenter_basics(bu, p, "special_foo_presenter")
40
+ assert p.is_a?(SpecialFooPresenter)
41
+ assert_equal "Hello World!", p.show_link_text
42
+ end
43
+
44
+ def test_poro_presenter_built
45
+ poro = Poro.new
46
+ p = poro.presenter
47
+ assert_presenter_basics(poro, p)
48
+ end
49
+
50
+ def test_ar_resource_methods_built
51
+ bp = BlogPost.build_new
52
+ p = bp.presenter
53
+ assert bp.is_restful?
54
+ assert_nil bp.nested_resource
55
+ rest_verbs.each_pair do |verb, meth|
56
+ assert p.respond_to?("#{verb}_link_text")
57
+ assert_equal verb.to_s, p.send("#{verb}_link_text")
58
+ assert p.respond_to?("#{verb}_link_options")
59
+ assert_equal({:method => meth.to_sym}, p.send("#{verb}_link_options")) unless verb == :destroy
60
+ assert_equal({:method => meth.to_sym, :confirm => 'Are you sure?', :method => :delete}, p.send("#{verb}_link_options")) if verb == :destroy
61
+ assert p.respond_to?("#{verb}_link")
62
+ assert_equal link_to(h("#{verb}"), p.send("#{verb}_path"), p.send("#{verb}_link_options")), p.send("#{verb}_link")
63
+ assert p.respond_to?("#{verb}_path")
64
+ end
65
+ end
66
+
67
+ def test_ar_resource_methods_not_built
68
+ bp = Poro.new
69
+ p = bp.presenter
70
+ rest_verbs.each_pair do |verb, meth|
71
+ assert !p.respond_to?("#{verb}_link_text")
72
+ assert !p.respond_to?("#{verb}_link_options")
73
+ assert !p.respond_to?("#{verb}_link")
74
+ assert !p.respond_to?("#{verb}_path")
75
+ end
76
+ end
77
+
78
+ def rest_verbs
79
+ ActivePresenter::REST_VERBS
80
+ end
81
+
82
+ def assert_presenter_basics(model, presenter, presenter_name = "#{model.class.to_s.underscore.to_sym}_presenter")
83
+ m_underscore_sym = model.class.to_s.underscore.to_sym
84
+ assert model.is_presentable?
85
+ assert_equal presenter_name, model.presenter_name
86
+ assert_not_nil presenter
87
+ assert presenter.is_a?(ActivePresenter::Base)
88
+ assert_equal model, presenter.model
89
+ assert presenter.respond_to?(m_underscore_sym)
90
+ assert_equal presenter.model, presenter.send(m_underscore_sym)
91
+ end
92
+
93
+ end
data/test/models.rb ADDED
@@ -0,0 +1,59 @@
1
+ class BlogPost < ActiveRecord::Base
2
+
3
+ attr_accessor :title
4
+ attr_accessor :body
5
+ attr_accessor :created_at
6
+ attr_accessor :updated_at
7
+ attr_accessor :id
8
+
9
+ def initialize(hsh = {})
10
+ hsh.each { |k, v| send("#{k}=", v) }
11
+ end
12
+
13
+ def self.build_new(options = {})
14
+ BlogPost.new({:id => 1, :title => "Hello!", :body => "This is my body", :created_at => 1.day.ago, :updated_at => Time.now}.merge(options))
15
+ end
16
+
17
+ end
18
+
19
+ class BlogComment < ActiveRecord::Base
20
+
21
+ attr_accessor :blog_id
22
+ attr_accessor :body
23
+ attr_accessor :created_at
24
+ attr_accessor :updated_at
25
+ attr_accessor :id
26
+
27
+ def initialize(hsh = {})
28
+ hsh.each { |k, v| send("#{k}=", v) }
29
+ end
30
+
31
+ def self.build_new(options = {})
32
+ BlogComment.new({:id => 1, :blog_id => 1, :body => "This is my body", :created_at => 1.day.ago, :updated_at => Time.now}.merge(options))
33
+ end
34
+
35
+ end
36
+
37
+ class BlogUser < ActiveRecord::Base
38
+
39
+ use_presenter :special_foo
40
+
41
+ attr_accessor :username
42
+ attr_accessor :email
43
+ attr_accessor :created_at
44
+ attr_accessor :updated_at
45
+ attr_accessor :id
46
+
47
+ def initialize(hsh = {})
48
+ hsh.each { |k, v| send("#{k}=", v) }
49
+ end
50
+
51
+ def self.build_new(options = {})
52
+ BlogUser.new({:id => 1, :username => "markbates", :email => "foo@foo.com", :created_at => 1.day.ago, :updated_at => Time.now}.merge(options))
53
+ end
54
+
55
+ end
56
+
57
+ class Poro
58
+ include ActivePresenter::Presentable
59
+ end
@@ -0,0 +1,11 @@
1
+ class BlogCommentPresenter < ActivePresenter::Base
2
+
3
+ end
4
+
5
+ class SpecialFooPresenter < ActivePresenter::Base
6
+
7
+ def show_link_text
8
+ "Hello World!"
9
+ end
10
+
11
+ end
@@ -0,0 +1,75 @@
1
+ require 'test/unit'
2
+ ENV["RAILS_ENV"] = "test"
3
+ require File.expand_path(File.dirname(__FILE__) + "/../../../../config/environment")
4
+ require File.expand_path(File.dirname(__FILE__) + "/../init")
5
+ require File.expand_path(File.dirname(__FILE__) + "/models")
6
+ require File.expand_path(File.dirname(__FILE__) + "/presenters")
7
+
8
+ class ProxyTest < Test::Unit::TestCase
9
+
10
+ def test_empty_constructor
11
+ p = ActivePresenter::Proxy.new
12
+ puts "p = #{p.inspect}"
13
+ end
14
+
15
+ def test_hash_constructor
16
+ p = ActivePresenter::Proxy.new(:foo => :bar)
17
+ assert p.methods.include?("foo")
18
+ assert p.methods.include?("foo=")
19
+ assert_equal :bar, p.foo
20
+ p.foo = :foo_bar
21
+ assert_equal :foo_bar, p.foo
22
+ end
23
+
24
+ def test_array_constructor
25
+ @hello = "Hello There World!"
26
+ p = ActivePresenter::Proxy.new([:mark, :bates, @hello])
27
+ assert !p.methods.include?("mark")
28
+ assert !p.methods.include?("bates")
29
+ assert !p.methods.include?("hello")
30
+ end
31
+
32
+ def test_methods_genned
33
+ p = ActivePresenter::Proxy.new
34
+ assert !p.methods.include?("foo_bar")
35
+ assert !p.methods.include?("foo_bar=")
36
+ p.foo_bar = :bar
37
+ assert_equal :bar, p.foo_bar
38
+ assert p.methods.include?("foo_bar")
39
+ assert p.methods.include?("foo_bar=")
40
+ end
41
+
42
+ def test_block
43
+ p = ActivePresenter::Proxy.new(:cool => :mark)
44
+ assert_equal :mark, p.cool
45
+ x = p.cool do |v|
46
+ assert_equal :mark, v
47
+ assert_equal 2, 1 + 1
48
+ v = "mark is cool"
49
+ assert_equal "mark is cool", v
50
+ end
51
+ assert_equal :mark, x
52
+ end
53
+
54
+ def test_define_method
55
+ p = ActivePresenter::Proxy.new
56
+ assert !p.methods.include?("my_crazy_method")
57
+ p.create_method("my_crazy_method") do |k, v|
58
+ return [1, 2, k, v]
59
+ end
60
+ assert p.methods.include?("my_crazy_method")
61
+ assert_equal [1,2,3,4], p.my_crazy_method(3,4)
62
+ end
63
+
64
+ def test_block_constructor
65
+ p = ActivePresenter::Proxy.new(:partner => :mark) do |p|
66
+ assert_equal :mark, p.partner
67
+ p.baby = :dylan
68
+ assert_equal p.baby, :dylan
69
+ end
70
+ assert_equal :mark, p.partner
71
+ assert_equal p.baby, :dylan
72
+ end
73
+
74
+
75
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.2
3
+ specification_version: 1
4
+ name: active_presenters
5
+ version: !ruby/object:Gem::Version
6
+ version: 1.0.0
7
+ date: 2007-09-11 00:00:00 -04:00
8
+ summary: active_presenters
9
+ require_paths:
10
+ - lib
11
+ - lib
12
+ - lib
13
+ - lib/tasks
14
+ email:
15
+ homepage:
16
+ rubyforge_project: magrathea
17
+ description: "active_presenters was developed by: markbates"
18
+ autorequire:
19
+ - proxy
20
+ - presentable
21
+ - base
22
+ - ar_hooks
23
+ - active_presenters
24
+ - ac_hooks
25
+ - proxy
26
+ - presentable
27
+ - base
28
+ - ar_hooks
29
+ - active_presenters
30
+ - ac_hooks
31
+ default_executable:
32
+ bindir: bin
33
+ has_rdoc: false
34
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
35
+ requirements:
36
+ - - ">"
37
+ - !ruby/object:Gem::Version
38
+ version: 0.0.0
39
+ version:
40
+ platform: ruby
41
+ signing_key:
42
+ cert_chain:
43
+ post_install_message:
44
+ authors:
45
+ - markbates
46
+ files:
47
+ - init.rb
48
+ - lib/ac_hooks.rb
49
+ - lib/active_presenters.rb
50
+ - lib/ar_hooks.rb
51
+ - lib/base.rb
52
+ - lib/presentable.rb
53
+ - lib/proxy.rb
54
+ - lib/tasks/rubyforge_config.yml
55
+ - test/active_presenters_test.rb
56
+ - test/models.rb
57
+ - test/presenters.rb
58
+ - test/proxy_test.rb
59
+ test_files: []
60
+
61
+ rdoc_options: []
62
+
63
+ extra_rdoc_files: []
64
+
65
+ executables: []
66
+
67
+ extensions: []
68
+
69
+ requirements: []
70
+
71
+ dependencies: []
72
+