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.
Files changed (68) hide show
  1. data/README +4 -4
  2. data/Rakefile +27 -13
  3. data/TODO +1 -2
  4. data/bin/slice +77 -0
  5. data/lib/generators/templates/common/Rakefile +16 -12
  6. data/lib/generators/templates/full/README +4 -4
  7. data/lib/generators/templates/full/Rakefile +32 -13
  8. data/lib/generators/templates/full/config/init.rb +43 -0
  9. data/lib/generators/templates/full/lib/%base_name%.rb +3 -1
  10. data/lib/generators/templates/full/spec/%base_name%_spec.rb +10 -121
  11. data/lib/generators/templates/full/spec/controllers/main_spec.rb +18 -8
  12. data/lib/generators/templates/thin/README +4 -4
  13. data/lib/generators/templates/very_thin/README +4 -4
  14. data/lib/merb-slices.rb +3 -3
  15. data/lib/merb-slices/controller_mixin.rb +34 -7
  16. data/lib/merb-slices/merbtasks.rb +5 -34
  17. data/lib/merb-slices/module.rb +9 -3
  18. data/lib/merb-slices/module_mixin.rb +19 -31
  19. data/lib/merb-slices/router_ext.rb +10 -7
  20. data/spec/full_slice_generator_spec.rb +31 -2
  21. data/spec/full_slice_spec.rb +162 -0
  22. data/spec/merb-slice_spec.rb +97 -3
  23. data/spec/slice_generator_spec.rb +15 -3
  24. data/spec/slices/full-test-slice/LICENSE +20 -0
  25. data/spec/slices/full-test-slice/README +170 -0
  26. data/spec/slices/full-test-slice/Rakefile +67 -0
  27. data/spec/slices/full-test-slice/TODO +15 -0
  28. data/spec/slices/full-test-slice/app/controllers/application.rb +5 -0
  29. data/spec/slices/full-test-slice/app/controllers/main.rb +7 -0
  30. data/spec/slices/full-test-slice/app/helpers/application_helper.rb +64 -0
  31. data/spec/slices/full-test-slice/app/views/layout/full_test_slice.html.erb +16 -0
  32. data/spec/slices/full-test-slice/app/views/main/index.html.erb +1 -0
  33. data/spec/slices/full-test-slice/config/init.rb +43 -0
  34. data/spec/slices/full-test-slice/lib/full-test-slice.rb +80 -0
  35. data/spec/slices/full-test-slice/lib/full-test-slice/merbtasks.rb +103 -0
  36. data/spec/slices/full-test-slice/lib/full-test-slice/slicetasks.rb +18 -0
  37. data/spec/slices/full-test-slice/lib/full-test-slice/spectasks.rb +65 -0
  38. data/spec/slices/full-test-slice/public/javascripts/master.js +0 -0
  39. data/spec/slices/full-test-slice/public/stylesheets/master.css +2 -0
  40. data/spec/slices/full-test-slice/stubs/app/controllers/application.rb +2 -0
  41. data/spec/slices/full-test-slice/stubs/app/controllers/main.rb +2 -0
  42. data/spec/slices/thin-test-slice/LICENSE +20 -0
  43. data/spec/slices/thin-test-slice/README +130 -0
  44. data/spec/slices/thin-test-slice/Rakefile +43 -0
  45. data/spec/slices/thin-test-slice/TODO +7 -0
  46. data/spec/slices/thin-test-slice/application.rb +36 -0
  47. data/spec/slices/thin-test-slice/lib/thin-test-slice.rb +93 -0
  48. data/spec/slices/thin-test-slice/lib/thin-test-slice/merbtasks.rb +103 -0
  49. data/spec/slices/thin-test-slice/lib/thin-test-slice/slicetasks.rb +18 -0
  50. data/spec/slices/thin-test-slice/public/javascripts/master.js +0 -0
  51. data/spec/slices/thin-test-slice/public/stylesheets/master.css +2 -0
  52. data/spec/slices/thin-test-slice/stubs/application.rb +9 -0
  53. data/spec/slices/thin-test-slice/views/layout/thin_test_slice.html.erb +16 -0
  54. data/spec/slices/thin-test-slice/views/main/index.html.erb +1 -0
  55. data/spec/slices/very-thin-test-slice/LICENSE +20 -0
  56. data/spec/slices/very-thin-test-slice/README +110 -0
  57. data/spec/slices/very-thin-test-slice/Rakefile +43 -0
  58. data/spec/slices/very-thin-test-slice/TODO +7 -0
  59. data/spec/slices/very-thin-test-slice/application.rb +36 -0
  60. data/spec/slices/very-thin-test-slice/lib/very-thin-test-slice.rb +89 -0
  61. data/spec/slices/very-thin-test-slice/lib/very-thin-test-slice/merbtasks.rb +103 -0
  62. data/spec/slices/very-thin-test-slice/lib/very-thin-test-slice/slicetasks.rb +18 -0
  63. data/spec/spec_helper.rb +27 -2
  64. data/spec/thin_slice_generator_spec.rb +24 -2
  65. data/spec/thin_slice_spec.rb +139 -0
  66. data/spec/very_thin_slice_generator_spec.rb +22 -2
  67. data/spec/very_thin_slice_spec.rb +119 -0
  68. 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 { |r| r.add_slice(:<%= module_name %>) } if standalone?
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
- controller.slice_url(:action => 'show', :format => 'html').should == "/<%= base_name %>/main/show.html"
46
- controller.slice_url(:<%= symbol_name %>_index, :format => 'html').should == "/<%= base_name %>/index.html"
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
- r.add_slice(:<%= module_name %>)
78
+ add_slice(:<%= module_name %>)
79
79
 
