r3_plugin_toolbox 0.3.5 → 0.3.6

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 (41) hide show
  1. data/.document +0 -0
  2. data/.gitignore +0 -0
  3. data/.rspec +0 -0
  4. data/LICENSE +0 -0
  5. data/README.markdown +11 -6
  6. data/Rakefile +1 -0
  7. data/VERSION +1 -1
  8. data/config/database.yml +0 -0
  9. data/lib/r3_plugin_toolbox.rb +1 -1
  10. data/lib/r3_plugin_toolbox/engine.rb +77 -0
  11. data/lib/r3_plugin_toolbox/extender.rb +72 -0
  12. data/lib/r3_plugin_toolbox/extender/load_handler.rb +39 -0
  13. data/lib/r3_plugin_toolbox/extender/util.rb +64 -0
  14. data/lib/r3_plugin_toolbox/main.rb +5 -0
  15. data/lib/r3_plugin_toolbox/railtie.rb +85 -0
  16. data/lib/r3_plugin_toolbox/rspec/config.rb +14 -0
  17. data/lib/r3_plugin_toolbox/rspec/macro.rb +33 -0
  18. data/lib/r3_plugin_toolbox/rspec/matchers/be_extended_with.rb +66 -0
  19. data/lib/r3_plugin_toolbox/shortcuts.rb +11 -0
  20. data/log/development.log +0 -0
  21. data/r3_plugin_toolbox.gemspec +30 -16
  22. data/spec/fixtures/extension_modules.rb +29 -0
  23. data/spec/r3_plugin_toolbox/engine_spec.rb +17 -0
  24. data/spec/{plugin_toolbox → r3_plugin_toolbox/extender}/extend_view_content_spec.rb +5 -2
  25. data/spec/{plugin_toolbox → r3_plugin_toolbox/extender}/extender_action_spec.rb +4 -4
  26. data/spec/{plugin_toolbox → r3_plugin_toolbox/extender}/extender_i18n_spec.rb +2 -2
  27. data/spec/{plugin_toolbox → r3_plugin_toolbox}/extender_spec.rb +3 -3
  28. data/spec/r3_plugin_toolbox/railtie_spec.rb +16 -0
  29. data/spec/r3_plugin_toolbox/shortcuts_spec.rb +54 -0
  30. data/spec/spec_helper.rb +3 -32
  31. data/wiki/add_rake_tasks.markdown +0 -0
  32. data/wiki/engine.markdown +0 -0
  33. data/wiki/how_to_guide.markdown +0 -0
  34. metadata +49 -21
  35. data/lib/plugin_toolbox/extender.rb +0 -65
  36. data/lib/plugin_toolbox/loader.rb +0 -32
  37. data/lib/plugin_toolbox/rspec/config.rb +0 -12
  38. data/lib/plugin_toolbox/rspec/macro.rb +0 -32
  39. data/lib/plugin_toolbox/rspec/matchers/be_extended_with.rb +0 -64
  40. data/lib/plugin_toolbox/util.rb +0 -62
  41. data/rails3_plugin_toolbox.gemspec +0 -78
data/.document CHANGED
File without changes
data/.gitignore CHANGED
File without changes
data/.rspec CHANGED
File without changes
data/LICENSE CHANGED
File without changes
data/README.markdown CHANGED
@@ -1,10 +1,15 @@
1
- # Rails 3 Plugin Toolbox
1
+
2
+ # Rails3 Plugin Toolbox
2
3
 
3
4
  This is a small toolbox that greatly facilitates creating Plugins for Rails 3 without having to know a lot about the Rails 3 internals and Plugin architecture.
4
5
  The toolbox provides a convenient DSL that abstracts away the internal Rails 3 plugin wiring to an even greater extent, making the DSL dead simple to use!
5
6
 
6
7
  I also provide a specialized RSpec 2 matcher *be_extended_with* which makes it easy to spec your plugin extension functionality, to make sure Rails is extended with
7
- the functionality (modules) that you expect and desire ;)
8
+ the functionality (modules) that you expect and desire ;)
9
+
10
+ Good description of the Rails 3 plugin structure on this gist by Jose Valim:
11
+
12
+ _INFO_: [Rails 3 plugin architecture](https://gist.github.com/af7e572c2dc973add221)
8
13
 
9
14
  ## Install
10
15
 
@@ -18,7 +23,7 @@ the functionality (modules) that you expect and desire ;)
18
23
  require 'rails/all'
19
24
  require 'r3_plugin_toolbox'
20
25
 
