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.
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