80
80
  # example: /foo/:controller/:action/:id
81
81
 
82
- r.add_slice(:<%= module_name %>, 'foo') # same as :path => 'foo'
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
- r.add_slice(:<%= module_name %>, :path => ':lang', :params => { :a => 'b' })
86
+ add_slice(:<%= module_name %>, :path => ':lang', :params => { :a => 'b' })
87
87
 
88
88
  # example: /:controller/:action/:id
89
89
 
90
- r.slice(:<%= module_name %>)
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
- r.add_slice(:<%= module_name %>)
58
+ add_slice(:<%= module_name %>)
59
59
 
60
60
  # example: /foo/:controller/:action/:id
61
61
 
62
- r.add_slice(:<%= module_name %>, 'foo') # same as :path => 'foo'
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
- r.add_slice(:<%= module_name %>, :path => ':lang', :params => { :a => 'b' })
66
+ add_slice(:<%= module_name %>, :path => ':lang', :params => { :a => 'b' })
67
67
 
68
68
  # example: /:controller/:action/:id
69
69
 
70
- r.slice(:<%= module_name %>)
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 remove_file(file)
43
- Merb::BootLoader::LoadClasses.remove_file file
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::LoadClasses.reload_router!
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
- def slice_url(name, rparams={})
90
- self.slice.url(name, rparams, {
91
- :controller => controller_name,
92
- :action => action_name,
93
- :format => params[:format]
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 "rubygems/dependency_installer"
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
- puts "Installing #{ENV["GEM"]} as a local gem"
26
- install_gem(ENV['GEM_DIR'], ENV['GEM'], ENV['VERSION'])
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
@@ -1,10 +1,10 @@
1
1
  module Merb
2
2
  module Slices
3
3
 
4
- VERSION = "0.9.4"
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.remove_file file }
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.routes && !self.routes.empty?
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 r.all_slices('BlogSlice' => 'blog', 'ForumSlice' => { :path => 'forum' })
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.to_s.snake_case
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
- slice_module.routes, slice_module.named_routes = Merb::Router.capture do
53
- self.namespace(namespace.to_sym, options.except(:default_routes, :prepend_routes, :append_routes)) do |ns|
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('/tmp', {}, 'testing')
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