21
- Rails3::PluginExtender.new do
26
+ Rails3::Plugin::Extender.new do
22
27
  extend_from_module Ultra::View, :stuff, :in => :view
23
28
  extend_with Ultra::Controller, :in => :controller
24
29
 
@@ -52,7 +57,7 @@ end
52
57
  More API examples
53
58
 
54
59
  <pre>
55
- Rails3::PluginExtender.new do
60
+ Rails3::Plugin::Extender.new do
56
61
  extend_rails :view do # or use :action_view
57
62
  with MyViewAddition
58
63
  end
@@ -100,7 +105,7 @@ require 'rails/all'
100
105
 
101
106
  describe "My Plugin rails extensions" do
102
107
  it "should extend Action View with View Helpers" do
103
- Rails3::PluginExtender.new do
108
+ Rails3::Plugin::Extender.new do
104
109
  extend_rails :view do
105
110
  extend_from_module Helper::View, :panel, :window
106
111
  extend_with Helper::View::Button, Helper::View::Form
@@ -127,7 +132,7 @@ end
127
132
 
128
133
  describe "My other Plugin rails extensions" do
129
134
  before :each do
130
- Rails3::PluginExtender.new do
135
+ Rails3::Plugin::Extender.new do
131
136
  extend_rails :view do
132
137
  extend_from_module Helper::View, :grid, :tree
133
138
  end
data/Rakefile CHANGED
@@ -9,6 +9,7 @@ begin
9
9
  gem.authors = ["Kristian Mandrup"]
10
10
  gem.add_development_dependency "rspec", "~> 2.0.0"
11
11
 
12
+ gem.add_development_dependency "rspec", ">= 2.0.0.beta.19"
12
13
  gem.add_dependency "rails", "~> 3.0.0"
13
14
  gem.add_dependency "require_all", "~> 1.1.0"
14
15
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.5
1
+ 0.3.6
data/config/database.yml CHANGED
File without changes
@@ -4,4 +4,4 @@ end
4
4
  require 'active_support/inflector'
5
5
  require 'require_all'
6
6
 
