aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPiotr Sarnacki <drogus@gmail.com>2010-10-15 17:46:31 +0300
committerPiotr Sarnacki <drogus@gmail.com>2010-11-02 17:14:49 +0100
commitcfcea1d53ae5ce38a7cbeb41e05958dc009988b0 (patch)
treef581de5327011c5a9108fac46783aa05d676b03d
parentd446392f76c063d9f04396a1d3ca9e314a521671 (diff)
downloadrails-cfcea1d53ae5ce38a7cbeb41e05958dc009988b0.tar.gz
rails-cfcea1d53ae5ce38a7cbeb41e05958dc009988b0.tar.bz2
rails-cfcea1d53ae5ce38a7cbeb41e05958dc009988b0.zip
Added 'rails plugin new' generator which generates gem plugin skeleton.
This command is based on enginex gem by José Valim. It generates gem structure and ads dummy application into test/dummy. This can be used to start developing any kind of extension for rails 3.
-rw-r--r--railties/lib/rails/cli.rb7
-rw-r--r--railties/lib/rails/commands/plugin_new.rb16
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb225
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec9
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/Gemfile11
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/MIT-LICENSE20
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/README.rdoc3
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/Rakefile46
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/gitignore6
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%.rb.tt2
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/rails/application.rb12
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/rails/boot.rb10
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/script/rails.tt5
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/test/%name%_test.rb.tt7
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/test/integration/navigation_test.rb.tt7
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/test/support/integration_case.rb5
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb22
-rw-r--r--railties/test/fixtures/lib/plugin_builders/empty_builder.rb2
-rw-r--r--railties/test/fixtures/lib/plugin_builders/simple_builder.rb7
-rw-r--r--railties/test/fixtures/lib/plugin_builders/tweak_builder.rb7
-rw-r--r--railties/test/generators/plugin_new_generator_test.rb179
21 files changed, 607 insertions, 1 deletions
diff --git a/railties/lib/rails/cli.rb b/railties/lib/rails/cli.rb
index 1260772605..c8d70d8ffa 100644
--- a/railties/lib/rails/cli.rb
+++ b/railties/lib/rails/cli.rb
@@ -11,4 +11,9 @@ $:.unshift(railties_path) if File.directory?(railties_path) && !$:.include?(rail
require 'rails/ruby_version_check'
Signal.trap("INT") { puts; exit }
-require 'rails/commands/application'
+if ARGV.first == 'plugin'
+ ARGV.shift
+ require 'rails/commands/plugin_new'
+else
+ require 'rails/commands/application'
+end
diff --git a/railties/lib/rails/commands/plugin_new.rb b/railties/lib/rails/commands/plugin_new.rb
new file mode 100644
index 0000000000..00a7e30902
--- /dev/null
+++ b/railties/lib/rails/commands/plugin_new.rb
@@ -0,0 +1,16 @@
+require 'rails/version'
+if %w(--version -v).include? ARGV.first
+ puts "Rails #{Rails::VERSION::STRING}"
+ exit(0)
+end
+
+if ARGV.first != "new"
+ ARGV[0] = "--help"
+else
+ ARGV.shift
+end
+
+require 'rails/generators'
+require 'rails/generators/rails/plugin_new/plugin_new_generator'
+
+Rails::Generators::PluginNewGenerator.start
diff --git a/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb b/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb
new file mode 100644
index 0000000000..239115c07d
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb
@@ -0,0 +1,225 @@
+require "rails/generators/rails/app/app_generator"
+
+module Rails
+ class PluginBuilder
+ def rakefile
+ template "Rakefile"
+ end
+
+ def readme
+ copy_file "README.rdoc"
+ end
+
+ def gemfile
+ template "Gemfile"
+ end
+
+ def license
+ template "MIT-LICENSE"
+ end
+
+ def gemspec
+ template "%name%.gemspec"
+ end
+
+ def gitignore
+ copy_file "gitignore", ".gitignore"
+ end
+
+ def lib
+ directory "lib"
+ end
+
+ def test
+ directory "test"
+ end
+
+ def test_dummy
+ invoke Rails::Generators::AppGenerator,
+ [ File.expand_path(dummy_path, destination_root) ]
+ end
+
+ def test_dummy_config
+ store_application_definition!
+ template "rails/boot.rb", "#{dummy_path}/config/boot.rb", :force => true
+ template "rails/application.rb", "#{dummy_path}/config/application.rb", :force => true
+ end
+
+ def test_dummy_clean
+ inside dummy_path do
+ remove_file ".gitignore"
+ remove_file "db/seeds.rb"
+ remove_file "doc"
+ remove_file "Gemfile"
+ remove_file "lib/tasks"
+ remove_file "public/images/rails.png"
+ remove_file "public/index.html"
+ remove_file "public/robots.txt"
+ remove_file "README"
+ remove_file "test"
+ remove_file "vendor"
+ end
+ end
+
+ def script
+ directory "script" do |content|
+ "#{shebang}\n" + content
+ end
+ chmod "script", 0755, :verbose => false
+ end
+ end
+
+ module Generators
+ class PluginNewGenerator < Base
+ attr_accessor :rails_template
+
+ add_shebang_option!
+
+ argument :plugin_path, :type => :string
+
+ class_option :builder, :type => :string, :aliases => "-b",
+ :desc => "Path to a plugin builder (can be a filesystem path or URL)"
+
+ class_option :skip_gemfile, :type => :boolean, :default => false,
+ :desc => "Don't create a Gemfile"
+
+ class_option :skip_git, :type => :boolean, :aliases => "-G", :default => false,
+ :desc => "Skip Git ignores and keeps"
+
+ class_option :help, :type => :boolean, :aliases => "-h", :group => :rails,
+ :desc => "Show this help message and quit"
+
+ def self.say_step(message)
+ @step = (@step || 0) + 1
+ class_eval <<-METHOD, __FILE__, __LINE__ + 1
+ def step_#{@step}
+ #{"puts" if @step > 1}
+ say_status "STEP #{@step}", #{message.inspect}
+ end
+ METHOD
+ end
+
+ def initialize(*args)
+ raise Error, "Options should be given after plugin name. For details run: rails plugin --help" if args[0].blank?
+
+ @original_wd = Dir.pwd
+
+ super
+ end
+
+ say_step "Creating gem skeleton"
+
+ def create_root
+ self.destination_root = File.expand_path(plugin_path, destination_root)
+ valid_plugin_const?
+
+ empty_directory '.'
+ FileUtils.cd(destination_root) unless options[:pretend]
+ end
+
+ def create_root_files
+ build(:readme)
+ build(:rakefile)
+ build(:gemspec)
+ build(:license)
+ build(:gitignore) unless options[:skip_git]
+ build(:gemfile) unless options[:skip_gemfile]
+ end
+
+ def create_config_files
+ build(:config)
+ end
+
+ def create_lib_files
+ build(:lib)
+ end
+
+ def create_script_files
+ build(:script)
+ end
+
+ def create_test_files
+ build(:test) unless options[:skip_test_unit]
+ end
+
+ say_step "Vendoring Rails application at test/dummy"
+
+ def create_test_dummy_files
+ build(:test_dummy)
+ end
+
+ say_step "Configuring Rails application"
+
+ def change_config_files
+ build(:test_dummy_config)
+ end
+
+ say_step "Removing unneeded files"
+
+ def remove_uneeded_rails_files
+ build(:test_dummy_clean)
+ end
+
+ protected
+
+ def self.banner
+ "rails plugin new #{self.arguments.map(&:usage).join(' ')} [options]"
+ end
+
+ def builder
+ @builder ||= begin
+ if path = options[:builder]
+ if URI(path).is_a?(URI::HTTP)
+ contents = open(path, "Accept" => "application/x-thor-template") {|io| io.read }
+ else
+ contents = open(File.expand_path(path, @original_wd)) {|io| io.read }
+ end
+
+ prok = eval("proc { #{contents} }", TOPLEVEL_BINDING, path, 1)
+ instance_eval(&prok)
+ end
+
+ builder_class = defined?(::PluginBuilder) ? ::PluginBuilder : Rails::PluginBuilder
+ builder_class.send(:include, ActionMethods)
+ builder_class.new(self)
+ end
+ end
+
+ def build(meth, *args)
+ builder.send(meth, *args) if builder.respond_to?(meth)
+ end
+
+ def name
+ @name ||= File.basename(destination_root)
+ end
+
+ def camelized
+ @camelized ||= name.gsub(/\W/, '_').squeeze('_').camelize
+ end
+
+ def valid_plugin_const?
+ if camelized =~ /^\d/
+ raise Error, "Invalid plugin name #{name}. Please give a name which does not start with numbers."
+ elsif RESERVED_NAMES.include?(name)
+ raise Error, "Invalid plugin name #{name}. Please give a name which does not match one of the reserved rails words."
+ elsif Object.const_defined?(camelized)
+ raise Error, "Invalid plugin name #{name}, constant #{camelized} is already in use. Please choose another application name."
+ end
+ end
+
+ def dummy_path
+ "test/dummy"
+ end
+
+ def application_definition
+ @application_definition ||= begin
+ unless options[:pretend]
+ contents = File.read(File.expand_path("#{dummy_path}/config/application.rb", destination_root))
+ contents[(contents.index("module Dummy"))..-1]
+ end
+ end
+ end
+ alias :store_application_definition! :application_definition
+ end
+ end
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec b/railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec
new file mode 100644
index 0000000000..3d9bfb22c7
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec
@@ -0,0 +1,9 @@
+# Provide a simple gemspec so you can easily use your
+# project in your rails apps through git.
+Gem::Specification.new do |s|
+ s.name = "<%= name %>"
+ s.summary = "Insert <%= camelized %> summary."
+ s.description = "Insert <%= camelized %> description."
+ s.files = Dir["lib/**/*"] + ["MIT-LICENSE", "Rakefile", "README.rdoc"]
+ s.version = "0.0.1"
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile b/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile
new file mode 100644
index 0000000000..83ff86bbd8
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile
@@ -0,0 +1,11 @@
+source "http://rubygems.org"
+
+gem "rails", :git => "http://github.com/rails/rails.git"
+gem "arel" , :git => "http://github.com/rails/arel.git"
+gem "rack" , :git => "http://github.com/rack/rack.git"
+gem "capybara", ">= 0.3.9"
+gem "sqlite3-ruby", :require => "sqlite3"
+
+if RUBY_VERSION < '1.9'
+ gem "ruby-debug", ">= 0.10.3"
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/MIT-LICENSE b/railties/lib/rails/generators/rails/plugin_new/templates/MIT-LICENSE
new file mode 100644
index 0000000000..d7a9109894
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/MIT-LICENSE
@@ -0,0 +1,20 @@
+Copyright <%= Date.today.year %> YOURNAME
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/README.rdoc b/railties/lib/rails/generators/rails/plugin_new/templates/README.rdoc
new file mode 100644
index 0000000000..301d647731
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/README.rdoc
@@ -0,0 +1,3 @@
+= <%= camelized %>
+
+This project rocks and uses MIT-LICENSE. \ No newline at end of file
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/Rakefile b/railties/lib/rails/generators/rails/plugin_new/templates/Rakefile
new file mode 100644
index 0000000000..c0e6185ddc
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/Rakefile
@@ -0,0 +1,46 @@
+# encoding: UTF-8
+require 'rubygems'
+begin
+ require 'bundler/setup'
+rescue LoadError
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
+end
+
+require 'rake'
+require 'rake/rdoctask'
+require 'rake/gempackagetask'
+
+require 'rake/testtask'
+
+Rake::TestTask.new(:test) do |t|
+ t.libs << 'lib'
+ t.libs << 'test'
+ t.pattern = 'test/**/*_test.rb'
+ t.verbose = false
+end
+
+task :default => :test
+
+Rake::RDocTask.new(:rdoc) do |rdoc|
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = '<%= camelized %>'
+ rdoc.options << '--line-numbers' << '--inline-source'
+ rdoc.rdoc_files.include('README.rdoc')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
+
+spec = Gem::Specification.new do |s|
+ s.name = "<%= name %>"
+ s.summary = "Insert <%= camelized %> summary."
+ s.description = "Insert <%= camelized %> description."
+ s.files = FileList["[A-Z]*", "lib/**/*"]
+ s.version = "0.0.1"
+end
+
+Rake::GemPackageTask.new(spec) do |pkg|
+end
+
+desc "Install the gem #{spec.name}-#{spec.version}.gem"
+task :install do
+ system("gem install pkg/#{spec.name}-#{spec.version}.gem --no-ri --no-rdoc")
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/gitignore b/railties/lib/rails/generators/rails/plugin_new/templates/gitignore
new file mode 100644
index 0000000000..1463de6dfb
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/gitignore
@@ -0,0 +1,6 @@
+.bundle/
+log/*.log
+pkg/
+test/dummy/db/*.sqlite3
+test/dummy/log/*.log
+test/dummy/tmp/ \ No newline at end of file
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%.rb.tt b/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%.rb.tt
new file mode 100644
index 0000000000..cf77a0b4d3
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%.rb.tt
@@ -0,0 +1,2 @@
+module <%= camelized %>
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/rails/application.rb b/railties/lib/rails/generators/rails/plugin_new/templates/rails/application.rb
new file mode 100644
index 0000000000..fee63ea83e
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/rails/application.rb
@@ -0,0 +1,12 @@
+require File.expand_path('../boot', __FILE__)
+
+require "active_model/railtie"
+require "active_record/railtie"
+require "action_controller/railtie"
+require "action_view/railtie"
+require "action_mailer/railtie"
+
+Bundler.require
+require "<%= name %>"
+
+<%= application_definition %>
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/rails/boot.rb b/railties/lib/rails/generators/rails/plugin_new/templates/rails/boot.rb
new file mode 100644
index 0000000000..eba0681370
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/rails/boot.rb
@@ -0,0 +1,10 @@
+require 'rubygems'
+gemfile = File.expand_path('../../../../Gemfile', __FILE__)
+
+if File.exist?(gemfile)
+ ENV['BUNDLE_GEMFILE'] = gemfile
+ require 'bundler'
+ Bundler.setup
+end
+
+$:.unshift File.expand_path('../../../../lib', __FILE__) \ No newline at end of file
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/script/rails.tt b/railties/lib/rails/generators/rails/plugin_new/templates/script/rails.tt
new file mode 100644
index 0000000000..cd4f7f6ab3
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/script/rails.tt
@@ -0,0 +1,5 @@
+#!/usr/bin/env ruby
+# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
+
+ENGINE_PATH = File.expand_path('../..', __FILE__)
+load File.expand_path('../../test/dummy/script/rails', __FILE__)
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/test/%name%_test.rb.tt b/railties/lib/rails/generators/rails/plugin_new/templates/test/%name%_test.rb.tt
new file mode 100644
index 0000000000..0a8bbd4aaf
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/test/%name%_test.rb.tt
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class <%= camelized %>Test < ActiveSupport::TestCase
+ test "truth" do
+ assert_kind_of Module, <%= camelized %>
+ end
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/test/integration/navigation_test.rb.tt b/railties/lib/rails/generators/rails/plugin_new/templates/test/integration/navigation_test.rb.tt
new file mode 100644
index 0000000000..42721899c8
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/test/integration/navigation_test.rb.tt
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class NagivationTest < ActiveSupport::IntegrationCase
+ test "truth" do
+ assert_kind_of Dummy::Application, Rails.application
+ end
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/test/support/integration_case.rb b/railties/lib/rails/generators/rails/plugin_new/templates/test/support/integration_case.rb
new file mode 100644
index 0000000000..4cfe3f0e71
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/test/support/integration_case.rb
@@ -0,0 +1,5 @@
+# Define a bare test case to use with Capybara
+class ActiveSupport::IntegrationCase < ActiveSupport::TestCase
+ include Capybara
+ include Rails.application.routes.url_helpers
+end \ No newline at end of file
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb b/railties/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb
new file mode 100644
index 0000000000..5c39780a23
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb
@@ -0,0 +1,22 @@
+# Configure Rails Envinronment
+ENV["RAILS_ENV"] = "test"
+
+require File.expand_path("../dummy/config/environment.rb", __FILE__)
+require "rails/test_help"
+
+ActionMailer::Base.delivery_method = :test
+ActionMailer::Base.perform_deliveries = true
+ActionMailer::Base.default_url_options[:host] = "test.com"
+
+Rails.backtrace_cleaner.remove_silencers!
+
+# Configure capybara for integration testing
+require "capybara/rails"
+Capybara.default_driver = :rack_test
+Capybara.default_selector = :css
+
+# Run any available migration
+ActiveRecord::Migrator.migrate File.expand_path("../dummy/db/migrate/", __FILE__)
+
+# Load support files
+Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f } \ No newline at end of file
diff --git a/railties/test/fixtures/lib/plugin_builders/empty_builder.rb b/railties/test/fixtures/lib/plugin_builders/empty_builder.rb
new file mode 100644
index 0000000000..5c5607621c
--- /dev/null
+++ b/railties/test/fixtures/lib/plugin_builders/empty_builder.rb
@@ -0,0 +1,2 @@
+class PluginBuilder
+end
diff --git a/railties/test/fixtures/lib/plugin_builders/simple_builder.rb b/railties/test/fixtures/lib/plugin_builders/simple_builder.rb
new file mode 100644
index 0000000000..08f6c5535d
--- /dev/null
+++ b/railties/test/fixtures/lib/plugin_builders/simple_builder.rb
@@ -0,0 +1,7 @@
+class PluginBuilder
+ def gitignore
+ create_file ".gitignore", <<-R.strip
+foobar
+ R
+ end
+end
diff --git a/railties/test/fixtures/lib/plugin_builders/tweak_builder.rb b/railties/test/fixtures/lib/plugin_builders/tweak_builder.rb
new file mode 100644
index 0000000000..1e801409a4
--- /dev/null
+++ b/railties/test/fixtures/lib/plugin_builders/tweak_builder.rb
@@ -0,0 +1,7 @@
+class PluginBuilder < Rails::PluginBuilder
+ def gitignore
+ create_file ".gitignore", <<-R.strip
+foobar
+ R
+ end
+end
diff --git a/railties/test/generators/plugin_new_generator_test.rb b/railties/test/generators/plugin_new_generator_test.rb
new file mode 100644
index 0000000000..3c38dffce2
--- /dev/null
+++ b/railties/test/generators/plugin_new_generator_test.rb
@@ -0,0 +1,179 @@
+require 'abstract_unit'
+require 'generators/generators_test_helper'
+require 'rails/generators/rails/plugin_new/plugin_new_generator'
+
+DEFAULT_PLUGIN_FILES = %w(
+ .gitignore
+ Gemfile
+ Rakefile
+ bukkits.gemspec
+ MIT-LICENSE
+ lib
+ lib/bukkits.rb
+ script/rails
+ test/bukkits_test.rb
+ test/integration/navigation_test.rb
+ test/support/integration_case.rb
+ test/test_helper.rb
+ test/dummy
+)
+
+
+class PluginNewGeneratorTest < Rails::Generators::TestCase
+ include GeneratorsTestHelper
+ destination File.join(Rails.root, "tmp/bukkits")
+ arguments [destination_root]
+
+ def setup
+ Rails.application = TestApp::Application
+ super
+ @bundle_command = File.basename(Thor::Util.ruby_command).sub(/ruby/, 'bundle')
+
+ Kernel::silence_warnings do
+ Thor::Base.shell.send(:attr_accessor, :always_force)
+ @shell = Thor::Base.shell.new
+ @shell.send(:always_force=, true)
+ end
+ end
+
+ def teardown
+ super
+ Rails.application = TestApp::Application.instance
+ end
+
+ def test_plugin_skeleton_is_created
+ run_generator
+
+ DEFAULT_PLUGIN_FILES.each{ |path| assert_file path }
+ end
+
+ def test_plugin_new_generate_pretend
+ run_generator ["testapp", "--pretend"]
+
+ DEFAULT_PLUGIN_FILES.each{ |path| assert_no_file path }
+ end
+
+ def test_options_before_plugin_name_raises_an_error
+ content = capture(:stderr){ run_generator(["--pretend", destination_root]) }
+ assert_equal "Options should be given after plugin name. For details run: rails plugin --help\n", content
+ end
+
+ def test_name_collision_raises_an_error
+ reserved_words = %w[application destroy plugin runner test]
+ reserved_words.each do |reserved|
+ content = capture(:stderr){ run_generator [File.join(destination_root, reserved)] }
+ assert_equal "Invalid plugin name #{reserved}. Please give a name which does not match one of the reserved rails words.\n", content
+ end
+ end
+
+ def test_invalid_plugin_name_raises_an_error
+ content = capture(:stderr){ run_generator [File.join(destination_root, "43-things")] }
+ assert_equal "Invalid plugin name 43-things. Please give a name which does not start with numbers.\n", content
+ end
+
+ def test_plugin_name_raises_an_error_if_name_already_used_constant
+ %w{ String Hash Class Module Set Symbol }.each do |ruby_class|
+ content = capture(:stderr){ run_generator [File.join(destination_root, ruby_class)] }
+ assert_equal "Invalid plugin name #{ruby_class}, constant #{ruby_class} is already in use. Please choose another application name.\n", content
+ end
+ end
+
+ def test_invalid_plugin_name_is_fixed
+ run_generator [File.join(destination_root, "things-43")]
+ assert_file "things-43/lib/things-43.rb", /module Things43/
+ end
+
+ def test_shebang_is_added_to_rails_file
+ run_generator [destination_root, "--ruby", "foo/bar/baz"]
+ assert_file "script/rails", /#!foo\/bar\/baz/
+ end
+
+ def test_shebang_when_is_the_same_as_default_use_env
+ run_generator [destination_root, "--ruby", Thor::Util.ruby_command]
+ assert_file "script/rails", /#!\/usr\/bin\/env/
+ end
+
+ def test_generating_test_files
+ run_generator
+ assert_file "test/test_helper.rb"
+ assert_directory "test/support/"
+ assert_directory "test/integration/"
+
+ assert_file "test/bukkits_test.rb", /assert_kind_of Module, Bukkits/
+ assert_file "test/integration/navigation_test.rb", /assert_kind_of Dummy::Application, Rails.application/
+ assert_file "test/support/integration_case.rb", /class ActiveSupport::IntegrationCase/
+ end
+
+protected
+
+ def action(*args, &block)
+ silence(:stdout){ generator.send(*args, &block) }
+ end
+
+end
+
+class CustomPluginGeneratorTest < Rails::Generators::TestCase
+ include GeneratorsTestHelper
+ tests Rails::Generators::PluginNewGenerator
+
+ destination File.join(Rails.root, "tmp/bukkits")
+ arguments [destination_root]
+
+ def setup
+ Rails.application = TestApp::Application
+ super
+ @bundle_command = File.basename(Thor::Util.ruby_command).sub(/ruby/, 'bundle')
+ end
+
+ def teardown
+ super
+ Object.class_eval { remove_const :PluginBuilder if const_defined?(:PluginBuilder) }
+ Rails.application = TestApp::Application.instance
+ end
+
+ def test_builder_option_with_empty_app_builder
+ FileUtils.cd(destination_root)
+ run_generator([destination_root, "-b", "#{Rails.root}/lib/plugin_builders/empty_builder.rb"])
+ DEFAULT_PLUGIN_FILES.each{ |path| assert_no_file path }
+ end
+
+ def test_builder_option_with_simple_plugin_builder
+ FileUtils.cd(destination_root)
+ run_generator([destination_root, "-b", "#{Rails.root}/lib/plugin_builders/simple_builder.rb"])
+ (DEFAULT_PLUGIN_FILES - ['.gitignore']).each{ |path| assert_no_file path }
+ assert_file ".gitignore", "foobar"
+ end
+
+ def test_builder_option_with_relative_path
+ here = File.expand_path(File.dirname(__FILE__))
+ FileUtils.cd(here)
+ run_generator([destination_root, "-b", "../fixtures/lib/plugin_builders/simple_builder.rb"])
+ FileUtils.cd(destination_root)
+ (DEFAULT_PLUGIN_FILES - ['.gitignore']).each{ |path| assert_no_file path }
+ assert_file ".gitignore", "foobar"
+ end
+
+ def test_builder_option_with_tweak_plugin_builder
+ FileUtils.cd(destination_root)
+ run_generator([destination_root, "-b", "#{Rails.root}/lib/plugin_builders/tweak_builder.rb"])
+ DEFAULT_PLUGIN_FILES.each{ |path| assert_file path }
+ assert_file ".gitignore", "foobar"
+ end
+
+ def test_builder_option_with_http
+ path = "http://gist.github.com/103208.txt"
+ template = "class PluginBuilder; end"
+ template.instance_eval "def read; self; end" # Make the string respond to read
+
+ generator([destination_root], :builder => path).expects(:open).with(path, 'Accept' => 'application/x-thor-template').returns(template)
+ capture(:stdout) { generator.invoke_all }
+
+ DEFAULT_PLUGIN_FILES.each{ |path| assert_no_file path }
+ end
+
+protected
+
+ def action(*args, &block)
+ silence(:stdout){ generator.send(*args, &block) }
+ end
+end