merb-slices 0.9.7 → 0.9.8
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 +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
|