merb-slices 0.9.7 → 0.9.8
Sign up to get free protection for your applications and to get access to all the features.
- data/README +4 -4
- data/Rakefile +27 -13
- data/TODO +1 -2
- data/bin/slice +77 -0
- data/lib/generators/templates/common/Rakefile +16 -12
- data/lib/generators/templates/full/README +4 -4
- data/lib/generators/templates/full/Rakefile +32 -13
- data/lib/generators/templates/full/config/init.rb +43 -0
- data/lib/generators/templates/full/lib/%base_name%.rb +3 -1
- data/lib/generators/templates/full/spec/%base_name%_spec.rb +10 -121
- data/lib/generators/templates/full/spec/controllers/main_spec.rb +18 -8
- data/lib/generators/templates/thin/README +4 -4
- data/lib/generators/templates/very_thin/README +4 -4
- data/lib/merb-slices.rb +3 -3
- data/lib/merb-slices/controller_mixin.rb +34 -7
- data/lib/merb-slices/merbtasks.rb +5 -34
- data/lib/merb-slices/module.rb +9 -3
- data/lib/merb-slices/module_mixin.rb +19 -31
- data/lib/merb-slices/router_ext.rb +10 -7
- data/spec/full_slice_generator_spec.rb +31 -2
- data/spec/full_slice_spec.rb +162 -0
- data/spec/merb-slice_spec.rb +97 -3
- data/spec/slice_generator_spec.rb +15 -3
- data/spec/slices/full-test-slice/LICENSE +20 -0
- data/spec/slices/full-test-slice/README +170 -0
- data/spec/slices/full-test-slice/Rakefile +67 -0
- data/spec/slices/full-test-slice/TODO +15 -0
- data/spec/slices/full-test-slice/app/controllers/application.rb +5 -0
- data/spec/slices/full-test-slice/app/controllers/main.rb +7 -0
- data/spec/slices/full-test-slice/app/helpers/application_helper.rb +64 -0
- data/spec/slices/full-test-slice/app/views/layout/full_test_slice.html.erb +16 -0
- data/spec/slices/full-test-slice/app/views/main/index.html.erb +1 -0
- data/spec/slices/full-test-slice/config/init.rb +43 -0
- data/spec/slices/full-test-slice/lib/full-test-slice.rb +80 -0
- data/spec/slices/full-test-slice/lib/full-test-slice/merbtasks.rb +103 -0
- data/spec/slices/full-test-slice/lib/full-test-slice/slicetasks.rb +18 -0
- data/spec/slices/full-test-slice/lib/full-test-slice/spectasks.rb +65 -0
- data/spec/slices/full-test-slice/public/javascripts/master.js +0 -0
- data/spec/slices/full-test-slice/public/stylesheets/master.css +2 -0
- data/spec/slices/full-test-slice/stubs/app/controllers/application.rb +2 -0
- data/spec/slices/full-test-slice/stubs/app/controllers/main.rb +2 -0
- data/spec/slices/thin-test-slice/LICENSE +20 -0
- data/spec/slices/thin-test-slice/README +130 -0
- data/spec/slices/thin-test-slice/Rakefile +43 -0
- data/spec/slices/thin-test-slice/TODO +7 -0
- data/spec/slices/thin-test-slice/application.rb +36 -0
- data/spec/slices/thin-test-slice/lib/thin-test-slice.rb +93 -0
- data/spec/slices/thin-test-slice/lib/thin-test-slice/merbtasks.rb +103 -0
- data/spec/slices/thin-test-slice/lib/thin-test-slice/slicetasks.rb +18 -0
- data/spec/slices/thin-test-slice/public/javascripts/master.js +0 -0
- data/spec/slices/thin-test-slice/public/stylesheets/master.css +2 -0
- data/spec/slices/thin-test-slice/stubs/application.rb +9 -0
- data/spec/slices/thin-test-slice/views/layout/thin_test_slice.html.erb +16 -0
- data/spec/slices/thin-test-slice/views/main/index.html.erb +1 -0
- data/spec/slices/very-thin-test-slice/LICENSE +20 -0
- data/spec/slices/very-thin-test-slice/README +110 -0
- data/spec/slices/very-thin-test-slice/Rakefile +43 -0
- data/spec/slices/very-thin-test-slice/TODO +7 -0
- data/spec/slices/very-thin-test-slice/application.rb +36 -0
- data/spec/slices/very-thin-test-slice/lib/very-thin-test-slice.rb +89 -0
- data/spec/slices/very-thin-test-slice/lib/very-thin-test-slice/merbtasks.rb +103 -0
- data/spec/slices/very-thin-test-slice/lib/very-thin-test-slice/slicetasks.rb +18 -0
- data/spec/spec_helper.rb +27 -2
- data/spec/thin_slice_generator_spec.rb +24 -2
- data/spec/thin_slice_spec.rb +139 -0
- data/spec/very_thin_slice_generator_spec.rb +22 -2
- data/spec/very_thin_slice_spec.rb +119 -0
- metadata +79 -5
@@ -5,7 +5,7 @@ describe "<%= module_name %>::Main (controller)" do
|
|
5
5
|
# Feel free to remove the specs below
|
6
6
|
|
7
7
|
before :all do
|
8
|
-
Merb::Router.prepare {
|
8
|
+
Merb::Router.prepare { add_slice(:<%= module_name %>) } if standalone?
|
9
9
|
end
|
10
10
|
|
11
11
|
after :all do
|
@@ -35,15 +35,21 @@ describe "<%= module_name %>::Main (controller)" do
|
|
35
35
|
controller.should be_kind_of(<%= module_name %>::Main)
|
36
36
|
controller.action_name.should == 'index'
|
37
37
|
end
|
38
|
-
|
39
|
-
it "should have routes in <%= module_name %>.routes" do
|
40
|
-
<%= module_name %>.routes.should_not be_empty
|
41
|
-
end
|
42
|
-
|
38
|
+
|
43
39
|
it "should have a slice_url helper method for slice-specific routes" do
|
44
40
|
controller = dispatch_to(<%= module_name %>::Main, 'index')
|
45
|
-
|
46
|
-
controller.
|
41
|
+
|
42
|
+
url = controller.url(:<%= symbol_name %>_default, :controller => 'main', :action => 'show', :format => 'html')
|
43
|
+
url.should == "/<%= base_name %>/main/show.html"
|
44
|
+
controller.slice_url(:controller => 'main', :action => 'show', :format => 'html').should == url
|
45
|
+
|
46
|
+
url = controller.url(:<%= symbol_name %>_index, :format => 'html')
|
47
|
+
url.should == "/<%= base_name %>/index.html"
|
48
|
+
controller.slice_url(:index, :format => 'html').should == url
|
49
|
+
|
50
|
+
url = controller.url(:<%= symbol_name %>_home)
|
51
|
+
url.should == "/<%= base_name %>"
|
52
|
+
controller.slice_url(:home).should == url
|
47
53
|
end
|
48
54
|
|
49
55
|
it "should have helper methods for dealing with public paths" do
|
@@ -51,6 +57,10 @@ describe "<%= module_name %>::Main (controller)" do
|
|
51
57
|
controller.public_path_for(:image).should == "/slices/<%= base_name %>/images"
|
52
58
|
controller.public_path_for(:javascript).should == "/slices/<%= base_name %>/javascripts"
|
53
59
|
controller.public_path_for(:stylesheet).should == "/slices/<%= base_name %>/stylesheets"
|
60
|
+
|
61
|
+
controller.image_path.should == "/slices/<%= base_name %>/images"
|
62
|
+
controller.javascript_path.should == "/slices/<%= base_name %>/javascripts"
|
63
|
+
controller.stylesheet_path.should == "/slices/<%= base_name %>/stylesheets"
|
54
64
|
end
|
55
65
|
|
56
66
|
it "should have a slice-specific _template_root" do
|
@@ -75,19 +75,19 @@ file: config/router.rb
|
|
75
75
|
|
76
76
|
# example: /<%= base_name %>/:controller/:action/:id
|
77
77
|
|
78
|
-
|
78
|
+
add_slice(:<%= module_name %>)
|
79
79
|
|
80
80
|
# example: /foo/:controller/:action/:id
|
81
81
|
|
82
|
-
|
82
|
+
add_slice(:<%= module_name %>, 'foo') # same as :path => 'foo'
|
83
83
|
|
84
84
|
# example: /:lang/:controller/:action/:id (with :a param set)
|
85
85
|
|
86
|
-
|
86
|
+
add_slice(:<%= module_name %>, :path => ':lang', :params => { :a => 'b' })
|
87
87
|
|
88
88
|
# example: /:controller/:action/:id
|
89
89
|
|
90
|
-
|
90
|
+
slice(:<%= module_name %>)
|
91
91
|
|
92
92
|
Normally you should also run the following rake task:
|
93
93
|
|
@@ -55,19 +55,19 @@ file: config/router.rb
|
|
55
55
|
|
56
56
|
# example: /<%= base_name %>/:controller/:action/:id
|
57
57
|
|
58
|
-
|
58
|
+
add_slice(:<%= module_name %>)
|
59
59
|
|
60
60
|
# example: /foo/:controller/:action/:id
|
61
61
|
|
62
|
-
|
62
|
+
add_slice(:<%= module_name %>, 'foo') # same as :path => 'foo'
|
63
63
|
|
64
64
|
# example: /:lang/:controller/:action/:id (with :a param set)
|
65
65
|
|
66
|
-
|
66
|
+
add_slice(:<%= module_name %>, :path => ':lang', :params => { :a => 'b' })
|
67
67
|
|
68
68
|
# example: /:controller/:action/:id
|
69
69
|
|
70
|
-
|
70
|
+
slice(:<%= module_name %>)
|
71
71
|
|
72
72
|
Normally you should also run the following rake task:
|
73
73
|
|
data/lib/merb-slices.rb
CHANGED
@@ -39,8 +39,8 @@ if defined?(Merb::Plugins)
|
|
39
39
|
# Remove a single file and the classes loaded by it from ObjectSpace.
|
40
40
|
#
|
41
41
|
# @param file<String> The file to load.
|
42
|
-
def
|
43
|
-
Merb::BootLoader::LoadClasses.
|
42
|
+
def remove_classes_in_file(file)
|
43
|
+
Merb::BootLoader::LoadClasses.remove_classes_in_file file
|
44
44
|
end
|
45
45
|
|
46
46
|
# Load classes from given paths - using path/glob pattern.
|
@@ -52,7 +52,7 @@ if defined?(Merb::Plugins)
|
|
52
52
|
|
53
53
|
# Reload the router - takes all_slices into account to load slices at runtime.
|
54
54
|
def reload_router!
|
55
|
-
Merb::BootLoader::
|
55
|
+
Merb::BootLoader::Router.reload!
|
56
56
|
end
|
57
57
|
|
58
58
|
# Slice-level paths for all loaded slices.
|
@@ -34,7 +34,7 @@ module Merb
|
|
34
34
|
self.send(:extend, Merb::Slices::ControllerMixin::MixinMethods)
|
35
35
|
end
|
36
36
|
# Reference this controller's slice module
|
37
|
-
self.class_inheritable_accessor :slice
|
37
|
+
self.class_inheritable_accessor :slice, :instance_writer => false
|
38
38
|
self.slice = slice_mod
|
39
39
|
# Setup template roots
|
40
40
|
if options[:templates_for]
|
@@ -86,12 +86,39 @@ module Merb
|
|
86
86
|
def slice; self.class.slice; end
|
87
87
|
|
88
88
|
# Generate a url - takes the slice's :path_prefix into account.
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
89
|
+
#
|
90
|
+
# @param *args<Array[Symbol,Hash]>
|
91
|
+
# There are several possibilities regarding arguments:
|
92
|
+
# - when passing a Hash only, the :default route of the current
|
93
|
+
# slice will be used
|
94
|
+
# - when a single Symbol is passed, it's used as the route name,
|
95
|
+
# while the slice itself will be the current one
|
96
|
+
# - when two Symbols are passed, the first will be the slice name,
|
97
|
+
# the second will be the route name
|
98
|
+
# - a Hash with additional params can optionally be passed
|
99
|
+
#
|
100
|
+
# @return <String> A uri based on the requested slice.
|
101
|
+
#
|
102
|
+
# @example slice_url(:controller => 'foo', :action => 'bar')
|
103
|
+
# @example slice_url(:awesome, :format => 'html')
|
104
|
+
# @example slice_url(:forum, :posts, :format => 'xml')
|
105
|
+
def slice_url(*args)
|
106
|
+
opts = args.last.is_a?(Hash) ? args.pop : {}
|
107
|
+
slice_name, route_name = if args[0].is_a?(Symbol) && args[1].is_a?(Symbol)
|
108
|
+
[args.shift, args.shift] # other slice identifier, route name
|
109
|
+
elsif args[0].is_a?(Symbol)
|
110
|
+
[slice.identifier_sym, args.shift] # self, route name
|
111
|
+
else
|
112
|
+
[slice.identifier_sym, :default] # self, default route
|
113
|
+
end
|
114
|
+
|
115
|
+
routes = Merb::Slices.named_routes[slice_name]
|
116
|
+
unless routes && route = routes[route_name]
|
117
|
+
raise Merb::Router::GenerationError, "Named route not found: #{route_name}"
|
118
|
+
end
|
119
|
+
|
120
|
+
args.push(opts)
|
121
|
+
route.generate(args, params)
|
95
122
|
end
|
96
123
|
|
97
124
|
private
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require "
|
1
|
+
require "merb-core/tasks/merb_rake_helper"
|
2
2
|
|
3
3
|
desc "Show information on application slices"
|
4
4
|
task :slices => [ "slices:list" ]
|
@@ -22,42 +22,13 @@ namespace :slices do
|
|
22
22
|
task :install_as_gem do
|
23
23
|
if ENV['GEM']
|
24
24
|
ENV['GEM_DIR'] ||= File.join(Merb.root, 'gems')
|
25
|
-
|
26
|
-
|
25
|
+
options = { :install_dir => ENV['GEM_DIR'],
|
26
|
+
:cache => true, :ignore_dependencies => true }
|
27
|
+
options[:version] = ENV['VERSION'] if ENV['VERSION']
|
28
|
+
Merb::RakeHelper.install_package(ENV['GEM'], options)
|
27
29
|
else
|
28
30
|
puts "No slice GEM specified"
|
29
31
|
end
|
30
32
|
end
|
31
33
|
|
32
|
-
# Install a gem - looks remotely and locally; won't process rdoc or ri options.
|
33
|
-
def install_gem(install_dir, gem, version = nil)
|
34
|
-
Gem.configuration.update_sources = false
|
35
|
-
Gem.clear_paths # default to plain rubygems path
|
36
|
-
installer = Gem::DependencyInstaller.new(:install_dir => install_dir)
|
37
|
-
exception = nil
|
38
|
-
begin
|
39
|
-
installer.install gem, version
|
40
|
-
rescue Gem::InstallError => e
|
41
|
-
exception = e
|
42
|
-
rescue Gem::GemNotFoundException => e
|
43
|
-
puts "Locating #{gem} in local gem path cache..."
|
44
|
-
spec = if version
|
45
|
-
Gem.source_index.find_name(gem, "= #{version}").first
|
46
|
-
else
|
47
|
-
Gem.source_index.find_name(gem).sort_by { |g| g.version }.last
|
48
|
-
end
|
49
|
-
if spec && File.exists?(gem_file =
|
50
|
-
File.join(spec.installation_path, 'cache', "#{spec.full_name}.gem"))
|
51
|
-
installer.install gem_file
|
52
|
-
end
|
53
|
-
exception = e
|
54
|
-
end
|
55
|
-
if installer.installed_gems.empty? && e
|
56
|
-
puts "Failed to install gem '#{gem}' (#{e.message})"
|
57
|
-
end
|
58
|
-
installer.installed_gems.each do |spec|
|
59
|
-
puts "Successfully installed #{spec.full_name}"
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
34
|
end
|
data/lib/merb-slices/module.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
module Merb
|
2
2
|
module Slices
|
3
3
|
|
4
|
-
VERSION = "0.9.
|
4
|
+
VERSION = "0.9.8"
|
5
5
|
|
6
6
|
class << self
|
7
|
-
|
7
|
+
|
8
8
|
# Retrieve a slice module by name
|
9
9
|
#
|
10
10
|
# @param <#to_s> The slice module to check for.
|
@@ -74,7 +74,7 @@ module Merb
|
|
74
74
|
# @param slice_module<#to_s> The Slice module to unregister.
|
75
75
|
def unregister(slice_module)
|
76
76
|
if (slice = self[slice_module]) && self.paths.delete(module_name = slice.name)
|
77
|
-
slice.loadable_files.each { |file| Merb::Slices::Loader.
|
77
|
+
slice.loadable_files.each { |file| Merb::Slices::Loader.remove_classes_in_file file }
|
78
78
|
Object.send(:remove_const, module_name)
|
79
79
|
unless Object.const_defined?(module_name)
|
80
80
|
Merb.logger.info!("Unregistered slice #{module_name}")
|
@@ -182,6 +182,12 @@ module Merb
|
|
182
182
|
DynamicLoader.stop
|
183
183
|
end
|
184
184
|
|
185
|
+
# @return <Hash[Hash]>
|
186
|
+
# A Hash mapping between slice identifiers and non-prefixed named routes.
|
187
|
+
def named_routes
|
188
|
+
@named_routes ||= {}
|
189
|
+
end
|
190
|
+
|
185
191
|
# @return <Hash>
|
186
192
|
# The configuration loaded from Merb.root / "config/slices.yml" or, if
|
187
193
|
# the load fails, an empty hash.
|
@@ -2,10 +2,12 @@ module Merb
|
|
2
2
|
module Slices
|
3
3
|
module ModuleMixin
|
4
4
|
|
5
|
+
# See bin/slice for this - used by ModuleMixin#push_app_path
|
6
|
+
$SLICE_MODULE ||= false
|
7
|
+
|
5
8
|
def self.extended(slice_module)
|
6
9
|
slice_module.meta_class.module_eval do
|
7
10
|
attr_accessor :identifier, :identifier_sym, :root, :file
|
8
|
-
attr_accessor :routes, :named_routes
|
9
11
|
attr_accessor :description, :version, :author
|
10
12
|
end
|
11
13
|
end
|
@@ -33,7 +35,12 @@ module Merb
|
|
33
35
|
|
34
36
|
# Check if there have been any routes setup.
|
35
37
|
def routed?
|
36
|
-
self.
|
38
|
+
self.named_routes && !self.named_routes.empty?
|
39
|
+
end
|
40
|
+
|
41
|
+
# Whether we're in an application or running from the slice dir itself.
|
42
|
+
def standalone?
|
43
|
+
Merb.root == self.root
|
37
44
|
end
|
38
45
|
|
39
46
|
# Return a value suitable for routes/urls.
|
@@ -58,6 +65,11 @@ module Merb
|
|
58
65
|
Merb::Slices::config[self.identifier_sym] ||= {}
|
59
66
|
end
|
60
67
|
|
68
|
+
# @return <Hash> The named routes for this slice.
|
69
|
+
def named_routes
|
70
|
+
Merb::Slices.named_routes[self.identifier_sym] ||= {}
|
71
|
+
end
|
72
|
+
|
61
73
|
# Load slice and it's classes located in the slice-level load paths.
|
62
74
|
#
|
63
75
|
# Assigns collected_slice_paths and collected_app_paths, then loads
|
@@ -93,35 +105,6 @@ module Merb
|
|
93
105
|
def collected_app_paths
|
94
106
|
@collected_app_paths ||= []
|
95
107
|
end
|
96
|
-
|
97
|
-
# Generate a url - takes the slice's :path_prefix into account.
|
98
|
-
#
|
99
|
-
# This is only relevant for default routes, as named routes are
|
100
|
-
# handled correctly without any special considerations.
|
101
|
-
#
|
102
|
-
# @param name<#to_sym,Hash> The name of the URL to generate.
|
103
|
-
# @param rparams<Hash> Parameters for the route generation.
|
104
|
-
#
|
105
|
-
# @return String The generated URL.
|
106
|
-
#
|
107
|
-
# @notes If a hash is used as the first argument, a default route will be
|
108
|
-
# generated based on it and rparams.
|
109
|
-
def url(name, rparams = {}, defaults = {})
|
110
|
-
defaults = rparams if name.is_a?(Hash) && defaults.empty?
|
111
|
-
rparams = name if name.is_a?(Hash)
|
112
|
-
|
113
|
-
if name.is_a?(Symbol)
|
114
|
-
raise "Named route not found: #{name}" unless self.named_routes[name]
|
115
|
-
uri = Merb::Router.generate(name, rparams, defaults)
|
116
|
-
else
|
117
|
-
defaults[:controller] = defaults[:controller].gsub(%r|^#{self.identifier_sym}/|, '') if defaults[:controller]
|
118
|
-
uri = Merb::Router.generate(name, rparams, defaults)
|
119
|
-
uri = self[:path_prefix] / uri unless self[:path_prefix].blank?
|
120
|
-
uri = "/#{uri}" unless uri[0,1] == '/'
|
121
|
-
end
|
122
|
-
|
123
|
-
Merb::Config[:path_prefix] ? Merb::Config[:path_prefix] + uri : uri
|
124
|
-
end
|
125
108
|
|
126
109
|
# The slice-level load paths to use when loading the slice.
|
127
110
|
#
|
@@ -239,8 +222,13 @@ module Merb
|
|
239
222
|
# @param path<String> The full path
|
240
223
|
# @param file_glob<String>
|
241
224
|
# A glob that will be used to autoload files under the path. Defaults to "**/*.rb".
|
225
|
+
#
|
226
|
+
# @note The :public path is adapted when the slice is run from bin/slice.
|
242
227
|
def push_app_path(type, path, file_glob = "**/*.rb")
|
243
228
|
enforce!(type => Symbol)
|
229
|
+
if type == :public && standalone? && $SLICE_MODULE
|
230
|
+
path.gsub!(/\/slices\/#{self.identifier}$/, '')
|
231
|
+
end
|
244
232
|
app_paths[type] = [path, file_glob]
|
245
233
|
end
|
246
234
|
|
@@ -15,7 +15,7 @@ module Merb
|
|
15
15
|
# @yield A new Behavior instance is yielded in the block for nested routes.
|
16
16
|
# @yieldparam ns<Behavior> The namespace behavior object.
|
17
17
|
#
|
18
|
-
# @example
|
18
|
+
# @example all_slices('BlogSlice' => 'blog', 'ForumSlice' => { :path => 'forum' })
|
19
19
|
#
|
20
20
|
# @note The block is yielded for each slice individually.
|
21
21
|
def all_slices(config = {}, &block)
|
@@ -41,16 +41,19 @@ module Merb
|
|
41
41
|
if Merb::Slices.exists?(slice_module)
|
42
42
|
options = { :path => options } if options.is_a?(String)
|
43
43
|
slice_module = Object.full_const_get(slice_module.to_s.camel_case) if slice_module.class.in?(String, Symbol)
|
44
|
-
namespace = options[:namespace] || slice_module.
|
45
|
-
options[:path] ||= slice_module[:path_prefix] || options[:namespace] || slice_module.identifier
|
44
|
+
namespace = options[:namespace] || slice_module.identifier_sym
|
45
|
+
options[:path] ||= options[:path_prefix] || slice_module[:path_prefix] || options[:namespace] || slice_module.identifier
|
46
46
|
options[:default_routes] = true unless options.key?(:default_routes)
|
47
47
|
options[:prepend_routes] = block if block_given?
|
48
48
|
slice_module[:path_prefix] = options[:path]
|
49
49
|
Merb.logger.info!("Mounting slice #{slice_module} at /#{options[:path]}")
|
50
50
|
|
51
|
+
# reset the inherited controller prefix - especially for 'slice' entries (see below)
|
52
|
+
@options[:controller_prefix] = nil if options.delete(:reset_controller_prefix)
|
53
|
+
|
51
54
|
# setup routes - capture the slice's routes for easy reference
|
52
|
-
|
53
|
-
|
55
|
+
self.namespace(namespace, options.except(:default_routes, :prepend_routes, :append_routes, :path_prefix)) do |ns|
|
56
|
+
Merb::Slices.named_routes[slice_module.identifier_sym] = ns.capture do
|
54
57
|
options[:prepend_routes].call(ns) if options[:prepend_routes].respond_to?(:call)
|
55
58
|
slice_module.setup_router(ns) # setup the routes from the slice itself
|
56
59
|
options[:append_routes].call(ns) if options[:append_routes].respond_to?(:call)
|
@@ -65,9 +68,9 @@ module Merb
|
|
65
68
|
|
66
69
|
# Insert a slice directly into the current router context.
|
67
70
|
#
|
68
|
-
# This will still setup a namespace, but doesn't set a path prefix.
|
71
|
+
# This will still setup a namespace, but doesn't set a path prefix. Only for special cases.
|
69
72
|
def slice(slice_module, options = {}, &block)
|
70
|
-
add_slice(slice_module, options.merge(:path => ''), &block)
|
73
|
+
add_slice(slice_module, options.merge(:path => '', :reset_controller_prefix => true), &block)
|
71
74
|
end
|
72
75
|
|
73
76
|
end
|
@@ -1,14 +1,43 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/spec_helper'
|
2
2
|
|
3
|
+
slices_path = File.dirname(__FILE__) / 'slices'
|
4
|
+
|
3
5
|
describe Merb::Generators::FullSliceGenerator do
|
4
6
|
|
5
7
|
describe "templates" do
|
6
8
|
|
9
|
+
before(:all) { FileUtils.rm_rf(slices_path / 'testing') rescue nil }
|
10
|
+
after(:all) { FileUtils.rm_rf(slices_path / 'testing') rescue nil }
|
11
|
+
|
7
12
|
before do
|
8
|
-
@generator = Merb::Generators::FullSliceGenerator.new(
|
13
|
+
@generator = Merb::Generators::FullSliceGenerator.new(slices_path, {}, 'testing')
|
9
14
|
end
|
10
15
|
|
11
|
-
it "should create a number of templates"
|
16
|
+
it "should create a number of templates" do
|
17
|
+
@generator.invoke!
|
18
|
+
files = Dir[slices_path / 'testing' / '**' / '*'].map do |path|
|
19
|
+
path.relative_path_from(slices_path)
|
20
|
+
end
|
21
|
+
expected = [
|
22
|
+
"testing/app", "testing/app/controllers", "testing/app/controllers/application.rb",
|
23
|
+
"testing/app/controllers/main.rb", "testing/app/helpers",
|
24
|
+
"testing/app/helpers/application_helper.rb", "testing/app/views",
|
25
|
+
"testing/app/views/layout", "testing/app/views/layout/testing.html.erb",
|
26
|
+
"testing/app/views/main", "testing/app/views/main/index.html.erb",
|
27
|
+
"testing/config", "testing/config/init.rb", "testing/lib", "testing/lib/testing",
|
28
|
+
"testing/lib/testing/merbtasks.rb", "testing/lib/testing/slicetasks.rb",
|
29
|
+
"testing/lib/testing/spectasks.rb", "testing/lib/testing.rb",
|
30
|
+
"testing/LICENSE", "testing/public", "testing/public/javascripts",
|
31
|
+
"testing/public/javascripts/master.js", "testing/public/stylesheets",
|
32
|
+
"testing/public/stylesheets/master.css", "testing/Rakefile",
|
33
|
+
"testing/README", "testing/spec", "testing/spec/controllers",
|
34
|
+
"testing/spec/controllers/main_spec.rb", "testing/spec/spec_helper.rb",
|
35
|
+
"testing/spec/testing_spec.rb", "testing/stubs", "testing/stubs/app",
|
36
|
+
"testing/stubs/app/controllers", "testing/stubs/app/controllers/application.rb",
|
37
|
+
"testing/stubs/app/controllers/main.rb", "testing/TODO"
|
38
|
+
]
|
39
|
+
files.should == expected
|
40
|
+
end
|
12
41
|
|
13
42
|
it "should render templates successfully" do
|
14
43
|
lambda { @generator.render! }.should_not raise_error
|
@@ -0,0 +1,162 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
slices_path = File.dirname(__FILE__) / 'slices'
|
4
|
+
|
5
|
+
describe "A slice" do
|
6
|
+
|
7
|
+
before(:all) do
|
8
|
+
self.current_slice_root = slices_path / 'full-test-slice'
|
9
|
+
|
10
|
+
# Uncomment this re-generate the slice - but remove the specs dir!
|
11
|
+
|
12
|
+
# FileUtils.rm_rf(slices_path / 'full-test-slice') rescue nil
|
13
|
+
# generator = Merb::Generators::FullSliceGenerator.new(slices_path, {}, 'full-test-slice')
|
14
|
+
# generator.invoke!
|
15
|
+
|
16
|
+
# Add the slice to the search path
|
17
|
+
Merb::Plugins.config[:merb_slices][:auto_register] = true
|
18
|
+
Merb::Plugins.config[:merb_slices][:search_path] = slices_path
|
19
|
+
|
20
|
+
Merb.start(
|
21
|
+
:testing => true,
|
22
|
+
:adapter => 'runner',
|
23
|
+
:environment => ENV['MERB_ENV'] || 'test',
|
24
|
+
:merb_root => Merb.root
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Uncomment this re-generate the slice
|
29
|
+
|
30
|
+
# after(:all) do
|
31
|
+
# FileUtils.rm_rf(slices_path / 'full-test-slice') rescue nil
|
32
|
+
# end
|
33
|
+
|
34
|
+
before :all do
|
35
|
+
Merb::Router.prepare { add_slice(:FullTestSlice) }
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should be registered in Merb::Slices.slices" do
|
39
|
+
Merb::Slices.slices.should include(FullTestSlice)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should be registered in Merb::Slices.paths" do
|
43
|
+
Merb::Slices.paths[FullTestSlice.name].should == current_slice_root
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should have an :identifier property" do
|
47
|
+
FullTestSlice.identifier.should == "full-test-slice"
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should have an :identifier_sym property" do
|
51
|
+
FullTestSlice.identifier_sym.should == :full_test_slice
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should have a :root property" do
|
55
|
+
FullTestSlice.root.should == Merb::Slices.paths[FullTestSlice.name]
|
56
|
+
FullTestSlice.root_path('app').should == current_slice_root / 'app'
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should have a :file property" do
|
60
|
+
FullTestSlice.file.should == current_slice_root / 'lib' / 'full-test-slice.rb'
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should have metadata properties" do
|
64
|
+
FullTestSlice.description.should == "FullTestSlice is a chunky Merb slice!"
|
65
|
+
FullTestSlice.version.should == "0.0.1"
|
66
|
+
FullTestSlice.author.should == "YOUR NAME"
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should have a :named_routes property" do
|
70
|
+
FullTestSlice.named_routes[:default].should be_kind_of(Merb::Router::Route)
|
71
|
+
FullTestSlice.named_routes[:index].should be_kind_of(Merb::Router::Route)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should have a config property (Hash)" do
|
75
|
+
FullTestSlice.config.should be_kind_of(Hash)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should have bracket accessors as shortcuts to the config" do
|
79
|
+
FullTestSlice[:foo] = 'bar'
|
80
|
+
FullTestSlice[:foo].should == 'bar'
|
81
|
+
FullTestSlice[:foo].should == FullTestSlice.config[:foo]
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should have a :layout config option set" do
|
85
|
+
FullTestSlice.config[:layout].should == :full_test_slice
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should have a dir_for method" do
|
89
|
+
app_path = FullTestSlice.dir_for(:application)
|
90
|
+
app_path.should == current_slice_root / 'app'
|
91
|
+
[:view, :model, :controller, :helper, :mailer, :part].each do |type|
|
92
|
+
FullTestSlice.dir_for(type).should == app_path / "#{type}s"
|
93
|
+
end
|
94
|
+
public_path = FullTestSlice.dir_for(:public)
|
95
|
+
public_path.should == current_slice_root / 'public'
|
96
|
+
[:stylesheet, :javascript, :image].each do |type|
|
97
|
+
FullTestSlice.dir_for(type).should == public_path / "#{type}s"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should have a app_dir_for method" do
|
102
|
+
root_path = FullTestSlice.app_dir_for(:root)
|
103
|
+
root_path.should == Merb.root / 'slices' / 'full-test-slice'
|
104
|
+
app_path = FullTestSlice.app_dir_for(:application)
|
105
|
+
app_path.should == root_path / 'app'
|
106
|
+
[:view, :model, :controller, :helper, :mailer, :part].each do |type|
|
107
|
+
FullTestSlice.app_dir_for(type).should == app_path / "#{type}s"
|
108
|
+
end
|
109
|
+
public_path = FullTestSlice.app_dir_for(:public)
|
110
|
+
public_path.should == Merb.dir_for(:public) / 'slices' / 'full-test-slice'
|
111
|
+
[:stylesheet, :javascript, :image].each do |type|
|
112
|
+
FullTestSlice.app_dir_for(type).should == public_path / "#{type}s"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should have a public_dir_for method" do
|
117
|
+
public_path = FullTestSlice.public_dir_for(:public)
|
118
|
+
public_path.should == '/slices' / 'full-test-slice'
|
119
|
+
[:stylesheet, :javascript, :image].each do |type|
|
120
|
+
FullTestSlice.public_dir_for(type).should == public_path / "#{type}s"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should have a public_path_for method" do
|
125
|
+
public_path = FullTestSlice.public_dir_for(:public)
|
126
|
+
FullTestSlice.public_path_for("path", "to", "file").should == public_path / "path" / "to" / "file"
|
127
|
+
[:stylesheet, :javascript, :image].each do |type|
|
128
|
+
FullTestSlice.public_path_for(type, "path", "to", "file").should == public_path / "#{type}s" / "path" / "to" / "file"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should have a app_path_for method" do
|
133
|
+
FullTestSlice.app_path_for("path", "to", "file").should == FullTestSlice.app_dir_for(:root) / "path" / "to" / "file"
|
134
|
+
FullTestSlice.app_path_for(:controller, "path", "to", "file").should == FullTestSlice.app_dir_for(:controller) / "path" / "to" / "file"
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should have a slice_path_for method" do
|
138
|
+
FullTestSlice.slice_path_for("path", "to", "file").should == FullTestSlice.dir_for(:root) / "path" / "to" / "file"
|
139
|
+
FullTestSlice.slice_path_for(:controller, "path", "to", "file").should == FullTestSlice.dir_for(:controller) / "path" / "to" / "file"
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should keep a list of path component types to use when copying files" do
|
143
|
+
(FullTestSlice.mirrored_components & FullTestSlice.slice_paths.keys).length.should == FullTestSlice.mirrored_components.length
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should have a slice_url helper method for slice-specific routes" do
|
147
|
+
controller = dispatch_to(FullTestSlice::Main, 'index')
|
148
|
+
|
149
|
+
url = controller.url(:full_test_slice_default, :controller => 'main', :action => 'show', :format => 'html')
|
150
|
+
url.should == "/full-test-slice/main/show.html"
|
151
|
+
controller.slice_url(:controller => 'main', :action => 'show', :format => 'html').should == url
|
152
|
+
|
153
|
+
url = controller.url(:full_test_slice_index, :format => 'html')
|
154
|
+
url.should == "/full-test-slice/index.html"
|
155
|
+
controller.slice_url(:index, :format => 'html').should == url
|
156
|
+
|
157
|
+
url = controller.url(:full_test_slice_home)
|
158
|
+
url.should == "/full-test-slice/"
|
159
|
+
controller.slice_url(:home).should == url
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|