7
- require_all File.dirname(__FILE__) + '/plugin_toolbox'
7
+ require_all File.dirname(__FILE__) + '/r3_plugin_toolbox'
@@ -0,0 +1,77 @@
1
+ # See: http://edgeapi.rubyonrails.org/classes/Rails/Engine.html
2
+
3
+ # Any Rails::Engine is also a Rails::Railtie, so the same methods (like rake_tasks and generators) and configuration available in the latter can also be used in the former.
4
+
5
+ require 'r3_plugin_toolbox/railtie'
6
+
7
+ def make_engine module_name
8
+ eval %{
9
+ module #{module_name}
10
+ class Engine < ::Rails::Engine
11
+ extend ::Rails3::Engine::Assist
12
+ end
13
+ end
14
+ }
15
+ end
16
+
17
+ module Rails3
18
+ class Engine < ::Rails3::Plugin
19
+ attr_reader :name
20
+
21
+ def initialize name, &block
22
+ @name = name
23
+ module_name = name.to_s.camelize
24
+ make_engine module_name
25
+
26
+ engine = "#{module_name}::Engine".constantize
27
+
28
+ if block
29
+ block.arity < 1 ? engine.instance_eval(&block) : block.call(engine)
30
+ end
31
+ end
32
+
33
+ module Assist
34
+ include ::Rails3::Plugin::Assist
35
+
36
+ [:autoload, :eagerload].each do |name|
37
+ class_eval %{
38
+ def add_#{name}_paths path
39
+ config.#{name}_paths << path
40
+ end
41
+ }
42
+ end
43
+
44
+ [:controllers, :helpers, :models, :views].each do |name|
45
+ class_eval %{
46
+ def add_#{name}_dir path
47
+ paths.app.#{name} << path
48
+ end
49
+ }
50
+ end
51
+
52
+ [:initializers, :locales, :routes].each do |name|
53
+ class_eval %{
54
+ def add_#{name}_dir path
55
+ paths.config.#{name} << path
56
+ end
57
+ }
58
+ end
59
+
60
+ def add_tasks_dir path
61
+ paths.lib.tasks << path
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ # Example
68
+
69
+ # class MyEngine < Rails::Engine
70
+ # # Add a load path for this specific Engine
71
+ # config.autoload_paths << File.expand_path("../lib/some/path", __FILE__)
72
+ #
73
+ # initializer "my_engine.add_middleware" do |app|
74
+ # app.middleware.use MyEngine::Middleware
75
+ # end
76
+ # end
77
+
@@ -0,0 +1,72 @@
1
+ require 'r3_plugin_toolbox/extender/util'
2
+ require 'r3_plugin_toolbox/extender/load_handler'
3
+
4
+ module Rails3
5
+ class Plugin
6
+ class Extender
7
+ include LoadHandler
8
+
9
+ def initialize &block
10
+ if block
11
+ block.arity < 1 ? self.instance_eval(&block) : block.call(self)
12
+ end
13
+ end
14
+
15
+ # load after: [:initialize, :configuration, :eager_load]
16
+ def extend_rails(type, &block)
17
+ on_load(type, &block)
18
+ end
19
+
20
+
21
+ # convenience method to extend with multiple modules all within the same base module
22
+ def extend_from_module base_name, *module_names, options
23
+ raise ArgumentError, "You must specify an options Hash as the last argument for #extend_from_module" if !options.kind_of? Hash
24
+ module_names.each do |name|
25
+ extend_with get_constant(base_name, name), options
26
+ end
27
+ end
28
+
29
+ def extend_with *module_names, options
30
+ raise ArgumentError, "You must specify an options Hash as the last argument for #extend_with" if !options.kind_of? Hash
31
+ type = options[:in]
32
+ raise ArgumentError, "You must specify an :in option to indicate which Rails 3 component base class to extend with #{module_names}" if !type
33
+ module_names.each do |name|
34
+ extend! name, type
35
+ end
36
+ end
37
+
38
+ module DSL
39
+ include ::Rails3::Plugin::Extender::LoadHandler
40
+
41
+ def extend_from_module base_name, *module_names
42
+ module_names.each do |name|
43
+ include get_constant(base_name, name)
44
+ end
45
+ end
46
+
47
+ def extend_with *module_names
48
+ module_names.each do |module_name|
49
+ begin
50
+ include get_module(module_name)
51
+ rescue
52
+ raise ArgumentError, "Unable to extend with #{module_name}"
53
+ end
54
+ end
55
+ end
56
+ alias_method :with, :extend_with
57
+ end
58
+
59
+ protected
60
+
61
+ def extend! module_name, type
62
+ do_extend! get_module(module_name), get_load_type(type.to_sym)
63
+ end
64
+
65
+ def do_extend! module_name, type
66
+ ActiveSupport.on_load(type) do
67
+ include module_name
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,39 @@
1
+ require 'r3_plugin_toolbox/extender/util'
2
+
3
+ module Rails3
4
+ class Plugin
5
+ class Extender
6
+ module LoadHandler
7
+ include ::Rails3::Plugin::Extender::Util
8
+
9
+ def before type, &block
10
+ type = type.to_sym
11
+ raise ArgumentError, "#{type} is not a valid before hook" if !valid_before_hook? type
12
+ load_handling :"before_#{type}", &block
13
+ end
14
+
15
+ def after type, &block
16
+ type = type.to_sym
17
+ raise ArgumentError, "#{type} is not a valid after hook" if !valid_after_hook? type
18
+ load_handling :"after_#{type}", &block
19
+ end
20
+
21
+ def on_load type, &block
22
+ type = get_load_type type
23
+ raise ArgumentError, "#{type} is not a valid load hook" if !valid_load_hook? type
24
+ load_handling type, &block
25
+ end
26
+
27
+ def load_handling type, &block
28
+ ActiveSupport.on_load type do
29
+ extend Rails3::Plugin::Extender::DSL
30
+
31
+ if block
32
+ block.arity < 1 ? self.instance_eval(&block) : block.call(self)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,64 @@
1
+ module Rails3
2
+ class Plugin
3
+ class Extender
4
+ module Util
5
+ INIT = :initialize
6
+ ACTIVE_MODULES = {:AR => :active_record, :view => :action_view, :controller => :action_controller, :mailer => :action_mailer}
7
+
8
+ def get_base_class type
9
+ type = get_load_type(type).to_s
10
+ const = act_type?(type) ? rails_const_base(type) : "#{type.to_s.camelize}"
11
+ end
12
+
13
+ def act_type? type
14
+ type =~/action/ || type =~/active/
15
+ end
16
+
17
+ def get_constant base_name, name
18
+ make_constant(base_name, name).constantize
19
+ end
20
+
21
+ def rails_const_base type
22
+ "#{type.to_s.camelize}::Base"
23
+ end
24
+
25
+ def make_constant base_name, name
26
+ "#{base_name.to_s.camelize}::#{name.to_s.camelize}"
27
+ end
28
+
29
+ def get_load_type type
30
+ return ACTIVE_MODULES[type] if ACTIVE_MODULES[type]
31
+ return type if ACTIVE_MODULES.values.include? type
32
+ return type if type == :i18n
33
+ logger.warn "WARNING: The Rails 3 load handler for the component #{type} is not part of the default load process."
34
+ end
35
+
36
+ def get_module module_name
37
+ case module_name
38
+ when Module
39
+ module_name
40
+ when String
41
+ module_name.to_s.constantize
42
+ else
43
+ raise ArgumentError, "#{module_name} could not be converted into a module constant"
44
+ end
45
+ end
46
+
47
+ protected
48
+
49
+ def valid_before_hook? type
50
+ [INIT, :configuration, :eager_load].include?(type)
51
+ end
52
+
53
+ def valid_after_hook? type
54
+ INIT == type
55
+ end
56
+
57
+ def valid_load_hook? type
58
+ @valid_load_hooks ||= [ACTIVE_MODULES.keys, ACTIVE_MODULES.values, :i18n].flatten
59
+ @valid_load_hooks.include?(type)
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,5 @@
1
+ require 'r3_plugin_toolbox/railtie'
2
+ require 'r3_plugin_toolbox/extender'
3
+ require 'r3_plugin_toolbox/engine'
4
+
5
+ require_all File.dirname(__FILE__) + '/rspec'
@@ -0,0 +1,85 @@
1
+ # See: http://edgeapi.rubyonrails.org/classes/Rails/Railtie.html
2
+
3
+ # Add a to_prepare block which is executed once in production
4
+ # and before each request in development
5
+ # config.to_prepare do
6
+ # MyRailtie.setup!
7
+ # end
8
+
9
+ # rake_tasks do
10
+ # load "path/to/my_railtie.tasks"
11
+ # end
12
+
13
+ # generators do
14
+ # require "path/to/my_railtie_generator"
15
+ # end
16
+
17
+
18
+ def make_railtie name
19
+ eval %{
20
+ module #{name.to_s.camelize}
21
+ class Railtie < Rails::Railtie
22
+ extend ::Rails3::Plugin::Assist
23
+ end
24
+ end
25
+ }
26
+ end
27
+
28
+ module Rails3
29
+ class Plugin
30
+ attr_reader :name
31
+
32
+ def initialize name, &block
33
+ @name = name
34
+
35
+ module_name = name.to_s.camelize
36
+ make_railtie module_name
37
+
38
+ railtie = "#{module_name}::Railtie".constantize
39
+
40
+ if block
41
+ block.arity < 1 ? railtie.instance_eval(&block) : block.call(railtie)
42
+ end
43
+ end
44
+
45
+ module Assist
46
+ def set_test_framework name
47
+ config.generators.test_framework name
48
+ end
49
+
50
+ def use_middleware middleware
51
+ app.middleware.use middleware
52
+ end
53
+
54
+ def set_orm orm_name
55
+ config.generators.orm(orm_name)
56
+ end
57
+
58
+ def subscribe_notifications *args, &block
59
+ ActiveSupport::Notifications.subscribe do |*args|
60
+ yield *args
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ # Example
68
+
69
+ # module NewPlugin
70
+ # # namespace our plugin and inherit from Rails::Railtie
71
+ # # to get our plugin into the initialization process
72
+ # class Railtie < Rails::Railtie
73
+ #
74
+ # # configure our plugin on boot. other extension points such
75
+ # # as configuration, rake tasks, etc, are also available
76
+ # initializer "newplugin.initialize" do |app|
77
+ #
78
+ # # subscribe to all rails notifications: controllers, AR, etc.
79
+ # ActiveSupport::Notifications.subscribe do |*args|
80
+ # event = ActiveSupport::Notifications::Event.new(*args)
81
+ # puts "Got notification: #{event.inspect}"
82
+ # end
83
+ # end
84
+ # end
85
+ # end
@@ -0,0 +1,14 @@
1
+ require 'rspec'
2
+ require 'r3_plugin_toolbox/rspec/macro'
3
+ require_all File.dirname(__FILE__) + '/matchers'
4
+
5
+ RSpec.configure do |config|
6
+ config.include Rails3::Plugin::Extender::Matchers
7
+ config.extend Rails3::Plugin::Extender::Macro
8
+ end
9
+
10
+ module RSpec::Core
11
+ class ExampleGroup
12
+ include Rails3::Plugin::Extender::Macro
13
+ end
14
+ end