genki-merb_component 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +8 -1
- data/lib/merb_component.rb +4 -2
- data/lib/merb_component/controller_ext.rb +57 -1
- data/lib/merb_component/helper_ext.rb +4 -0
- data/lib/merb_component/resource_ext.rb +7 -0
- data/spec/fixture/app/controllers/admin.rb +8 -0
- data/spec/fixture/app/controllers/application.rb +2 -0
- data/spec/fixture/app/controllers/comments.rb +25 -0
- data/spec/fixture/app/controllers/posts.rb +13 -0
- data/spec/fixture/app/models/comment.rb +8 -0
- data/spec/fixture/app/models/post.rb +7 -0
- data/spec/fixture/app/views/comments/index.html.erb +7 -0
- data/spec/fixture/app/views/comments/new.html.erb +3 -0
- data/spec/fixture/app/views/posts/index.html.erb +7 -0
- data/spec/fixture/app/views/posts/show.html.erb +6 -0
- data/spec/fixture/config/router.rb +14 -0
- data/spec/merb_component_spec.rb +6 -2
- data/spec/posts_spec.rb +76 -0
- data/spec/spec_helper.rb +35 -1
- metadata +25 -2
data/Rakefile
CHANGED
@@ -5,7 +5,7 @@ require 'merb-core'
|
|
5
5
|
require 'merb-core/tasks/merb'
|
6
6
|
|
7
7
|
GEM_NAME = "merb_component"
|
8
|
-
GEM_VERSION = "0.1.
|
8
|
+
GEM_VERSION = "0.1.2"
|
9
9
|
AUTHOR = "Genki Takiuchi"
|
10
10
|
EMAIL = "genki@s21g.com"
|
11
11
|
HOMEPAGE = "http://blog.s21g.com/genki"
|
@@ -49,3 +49,10 @@ task :gemspec do
|
|
49
49
|
file.puts spec.to_ruby
|
50
50
|
end
|
51
51
|
end
|
52
|
+
|
53
|
+
desc "Run specs"
|
54
|
+
task :spec do
|
55
|
+
sh "spec --color spec"
|
56
|
+
end
|
57
|
+
|
58
|
+
task :default => :spec
|
data/lib/merb_component.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
# make sure we're running inside Merb
|
2
2
|
if defined?(Merb::Plugins)
|
3
3
|
|
4
|
-
# Merb gives you a Merb::Plugins.config hash...feel free to put your stuff in
|
4
|
+
# Merb gives you a Merb::Plugins.config hash...feel free to put your stuff in
|
5
|
+
# your piece of it
|
5
6
|
Merb::Plugins.config[:merb_component] = {
|
6
|
-
:chickens => false
|
7
7
|
}
|
8
8
|
|
9
9
|
Merb::BootLoader.before_app_loads do
|
10
10
|
# require code that must be loaded before the application
|
11
11
|
require 'merb_component/controller_ext'
|
12
12
|
require 'merb_component/model_ext'
|
13
|
+
require 'merb_component/resource_ext'
|
14
|
+
require 'merb_component/helper_ext'
|
13
15
|
end
|
14
16
|
|
15
17
|
Merb::BootLoader.after_app_loads do
|
@@ -1,9 +1,65 @@
|
|
1
1
|
class Merb::Controller
|
2
|
+
METHOD_TO_ACTION = {
|
3
|
+
:post => :create,
|
4
|
+
:put => :update,
|
5
|
+
:delete => :destroy
|
6
|
+
}.freeze
|
7
|
+
|
8
|
+
class << self
|
9
|
+
private
|
10
|
+
def aggregates(*args)
|
11
|
+
@aggregations ||= Mash.new
|
12
|
+
options = extract_options_from_args!(args) || {}
|
13
|
+
args.each do |arg|
|
14
|
+
define_method(arg){} unless method_defined?(arg)
|
15
|
+
model = Object.full_const_get(arg.to_s.singular.camel_case)
|
16
|
+
key = "#{controller_name.singular}_id"
|
17
|
+
var = "@#{arg.to_s.singular}"
|
18
|
+
|
19
|
+
add_filter(_before_filters, proc{|c|
|
20
|
+
# setup request
|
21
|
+
id = params.delete(key)
|
22
|
+
req = request.dup
|
23
|
+
req.reset_params!
|
24
|
+
req.instance_variable_set(:@params, params.merge(
|
25
|
+
:controller => arg, :action => METHOD_TO_ACTION[req.method]))
|
26
|
+
|
27
|
+
# call action of subsidiary controller with scope
|
28
|
+
cc = Object.full_const_get(params[:action].camel_case).new(req)
|
29
|
+
model.send :with_scope, key => id do
|
30
|
+
cc._abstract_dispatch(req.params[:action])
|
31
|
+
result = cc.instance_variable_get(var)
|
32
|
+
c.instance_variable_set(var, result)
|
33
|
+
end
|
34
|
+
|
35
|
+
# prepare for performing actoin of principal controller
|
36
|
+
params[:id] = id
|
37
|
+
params[:action] = c.action_name = :show
|
38
|
+
}, :only => arg)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def _abstract_dispatch(*args)
|
44
|
+
_dispatch = Merb::AbstractController.instance_method(:_dispatch)
|
45
|
+
_dispatch.bind(self).call(*args)
|
46
|
+
end
|
47
|
+
|
2
48
|
private
|
3
49
|
def component(controller, action, params = {})
|
4
50
|
req = request.dup
|
5
51
|
req.reset_params!
|
6
52
|
req.instance_variable_set :@params, params
|
7
|
-
controller.new(req).
|
53
|
+
controller.new(req)._abstract_dispatch(action)
|
54
|
+
end
|
55
|
+
|
56
|
+
def resource(first, *args)
|
57
|
+
model = case first
|
58
|
+
when Symbol, String
|
59
|
+
Object.full_const_get(first.to_s.singular.camel_case)
|
60
|
+
else first.class
|
61
|
+
end
|
62
|
+
return super unless model.relation
|
63
|
+
super(model.relation, first, *args)
|
8
64
|
end
|
9
65
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class Comments < Application
|
2
|
+
def index
|
3
|
+
@comments = Comment.all
|
4
|
+
display @comments
|
5
|
+
end
|
6
|
+
|
7
|
+
def new
|
8
|
+
@comment = Comment.build
|
9
|
+
display @comment
|
10
|
+
end
|
11
|
+
|
12
|
+
def create(comment)
|
13
|
+
@comment = Comment.all.create(comment)
|
14
|
+
end
|
15
|
+
|
16
|
+
def update(id, comment)
|
17
|
+
@comment = Comment.get(id)
|
18
|
+
@comment.update_attributes(comment)
|
19
|
+
end
|
20
|
+
|
21
|
+
def destroy(id)
|
22
|
+
@comment = Comment.get(id)
|
23
|
+
@comment.destroy
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Merb::Router.prepare do
|
2
|
+
resources :posts do |posts|
|
3
|
+
posts.match("/:action").to(:controller => :posts)
|
4
|
+
posts.match("/:action/:id").to(:controller => :posts)
|
5
|
+
posts.resources :comments#, :controller => :posts
|
6
|
+
end
|
7
|
+
resource :admin do |admin|
|
8
|
+
admin.match("/:action").to(:controller => :admin)
|
9
|
+
admin.match("/:action/:id").to(:controller => :admin)
|
10
|
+
admin.resources :comments#, :controller => :admin
|
11
|
+
end
|
12
|
+
|
13
|
+
default_routes
|
14
|
+
end
|
data/spec/merb_component_spec.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/spec_helper'
|
2
2
|
|
3
3
|
describe "merb_component" do
|
4
|
-
it "should
|
5
|
-
|
4
|
+
it "should extend controller" do
|
5
|
+
Posts.private_instance_methods.should be_include("component")
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should extend model" do
|
9
|
+
Post.public_methods.should be_include("related_with")
|
6
10
|
end
|
7
11
|
end
|
data/spec/posts_spec.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe Posts do
|
4
|
+
before do
|
5
|
+
@req = Merb::Request.new(
|
6
|
+
Merb::Const::REQUEST_PATH => "/posts",
|
7
|
+
Merb::Const::REQUEST_METHOD => "GET",
|
8
|
+
Merb::Const::QUERY_STRING => "")
|
9
|
+
@c = Posts.new(@req)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should be a controller" do
|
13
|
+
@c.should be_kind_of(Merb::Controller)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "Posts controller" do
|
18
|
+
before :all do
|
19
|
+
@post = Post.create
|
20
|
+
@comment = @post.comments.create
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should be tested on at least one post" do
|
24
|
+
Post.count.should > 0
|
25
|
+
Comment.count.should > 0
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should show html" do
|
29
|
+
res = request(resource(@post))
|
30
|
+
res.should be_successful
|
31
|
+
res.should have_xpath("//h1")
|
32
|
+
res.should have_xpath("//h2")
|
33
|
+
res.should have_xpath("//ul/li")
|
34
|
+
res.should have_xpath("//form[@method='post']")
|
35
|
+
res.should have_xpath("//form[@action='/posts/#{@post.id}/comments']")
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should show html after post a comment" do
|
39
|
+
count = @post.comments.count
|
40
|
+
res = request(resource(@post, :comments),
|
41
|
+
:method => 'POST', :params => {:comment => {:body => "foo"}})
|
42
|
+
res.should be_successful
|
43
|
+
res.should have_xpath("//h1")
|
44
|
+
res.should have_xpath("//h2")
|
45
|
+
res.should have_xpath("//ul/li[1]")
|
46
|
+
res.should have_xpath("//ul/li[2]")
|
47
|
+
res.should have_xpath("//form[@method='post']")
|
48
|
+
res.should contain("foo")
|
49
|
+
Comment.all(:post_id => @post.id).count.should == count + 1
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should show html after update a comment" do
|
53
|
+
comment = @post.comments.last
|
54
|
+
comment.should be_kind_of(Comment)
|
55
|
+
res = request(resource(@post, comment),
|
56
|
+
:method => 'PUT', :params => {:comment => {:body => "bar"}})
|
57
|
+
res.should be_successful
|
58
|
+
res.should have_xpath("//h1")
|
59
|
+
res.should have_xpath("//h2")
|
60
|
+
res.should have_xpath("//ul/li[1]")
|
61
|
+
res.should have_xpath("//ul/li[2]")
|
62
|
+
res.should have_xpath("//form[@method='post']")
|
63
|
+
res.should contain("bar")
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should show html after update a comment" do
|
67
|
+
count = @post.comments.count
|
68
|
+
comment = @post.comments.last
|
69
|
+
comment.should be_kind_of(Comment)
|
70
|
+
res = request(resource(@post, comment), :method => 'DELETE')
|
71
|
+
res.should be_successful
|
72
|
+
res.should have_xpath("//h1")
|
73
|
+
res.should have_xpath("//h2")
|
74
|
+
@post.comments.count.should == count - 1
|
75
|
+
end
|
76
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1 +1,35 @@
|
|
1
|
-
$:.push File.join(File.dirname(__FILE__), '..', 'lib')
|
1
|
+
$:.push File.join(File.dirname(__FILE__), '..', 'lib')
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'merb-core'
|
5
|
+
require 'merb-core/plugins'
|
6
|
+
require 'merb_component'
|
7
|
+
require "spec" # Satisfies Autotest and anyone else not using the Rake tasks
|
8
|
+
|
9
|
+
dependency "dm-core"
|
10
|
+
dependency "dm-aggregates"
|
11
|
+
dependency "merb-action-args"
|
12
|
+
dependency "merb-helpers"
|
13
|
+
|
14
|
+
use_orm :datamapper
|
15
|
+
use_test :rspec
|
16
|
+
use_template_engine :erb
|
17
|
+
|
18
|
+
# this loads all plugins required in your init file so don't add them
|
19
|
+
# here again, Merb will do it for you
|
20
|
+
Merb.disable(:initfile)
|
21
|
+
Merb.start_environment(
|
22
|
+
:testing => true,
|
23
|
+
:adapter => 'runner',
|
24
|
+
:environment => ENV['MERB_ENV'] || 'test',
|
25
|
+
:merb_root => File.dirname(__FILE__) / 'fixture',
|
26
|
+
:log_file => File.dirname(__FILE__) / '..' / "merb_test.log"
|
27
|
+
)
|
28
|
+
DataMapper.setup(:default, "sqlite3::memory:")
|
29
|
+
|
30
|
+
Spec::Runner.configure do |config|
|
31
|
+
config.include(Merb::Test::ViewHelper)
|
32
|
+
config.include(Merb::Test::RouteHelper)
|
33
|
+
config.include(Merb::Test::ControllerHelper)
|
34
|
+
config.before(:all){DataMapper.auto_migrate!}
|
35
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: genki-merb_component
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Genki Takiuchi
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-01-
|
12
|
+
date: 2009-01-25 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -38,10 +38,33 @@ files:
|
|
38
38
|
- TODO
|
39
39
|
- lib/merb_component
|
40
40
|
- lib/merb_component/controller_ext.rb
|
41
|
+
- lib/merb_component/helper_ext.rb
|
41
42
|
- lib/merb_component/merbtasks.rb
|
42
43
|
- lib/merb_component/model_ext.rb
|
44
|
+
- lib/merb_component/resource_ext.rb
|
43
45
|
- lib/merb_component.rb
|
46
|
+
- spec/fixture
|
47
|
+
- spec/fixture/app
|
48
|
+
- spec/fixture/app/controllers
|
49
|
+
- spec/fixture/app/controllers/admin.rb
|
50
|
+
- spec/fixture/app/controllers/application.rb
|
51
|
+
- spec/fixture/app/controllers/comments.rb
|
52
|
+
- spec/fixture/app/controllers/posts.rb
|
53
|
+
- spec/fixture/app/models
|
54
|
+
- spec/fixture/app/models/comment.rb
|
55
|
+
- spec/fixture/app/models/post.rb
|
56
|
+
- spec/fixture/app/views
|
57
|
+
- spec/fixture/app/views/comments
|
58
|
+
- spec/fixture/app/views/comments/index.html.erb
|
59
|
+
- spec/fixture/app/views/comments/new.html.erb
|
60
|
+
- spec/fixture/app/views/posts
|
61
|
+
- spec/fixture/app/views/posts/index.html.erb
|
62
|
+
- spec/fixture/app/views/posts/show.html.erb
|
63
|
+
- spec/fixture/config
|
64
|
+
- spec/fixture/config/router.rb
|
65
|
+
- spec/fixture/tmp
|
44
66
|
- spec/merb_component_spec.rb
|
67
|
+
- spec/posts_spec.rb
|
45
68
|
- spec/spec_helper.rb
|
46
69
|
has_rdoc: true
|
47
70
|
homepage: http://blog.s21g.com/genki
|