diff options
Diffstat (limited to 'railties')
61 files changed, 714 insertions, 697 deletions
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 5e68c05d7c..3fb4b723ab 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -8,7 +8,7 @@ module Rails class << self attr_writer :config alias configure class_eval - delegate :initialize!, :load_tasks, :to => :instance + delegate :initialize!, :load_tasks, :root, :to => :instance private :new def instance @@ -267,18 +267,5 @@ module Rails ActiveSupport::Dependencies.unhook! end end - - # For each framework, search for instrument file with Notifications hooks. - # - initializer :load_notifications_hooks do - frameworks = [ :active_record, :action_controller, :action_view, - :action_mailer, :active_resource ] - frameworks.each do |framework| - begin - require "#{framework}/notifications" - rescue LoadError => e - end - end - end end end diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb index 2ba56bc3c5..3713a38b33 100644 --- a/railties/lib/rails/generators.rb +++ b/railties/lib/rails/generators.rb @@ -10,7 +10,7 @@ require 'active_support/core_ext/module/attribute_accessors' require 'active_support/core_ext/string/inflections' # TODO: Do not always push on vendored thor -$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/vendor/thor-0.12.1/lib") +$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/vendor/thor-0.12.3/lib") require 'rails/generators/base' require 'rails/generators/named_base' @@ -117,11 +117,15 @@ module Rails end # Remove the color from output. - # def self.no_color! Thor::Base.shell = Thor::Shell::Basic end + # Track all generators subclasses. + def self.subclasses + @subclasses ||= [] + end + # Generators load paths used on lookup. The lookup happens as: # # 1) lib generators @@ -147,18 +151,10 @@ module Rails end load_paths # Cache load paths. Needed to avoid __FILE__ pointing to wrong paths. - # Rails finds namespaces exactly as thor, with three conveniences: - # - # 1) If your generator name ends with generator, as WebratGenerator, it sets - # its namespace to "webrat", so it can be invoked as "webrat" and not - # "webrat_generator"; + # Rails finds namespaces similar to thor, it only adds one rule: # - # 2) If your generator has a generators namespace, as Rails::Generators::WebratGenerator, - # the namespace is set to "rails:generators:webrat", but Rails allows it - # to be invoked simply as "rails:webrat". The "generators" is added - # automatically when doing the lookup; - # - # 3) Rails looks in load paths and loads the generator just before it's going to be used. + # Generators names must end with "_generator.rb". This is required because Rails + # looks in load paths and loads the generator just before it's going to be used. # # ==== Examples # @@ -166,113 +162,81 @@ module Rails # # Will search for the following generators: # - # "rails:generators:webrat", "webrat:generators:integration", "webrat" - # - # On the other hand, if "rails:webrat" is given, it will search for: + # "rails:webrat", "webrat:integration", "webrat" # - # "rails:generators:webrat", "rails:webrat" - # - # Notice that the "generators" namespace is handled automatically by Rails, - # so you don't need to type it when you want to invoke a generator in specific. + # Notice that "rails:generators:webrat" could be loaded as well, what + # Rails looks for is the first and last parts of the namespace. # def self.find_by_namespace(name, base=nil, context=nil) #:nodoc: - name, attempts = name.to_s, [ ] - - case name.count(':') - when 1 - base, name = name.split(':') - return find_by_namespace(name, base) - when 0 - attempts += generator_names(base, name) if base - attempts += generator_names(name, context) if context - end - - attempts << name - attempts += generator_names(name, name) unless name.include?(?:) - attempts.uniq! - - unloaded = attempts - namespaces - lookup(unloaded) + # Mount regexps to lookup + regexps = [] + regexps << /^#{base}:[\w:]*#{name}$/ if base + regexps << /^#{name}:[\w:]*#{context}$/ if context + regexps << /^[(#{name}):]+$/ + regexps.uniq! + + # Check if generator happens to be loaded + checked = subclasses.dup + klass = find_by_regexps(regexps, checked) + return klass if klass + + # Try to require other generators by looking in load_paths + lookup(name, context) + unchecked = subclasses - checked + klass = find_by_regexps(regexps, unchecked) + return klass if klass + + # Invoke fallbacks + invoke_fallbacks_for(name, base) || invoke_fallbacks_for(context, name) + end - attempts.each do |namespace| - klass = Thor::Util.find_by_namespace(namespace) - return klass if klass + # Tries to find a generator which the namespace match the regexp. + def self.find_by_regexps(regexps, klasses) + klasses.find do |klass| + namespace = klass.namespace + regexps.find { |r| namespace =~ r } end - - invoke_fallbacks_for(name, base) || invoke_fallbacks_for(context, name) end # Receives a namespace, arguments and the behavior to invoke the generator. # It's used as the default entry point for generate, destroy and update # commands. - # def self.invoke(namespace, args=ARGV, config={}) - if klass = find_by_namespace(namespace, "rails") + names = namespace.to_s.split(':') + + if klass = find_by_namespace(names.pop, names.shift || "rails") args << "--help" if klass.arguments.any? { |a| a.required? } && args.empty? - klass.start args, config + klass.start(args, config) else puts "Could not find generator #{namespace}." end end # Show help message with available generators. - # def self.help - rails = Rails::Generators.builtin.map do |group, name| - name if group == "rails" - end - rails.compact! - rails.sort! - - puts "Please select a generator." - puts "Builtin: #{rails.join(', ')}." - - # Load paths and remove builtin - paths, others = load_paths.dup, [] - paths.pop - - paths.each do |path| - tail = [ "*", "*", "*_generator.rb" ] - - until tail.empty? - others += Dir[File.join(path, *tail)].collect do |file| - name = file.split('/')[-tail.size, 2] - name.last.sub!(/_generator\.rb$/, '') - name.uniq! - name.join(':') - end - tail.shift - end - end + builtin = Rails::Generators.builtin.each { |n| n.sub!(/^rails:/, '') } + builtin.sort! + lookup("*") + others = subclasses.map{ |k| k.namespace.gsub(':generators:', ':') } + others -= Rails::Generators.builtin others.sort! + + puts "Please select a generator." + puts "Builtin: #{builtin.join(', ')}." puts "Others: #{others.join(', ')}." unless others.empty? end protected - # Return all defined namespaces. - # - def self.namespaces #:nodoc: - Thor::Base.subclasses.map { |klass| klass.namespace } - end - - # Keep builtin generators in an Array[Array[group, name]]. - # + # Keep builtin generators in an Array. def self.builtin #:nodoc: Dir[File.dirname(__FILE__) + '/generators/*/*'].collect do |file| - file.split('/')[-2, 2] + file.split('/')[-2, 2].join(':') end end - # By default, Rails strips the generator namespace to make invocations - # easier. This method generaters the both possibilities names. - def self.generator_names(first, second) #:nodoc: - [ "#{first}:generators:#{second}", "#{first}:#{second}" ] - end - - # Try callbacks for the given base. - # + # Try fallbacks for the given base. def self.invoke_fallbacks_for(name, base) #:nodoc: return nil unless base && fallbacks[base.to_sym] invoked_fallbacks = [] @@ -290,10 +254,10 @@ module Rails # Receives namespaces in an array and tries to find matching generators # in the load path. - # - def self.lookup(attempts) #:nodoc: - attempts = attempts.map { |a| "#{a.split(":").last}_generator" }.uniq - attempts = "{#{attempts.join(',')}}.rb" + def self.lookup(*attempts) #:nodoc: + attempts.compact! + attempts.uniq! + attempts = "{#{attempts.join(',')}}_generator.rb" self.load_paths.each do |path| Dir[File.join(path, '**', attempts)].each do |file| diff --git a/railties/lib/rails/generators/base.rb b/railties/lib/rails/generators/base.rb index 226ae63963..5e8c2730fd 100644 --- a/railties/lib/rails/generators/base.rb +++ b/railties/lib/rails/generators/base.rb @@ -76,17 +76,18 @@ module Rails # # The controller generator will then try to invoke the following generators: # - # "rails:generators:test_unit", "test_unit:generators:controller", "test_unit" + # "rails:test_unit", "test_unit:controller", "test_unit" # - # In this case, the "test_unit:generators:controller" is available and is - # invoked. This allows any test framework to hook into Rails as long as it - # provides any of the hooks above. + # Notice that "rails:generators:test_unit" could be loaded as well, what + # Rails looks for is the first and last parts of the namespace. This is what + # allows any test framework to hook into Rails as long as it provides any + # of the hooks above. # # ==== Options # - # This lookup can be customized with two options: :base and :as. The first - # is the root module value and in the example above defaults to "rails". - # The later defaults to the generator name, without the "Generator" ending. + # The first and last part used to find the generator to be invoked are + # guessed based on class invokes hook_for, as noticed in the example above. + # This can be customized with two options: :base and :as. # # Let's suppose you are creating a generator that needs to invoke the # controller generator from test unit. Your first attempt is: @@ -97,7 +98,7 @@ module Rails # # The lookup in this case for test_unit as input is: # - # "test_unit:generators:awesome", "test_unit" + # "test_unit:awesome", "test_unit" # # Which is not the desired the lookup. You can change it by providing the # :as option: @@ -108,18 +109,18 @@ module Rails # # And now it will lookup at: # - # "test_unit:generators:awesome", "test_unit" + # "test_unit:controller", "test_unit" # # Similarly, if you want it to also lookup in the rails namespace, you just # need to provide the :base value: # # class AwesomeGenerator < Rails::Generators::Base - # hook_for :test_framework, :base => :rails, :as => :controller + # hook_for :test_framework, :in => :rails, :as => :controller # end # # And the lookup is exactly the same as previously: # - # "rails:generators:test_unit", "test_unit:generators:controller", "test_unit" + # "rails:test_unit", "test_unit:controller", "test_unit" # # ==== Switches # @@ -151,11 +152,11 @@ module Rails # ==== Custom invocations # # You can also supply a block to hook_for to customize how the hook is - # going to be invoked. The block receives two parameters, an instance + # going to be invoked. The block receives two arguments, an instance # of the current class and the klass to be invoked. # # For example, in the resource generator, the controller should be invoked - # with a pluralized class name. By default, it is invoked with the same + # with a pluralized class name. But by default it is invoked with the same # name as the resource generator, which is singular. To change this, we # can give a block to customize how the controller can be invoked. # @@ -178,11 +179,11 @@ module Rails end unless class_options.key?(name) - class_option name, defaults.merge!(options) + class_option(name, defaults.merge!(options)) end hooks[name] = [ in_base, as_hook ] - invoke_from_option name, options, &block + invoke_from_option(name, options, &block) end end @@ -193,7 +194,7 @@ module Rails # remove_hook_for :orm # def self.remove_hook_for(*names) - remove_invocation *names + remove_invocation(*names) names.each do |name| hooks.delete(name) @@ -219,12 +220,16 @@ module Rails # and can point to wrong directions when inside an specified directory. base.source_root - if base.name && base.name !~ /Base$/ && base.base_name && base.generator_name && defined?(Rails.root) && Rails.root - path = File.expand_path(File.join(Rails.root, 'lib', 'templates')) - if base.name.include?('::') - base.source_paths << File.join(path, base.base_name, base.generator_name) - else - base.source_paths << File.join(path, base.generator_name) + if base.name && base.name !~ /Base$/ + Rails::Generators.subclasses << base + + if defined?(Rails.root) && Rails.root + path = File.expand_path(File.join(Rails.root, 'lib', 'templates')) + if base.name.include?('::') + base.source_paths << File.join(path, base.base_name, base.generator_name) + else + base.source_paths << File.join(path, base.generator_name) + end end end end @@ -267,7 +272,7 @@ module Rails # parameters. # def invoked?(args) - args.last.is_a?(Hash) && args.last.key?(:invocations) + args.last.is_a?(Hash) && (args.last.key?(:invocations) || args.last.key?(:destination_root)) end # Use Rails default banner. @@ -290,12 +295,10 @@ module Rails # Rails::Generators::MetalGenerator will return "metal" as generator name. # def self.generator_name - if name - @generator_name ||= begin - if klass_name = name.to_s.split('::').last - klass_name.sub!(/Generator$/, '') - klass_name.underscore - end + @generator_name ||= begin + if generator = name.to_s.split('::').last + generator.sub!(/Generator$/, '') + generator.underscore end end end @@ -339,6 +342,7 @@ module Rails # def self.prepare_for_invocation(name, value) #:nodoc: if value && constants = self.hooks[name] + value = name if TrueClass === value Rails::Generators.find_by_namespace(value, *constants) else super diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb index ee401b1fde..fc6a3cdee8 100644 --- a/railties/lib/rails/generators/rails/app/app_generator.rb +++ b/railties/lib/rails/generators/rails/app/app_generator.rb @@ -46,15 +46,16 @@ module Rails::Generators def initialize(*args) super - if !options[:no_activerecord] && !DATABASES.include?(options[:database]) + if !options[:skip_activerecord] && !DATABASES.include?(options[:database]) raise Error, "Invalid value for --database option. Supported for preconfiguration are: #{DATABASES.join(", ")}." end end def create_root self.destination_root = File.expand_path(app_path, destination_root) - empty_directory '.' + valid_app_const? + empty_directory '.' set_default_accessors! FileUtils.cd(destination_root) end @@ -193,7 +194,14 @@ module Rails::Generators end def app_const - @app_const ||= "#{app_name.classify}::Application" + @app_const ||= "#{app_name.gsub(/\W/, '_').squeeze('_').classify}::Application" + end + + def valid_app_const? + case app_const + when /^\d/ + raise Error, "Invalid application name #{app_name}. Please give a name which does not start with numbers." + end end def app_secret diff --git a/railties/lib/rails/generators/rails/app/templates/config/application.rb b/railties/lib/rails/generators/rails/app/templates/config/application.rb index b6c1cef8cd..dce5b55d86 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/application.rb +++ b/railties/lib/rails/generators/rails/app/templates/config/application.rb @@ -7,7 +7,7 @@ module <%= app_name.classify %> # -- all .rb files in that directory are automatically loaded. # Add additional load paths for your own custom dirs - # config.load_paths += %W( #{root}/extras ) + # config.load_paths += %W( #{config.root}/extras ) # Only load the plugins named here, in the order given (default is alphabetical). # :all can be used as a placeholder for all plugins not explicitly named diff --git a/railties/lib/rails/generators/test_case.rb b/railties/lib/rails/generators/test_case.rb new file mode 100644 index 0000000000..643d7856c5 --- /dev/null +++ b/railties/lib/rails/generators/test_case.rb @@ -0,0 +1,239 @@ +require 'active_support/test_case' +require 'active_support/core_ext/class/inheritable_attributes' +require 'active_support/core_ext/hash/reverse_merge' +require 'rails/generators' +require 'fileutils' + +module Rails + module Generators + # Disable color in output. Easier to debug. + no_color! + + # This class provides a TestCase for testing generators. To setup, you need + # just to configure the destination and set which generator is being tested: + # + # class AppGeneratorTest < Rails::Generators::TestCase + # tests AppGenerator + # destination File.expand_path("../tmp", File.dirname(__FILE__)) + # end + # + # If you want to ensure your destination root is clean before running each test, + # you can set a setup callback: + # + # class AppGeneratorTest < Rails::Generators::TestCase + # tests AppGenerator + # destination File.expand_path("../tmp", File.dirname(__FILE__)) + # setup :prepare_destination + # end + # + class TestCase < ActiveSupport::TestCase + include FileUtils + + extlib_inheritable_accessor :destination_root, :current_path, :generator_class, + :default_arguments, :instance_writer => false + + # Generators frequently change the current path using +FileUtils.cd+. + # So we need to store the path at file load and revert back to it after each test. + self.current_path = File.expand_path(Dir.pwd) + self.default_arguments = [] + + setup :destination_root_is_set?, :ensure_current_path + teardown :ensure_current_path + + # Sets which generator should be tested: + # + # tests AppGenerator + # + def self.tests(klass) + self.generator_class = klass + end + + # Sets default arguments on generator invocation. This can be overwritten when + # invoking it. + # + # arguments %w(app_name --skip-activerecord) + # + def self.arguments(array) + self.default_arguments = array + end + + # Sets the destination of generator files: + # + # destination File.expand_path("../tmp", File.dirname(__FILE__)) + # + def self.destination(path) + self.destination_root = path + end + + # Captures the given stream and returns it: + # + # stream = capture(:stdout){ puts "Cool" } + # stream #=> "Cool\n" + # + def capture(stream) + begin + stream = stream.to_s + eval "$#{stream} = StringIO.new" + yield + result = eval("$#{stream}").string + ensure + eval("$#{stream} = #{stream.upcase}") + end + + result + end + alias :silence :capture + + # Asserts a given file exists. You need to supply an absolute path or a path relative + # to the configured destination: + # + # assert_file "config/environment.rb" + # + # You can also give extra arguments. If the argument is a regexp, it will check if the + # regular expression matches the given file content. If it's a string, it compares the + # file with the given string: + # + # assert_file "config/environment.rb", /initialize/ + # + # Finally, when a block is given, it yields the file content: + # + # assert_file "app/controller/products_controller.rb" do |controller| + # assert_instance_method :index, content do |index| + # assert_match /Product\.all/, index + # end + # end + # + def assert_file(relative, *contents) + absolute = File.expand_path(relative, destination_root) + assert File.exists?(absolute), "Expected file #{relative.inspect} to exist, but does not" + + read = File.read(absolute) if block_given? || !contents.empty? + yield read if block_given? + + contents.each do |content| + case content + when String + assert_equal content, read + when Regexp + assert_match content, read + end + end + end + alias :assert_directory :assert_file + + # Asserts a given file does not exist. You need to supply an absolute path or a + # path relative to the configured destination: + # + # assert_no_file "config/random.rb" + # + def assert_no_file(relative) + absolute = File.expand_path(relative, destination_root) + assert !File.exists?(absolute), "Expected file #{relative.inspect} to not exist, but does" + end + alias :assert_no_directory :assert_no_file + + # Asserts a given file does not exist. You need to supply an absolute path or a + # path relative to the configured destination: + # + # assert_migration "db/migrate/create_products.rb" + # + # This method manipulates the given path and tries to find any migration which + # matches the migration name. For example, the call above is converted to: + # + # assert_file "db/migrate/003_create_products.rb" + # + # Consequently, assert_migration accepts the same arguments has assert_file. + # + def assert_migration(relative, *contents, &block) + file_name = migration_file_name(relative) + assert file_name, "Expected migration #{relative} to exist, but was not found" + assert_file file_name, *contents, &block + end + + # Asserts a given migration does not exist. You need to supply an absolute path or a + # path relative to the configured destination: + # + # assert_no_file "config/random.rb" + # + def assert_no_migration(relative) + file_name = migration_file_name(relative) + assert_nil file_name, "Expected migration #{relative} to not exist, but found #{file_name}" + end + + # Asserts the given class method exists in the given content. This method does not detect + # class methods inside (class << self), only class methods which starts with "self.". + # When a block is given, it yields the content of the method. + # + # assert_migration "db/migrate/create_products.rb" do |migration| + # assert_class_method :up, migration do |up| + # assert_match /create_table/, up + # end + # end + # + def assert_class_method(method, content, &block) + assert_instance_method "self.#{method}", content, &block + end + + # Asserts the given method exists in the given content. When a block is given, + # it yields the content of the method. + # + # assert_file "app/controller/products_controller.rb" do |controller| + # assert_instance_method :index, content do |index| + # assert_match /Product\.all/, index + # end + # end + # + def assert_instance_method(method, content) + assert content =~ /def #{method}(\(.+\))?(.*?)\n end/m, "Expected to have method #{method}" + yield $2.strip if block_given? + end + alias :assert_method :assert_instance_method + + # Runs the generator configured for this class. The first argument is an array like + # command line arguments: + # + # class AppGeneratorTest < Rails::Generators::TestCase + # tests AppGenerator + # destination File.expand_path("../tmp", File.dirname(__FILE__)) + # teardown :cleanup_destination_root + # + # test "database.yml is not created when skipping activerecord" do + # run_generator %w(myapp --skip-activerecord) + # assert_no_file "config/database.yml" + # end + # end + # + # You can provide a configuration hash as second argument. This method returns the output + # printed by the generator. + def run_generator(args=self.default_arguments, config={}) + capture(:stdout) { self.generator_class.start(args, config.reverse_merge(:destination_root => destination_root)) } + end + + # Instantiate the generator. + def generator(args=self.default_arguments, options={}, config={}) + @generator ||= self.generator_class.new(args, options, config.reverse_merge(:destination_root => destination_root)) + end + + protected + + def destination_root_is_set? #:nodoc: + raise "You need to configure your Rails::Generators::TestCase destination root." unless destination_root + end + + def ensure_current_path #:nodoc: + cd current_path + end + + def prepare_destination + rm_rf(destination_root) + mkdir_p(destination_root) + end + + def migration_file_name(relative) #:nodoc: + absolute = File.expand_path(relative, destination_root) + dirname, file_name = File.dirname(absolute), File.basename(absolute).sub(/\.rb$/, '') + Dir.glob("#{dirname}/[0-9]*_*.rb").grep(/\d+_#{file_name}.rb$/).first + end + end + end +end
\ No newline at end of file diff --git a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb index e4bf4035da..9380aa49b6 100644 --- a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb +++ b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb @@ -16,7 +16,7 @@ class <%= controller_class_name %>ControllerTest < ActionController::TestCase test "should create <%= file_name %>" do assert_difference('<%= class_name %>.count') do - post :create, :<%= file_name %> => { } + post :create, :<%= file_name %> => <%= table_name %>(:one).attributes end assert_redirected_to <%= file_name %>_path(assigns(:<%= file_name %>)) @@ -33,7 +33,7 @@ class <%= controller_class_name %>ControllerTest < ActionController::TestCase end test "should update <%= file_name %>" do - put :update, :id => <%= table_name %>(:one).to_param, :<%= file_name %> => { } + put :update, :id => <%= table_name %>(:one).to_param, :<%= file_name %> => <%= table_name %>(:one).attributes assert_redirected_to <%= file_name %>_path(assigns(:<%= file_name %>)) end diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/version.rb b/railties/lib/rails/vendor/thor-0.12.1/lib/thor/version.rb deleted file mode 100644 index 650253d648..0000000000 --- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/version.rb +++ /dev/null @@ -1,3 +0,0 @@ -class Thor - VERSION = "0.12.1".freeze -end diff --git a/railties/lib/rails/vendor/thor-0.12.1/CHANGELOG.rdoc b/railties/lib/rails/vendor/thor-0.12.3/CHANGELOG.rdoc index 606a0cdb52..d02fc43e84 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/CHANGELOG.rdoc +++ b/railties/lib/rails/vendor/thor-0.12.3/CHANGELOG.rdoc @@ -1,9 +1,7 @@ -== TODO - -* Improve spec coverage for Thor::Runner - -== 0.12, released 2009-11-06 +== 0.12, released 2010-01-02 +* Removed rr in favor to rspec mock framework +* Improved output for thor -T * [#7] Do not force white color on status * [#8] Yield a block with the filename on directory @@ -17,7 +15,7 @@ * thor help now show information about any class/task. All those calls are possible: - + thor help describe thor help describe:amazing @@ -47,7 +45,7 @@ are in the 'standard' group. Running 'thor -T' will only show the standard tasks - adding --all will show all tasks. You can also filter on a specific group using the --group option: thor -T --group advanced - + == 0.9.6, released 2008-09-13 * Generic improvements diff --git a/railties/lib/rails/vendor/thor-0.12.1/LICENSE b/railties/lib/rails/vendor/thor-0.12.3/LICENSE index 98722da459..98722da459 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/LICENSE +++ b/railties/lib/rails/vendor/thor-0.12.3/LICENSE diff --git a/railties/lib/rails/vendor/thor-0.12.1/README.rdoc b/railties/lib/rails/vendor/thor-0.12.3/README.rdoc index ee545f3d97..ee545f3d97 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/README.rdoc +++ b/railties/lib/rails/vendor/thor-0.12.3/README.rdoc diff --git a/railties/lib/rails/vendor/thor-0.12.1/Thorfile b/railties/lib/rails/vendor/thor-0.12.3/Thorfile index ff1cb4498a..ff1cb4498a 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/Thorfile +++ b/railties/lib/rails/vendor/thor-0.12.3/Thorfile diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor.rb index 68944f140d..d4d8fbd64d 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor.rb +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor.rb @@ -78,14 +78,14 @@ class Thor @method_options end - # Adds an option to the set of class options. If :for is given as option, + # Adds an option to the set of method options. If :for is given as option, # it allows you to change the options from a previous defined task. # # def previous_task # # magic # end # - # method_options :foo => :bar, :for => :previous_task + # method_option :foo => :bar, :for => :previous_task # # def next_task # # magic @@ -101,7 +101,6 @@ class Thor # :default - Default value for this argument. It cannot be required and have default values. # :aliases - Aliases for this option. # :type - The type of the argument, can be :string, :hash, :array, :numeric or :boolean. - # :group - The group for this options. Use by class options to output options in different levels. # :banner - String to show on usage notes. # def method_option(name, options={}) @@ -140,49 +139,48 @@ class Thor end end - # Prints help information. If a task name is given, it shows information - # only about the specific task. + # Prints help information for the given task. # # ==== Parameters - # meth<String>:: An optional task name to print usage information about. + # shell<Thor::Shell> + # task_name<String> + # + def task_help(shell, task_name) + task = all_tasks[task_name] + raise UndefinedTaskError, "task '#{task_name}' could not be found in namespace '#{self.namespace}'" unless task + + shell.say "Usage:" + shell.say " #{banner(task)}" + shell.say + class_options_help(shell, nil => task.options.map { |_, o| o }) + shell.say task.description + end + + # Prints help information for this class. # - # ==== Options - # namespace:: When true, shows the namespace in the output before the usage. - # skip_inherited:: When true, does not show tasks from superclass. + # ==== Parameters + # shell<Thor::Shell> # - def help(shell, meth=nil, options={}) - meth, options = nil, meth if meth.is_a?(Hash) - - if meth - task = all_tasks[meth] - raise UndefinedTaskError, "task '#{meth}' could not be found in namespace '#{self.namespace}'" unless task - - shell.say "Usage:" - shell.say " #{banner(task, options[:namespace], false)}" - shell.say - class_options_help(shell, "Class", :Method => task.options.map { |_, o| o }) - shell.say task.description - else - list = (options[:short] ? tasks : all_tasks).map do |_, task| - item = [ banner(task, options[:namespace]) ] - item << "# #{task.short_description}" if task.short_description - item << " " - end - - options[:ident] ||= 2 - if options[:short] - shell.print_list(list, :ident => options[:ident]) - else - shell.say "Tasks:" - shell.print_list(list, :ident => options[:ident]) - end + def help(shell) + list = printable_tasks + Thor::Util.thor_classes_in(self).each do |klass| + list += klass.printable_tasks(false) + end + list.sort!{ |a,b| a[0] <=> b[0] } - Thor::Util.thor_classes_in(self).each do |subclass| - namespace = options[:namespace] == true || subclass.namespace.gsub(/^#{self.namespace}:/, '') - subclass.help(shell, options.merge(:short => true, :namespace => namespace)) - end + shell.say "Tasks:" + shell.print_table(list, :ident => 2, :truncate => true) + shell.say + class_options_help(shell) + end - class_options_help(shell, "Class") unless options[:short] + # Returns tasks ready to be printed. + def printable_tasks(all=true) + (all ? all_tasks : tasks).map do |_, task| + item = [] + item << banner(task) + item << (task.description ? "# #{task.description.gsub(/\s+/m,' ')}" : "") + item end end @@ -193,8 +191,8 @@ class Thor # the task that is going to be invoked and a boolean which indicates if # the namespace should be displayed as arguments. # - def banner(task, namespace=true, show_options=true) - task.formatted_usage(self, namespace, show_options) + def banner(task) + "thor " + task.formatted_usage(self) end def baseclass #:nodoc: @@ -237,6 +235,6 @@ class Thor desc "help [TASK]", "Describe available tasks or one specific task" def help(task=nil) - self.class.help(shell, task, :namespace => task && task.include?(?:)) + task ? self.class.task_help(shell, task) : self.class.help(shell) end end diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions.rb index 4bfb7c2870..da98444bf2 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions.rb +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions.rb @@ -1,4 +1,5 @@ require 'fileutils' +require 'thor/core_ext/file_binary_read' Dir[File.join(File.dirname(__FILE__), "actions", "*.rb")].each do |action| require action @@ -38,17 +39,17 @@ class Thor # Add runtime options that help actions execution. # def add_runtime_options! - class_option :pretend, :type => :boolean, :aliases => "-p", :group => :runtime, - :desc => "Run but do not make any changes" - class_option :force, :type => :boolean, :aliases => "-f", :group => :runtime, :desc => "Overwrite files that already exist" - class_option :skip, :type => :boolean, :aliases => "-s", :group => :runtime, - :desc => "Skip files that already exist" + class_option :pretend, :type => :boolean, :aliases => "-p", :group => :runtime, + :desc => "Run but do not make any changes" class_option :quiet, :type => :boolean, :aliases => "-q", :group => :runtime, :desc => "Supress status output" + + class_option :skip, :type => :boolean, :aliases => "-s", :group => :runtime, + :desc => "Skip files that already exist" end end @@ -114,7 +115,7 @@ class Thor @source_paths ||= self.class.source_paths_for_search end - # Receives a file or directory and search for it in the source paths. + # Receives a file or directory and search for it in the source paths. # def find_in_source_paths(file) relative_root = relative_to_original_destination_root(destination_root, false) @@ -222,7 +223,7 @@ class Thor run "#{command}", config.merge(:with => Thor::Util.ruby_command) end - # Run a thor command. A hash of options can be given and it's converted to + # Run a thor command. A hash of options can be given and it's converted to # switches. # # ==== Parameters diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions/create_file.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions/create_file.rb index a3d9296823..6e0eeb43e2 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions/create_file.rb +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions/create_file.rb @@ -42,7 +42,7 @@ class Thor # Boolean:: true if it is identical, false otherwise. # def identical? - exists? && File.read(destination) == render + exists? && File.binread(destination) == render end # Holds the content to be added to the file. @@ -58,7 +58,7 @@ class Thor def invoke! invoke_with_conflict_check do FileUtils.mkdir_p(File.dirname(destination)) - File.open(destination, 'w'){ |f| f.write render } + File.open(destination, 'wb') { |f| f.write render } end given_destination end diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions/directory.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions/directory.rb index 2e0b459fa3..2e0b459fa3 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions/directory.rb +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions/directory.rb diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions/empty_directory.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions/empty_directory.rb index 484cb820f8..484cb820f8 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions/empty_directory.rb +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions/empty_directory.rb diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions/file_manipulation.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions/file_manipulation.rb index 8a45c83f25..44d6836c10 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions/file_manipulation.rb +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions/file_manipulation.rb @@ -23,7 +23,7 @@ class Thor source = File.expand_path(find_in_source_paths(source.to_s)) create_file destination, nil, config do - content = File.read(source) + content = File.binread(source) content = block.call(content) if block content end @@ -48,7 +48,7 @@ class Thor # def get(source, destination=nil, config={}, &block) source = File.expand_path(find_in_source_paths(source.to_s)) unless source =~ /^http\:\/\// - render = open(source).read + render = File.binread(source) destination ||= if block_given? block.arity == 1 ? block.call(render) : block.call @@ -80,7 +80,7 @@ class Thor context = instance_eval('binding') create_file destination, nil, config do - content = ERB.new(::File.read(source), nil, '-').result(context) + content = ERB.new(::File.binread(source), nil, '-').result(context) content = block.call(content) if block content end @@ -193,7 +193,7 @@ class Thor say_status :gsub, relative_to_original_destination_root(path), config.fetch(:verbose, true) unless options[:pretend] - content = File.read(path) + content = File.binread(path) content.gsub!(flag, *args, &block) File.open(path, 'wb') { |file| file.write(content) } end diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions/inject_into_file.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions/inject_into_file.rb index 6b0b42ea02..350ab73862 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/actions/inject_into_file.rb +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/actions/inject_into_file.rb @@ -11,7 +11,7 @@ class Thor # data<String>:: Data to add to the file. Can be given as a block. # config<Hash>:: give :verbose => false to not log the status and the flag # for injection (:after or :before). - # + # # ==== Examples # # inject_into_file "config/environment.rb", "config.gem :thor", :after => "Rails::Initializer.run do |config|\n" @@ -90,7 +90,7 @@ class Thor # def replace!(regexp, string) unless base.options[:pretend] - content = File.read(destination) + content = File.binread(destination) content.gsub!(regexp, string) File.open(destination, 'wb') { |file| file.write(content) } end diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/base.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/base.rb index 700d794123..aae4cdb89c 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/base.rb +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/base.rb @@ -92,6 +92,8 @@ class Thor end module ClassMethods + attr_accessor :debugging + # Adds an argument to the class and creates an attr_accessor for it. # # Arguments are different from options in several aspects. The first one @@ -347,10 +349,11 @@ class Thor # Default way to start generators from the command line. # def start(given_args=ARGV, config={}) + self.debugging = given_args.include?("--debug") config[:shell] ||= Thor::Base.shell.new yield rescue Thor::Error => e - if given_args.include?("--debug") + if debugging raise e else config[:shell].error e.message @@ -361,48 +364,43 @@ class Thor protected # Prints the class options per group. If an option does not belong to - # any group, it uses the ungrouped name value. This method provide to - # hooks to add extra options, one of them if the third argument called - # extra_group that should be a hash in the format :group => Array[Options]. - # - # The second is by returning a lambda used to print values. The lambda - # requires two options: the group name and the array of options. + # any group, it's printed as Class option. # - def class_options_help(shell, ungrouped_name=nil, extra_group=nil) #:nodoc: - groups = {} - + def class_options_help(shell, groups={}) #:nodoc: + # Group options by group class_options.each do |_, value| groups[value.group] ||= [] groups[value.group] << value end - printer = proc do |group_name, options| - list = [] - padding = options.collect{ |o| o.aliases.size }.max.to_i * 4 + # Deal with default group + global_options = groups.delete(nil) || [] + print_options(shell, global_options) + + # Print all others + groups.each do |group_name, options| + print_options(shell, options, group_name) + end + end + + # Receives a set of options and print them. + def print_options(shell, options, group_name=nil) + return if options.empty? - options.each do |option| - item = [ option.usage(padding) ] - item.push(option.description ? "# #{option.description}" : "") + list = [] + padding = options.collect{ |o| o.aliases.size }.max.to_i * 4 - list << item - list << [ "", "# Default: #{option.default}" ] if option.show_default? - end + options.each do |option| + item = [ option.usage(padding) ] + item.push(option.description ? "# #{option.description}" : "") - unless list.empty? - shell.say(group_name ? "#{group_name} options:" : "Options:") - shell.print_table(list, :ident => 2) - shell.say "" - end + list << item + list << [ "", "# Default: #{option.default}" ] if option.show_default? end - # Deal with default group - global_options = groups.delete(nil) || [] - printer.call(ungrouped_name, global_options) if global_options - - # Print all others - groups = extra_group.merge(groups) if extra_group - groups.each(&printer) - printer + shell.say(group_name ? "#{group_name} options:" : "Options:") + shell.print_table(list, :ident => 2) + shell.say "" end # Raises an error if the word given is a Thor reserved word. diff --git a/railties/lib/rails/vendor/thor-0.12.3/lib/thor/core_ext/file_binary_read.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/core_ext/file_binary_read.rb new file mode 100644 index 0000000000..d6af7e44b0 --- /dev/null +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/core_ext/file_binary_read.rb @@ -0,0 +1,9 @@ +class File #:nodoc: + + unless File.respond_to?(:binread) + def self.binread(file) + File.open(file, 'rb') { |f| f.read } + end + end + +end diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/core_ext/hash_with_indifferent_access.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/core_ext/hash_with_indifferent_access.rb index 40d201d9e4..78bc5cf4bf 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/core_ext/hash_with_indifferent_access.rb +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/core_ext/hash_with_indifferent_access.rb @@ -65,7 +65,7 @@ class Thor else self[$1] == args.first end - else + else self[method] end end diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/core_ext/ordered_hash.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/core_ext/ordered_hash.rb index 27fea5bb35..27fea5bb35 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/core_ext/ordered_hash.rb +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/core_ext/ordered_hash.rb diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/error.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/error.rb index f9b31a35d1..f9b31a35d1 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/error.rb +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/error.rb diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/group.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/group.rb index 021a067a3e..a585b37b73 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/group.rb +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/group.rb @@ -41,16 +41,12 @@ class Thor::Group # ==== Options # short:: When true, shows only usage. # - def help(shell, options={}) - if options[:short] - shell.say banner - else - shell.say "Usage:" - shell.say " #{banner}" - shell.say - class_options_help(shell) - shell.say self.desc if self.desc - end + def help(shell) + shell.say "Usage:" + shell.say " #{banner}\n" + shell.say + class_options_help(shell) + shell.say self.desc if self.desc end # Stores invocations for this class merging with superclass values. @@ -132,7 +128,7 @@ class Thor::Group names.each do |name| unless class_options.key?(name) - raise ArgumentError, "You have to define the option #{name.inspect} " << + raise ArgumentError, "You have to define the option #{name.inspect} " << "before setting invoke_from_option." end @@ -177,15 +173,11 @@ class Thor::Group # Overwrite class options help to allow invoked generators options to be # shown recursively when invoking a generator. # - def class_options_help(shell, ungrouped_name=nil, extra_group=nil) #:nodoc: - group_options = {} - - get_options_from_invocations(group_options, class_options) do |klass| - klass.send(:get_options_from_invocations, group_options, class_options) + def class_options_help(shell, groups={}) #:nodoc: + get_options_from_invocations(groups, class_options) do |klass| + klass.send(:get_options_from_invocations, groups, class_options) end - - group_options.merge!(extra_group) if extra_group - super(shell, ungrouped_name, group_options) + super(shell, groups) end # Get invocations array and merge options from invocations. Those @@ -218,13 +210,26 @@ class Thor::Group end end + # Returns tasks ready to be printed. + def printable_tasks(*) + item = [] + item << banner + item << (desc ? "# #{desc.gsub(/\s+/m,' ')}" : "") + [item] + end + protected # The banner for this class. You can customize it if you are invoking the # thor class by another ways which is not the Thor::Runner. # def banner - "#{self.namespace} #{self.arguments.map {|a| a.usage }.join(' ')}" + "thor #{self_task.formatted_usage(self, false)}" + end + + # Represents the whole class as a task. + def self_task #:nodoc: + Thor::Task::Dynamic.new(self.namespace, class_options) end def baseclass #:nodoc: @@ -243,7 +248,6 @@ class Thor::Group # Shortcut to invoke with padding and block handling. Use internally by # invoke and invoke_from_option class methods. - # def _invoke_for_class_method(klass, task=nil, *args, &block) #:nodoc: shell.padding += 1 diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/invocation.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/invocation.rb index 32e6a72454..32e6a72454 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/invocation.rb +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/invocation.rb diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/parser.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/parser.rb index 57a3f6e1a5..57a3f6e1a5 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/parser.rb +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/parser.rb diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/parser/argument.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/parser/argument.rb index aa8ace4719..aa8ace4719 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/parser/argument.rb +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/parser/argument.rb diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/parser/arguments.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/parser/arguments.rb index fb5d965e06..fb5d965e06 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/parser/arguments.rb +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/parser/arguments.rb diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/parser/option.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/parser/option.rb index e09b4901e2..9e40ec73fa 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/parser/option.rb +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/parser/option.rb @@ -36,7 +36,7 @@ class Thor # string (--foo=value) or booleans (just --foo). # # By default all options are optional, unless :required is given. - # + # def self.parse(key, value) if key.is_a?(Array) name, *aliases = key diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/parser/options.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/parser/options.rb index 75092308b5..75092308b5 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/parser/options.rb +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/parser/options.rb diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/rake_compat.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/rake_compat.rb index 0d0757fdda..0d0757fdda 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/rake_compat.rb +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/rake_compat.rb diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/runner.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/runner.rb index 079f9e0c65..f197081e3f 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/runner.rb +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/runner.rb @@ -36,7 +36,7 @@ class Thor::Runner < Thor #:nodoc: def install(name) initialize_thorfiles - # If a directory name is provided as the argument, look for a 'main.thor' + # If a directory name is provided as the argument, look for a 'main.thor' # task in said directory. begin if File.directory?(File.expand_path(name)) @@ -124,11 +124,7 @@ class Thor::Runner < Thor #:nodoc: method_options :internal => :boolean def installed initialize_thorfiles(nil, true) - - klasses = Thor::Base.subclasses - klasses -= [Thor, Thor::Runner] unless options["internal"] - - display_klasses(true, klasses) + display_klasses(true, options["internal"]) end desc "list [SEARCH]", "List the available thor tasks (--substring means .*SEARCH)" @@ -144,11 +140,15 @@ class Thor::Runner < Thor #:nodoc: (options[:all] || k.group == group) && k.namespace =~ search end - display_klasses(false, klasses) + display_klasses(false, false, klasses) end private + def self.banner(task) + "thor " + task.formatted_usage(self, false) + end + def thor_root Thor::Util.thor_root end @@ -156,7 +156,7 @@ class Thor::Runner < Thor #:nodoc: def thor_yaml @thor_yaml ||= begin yaml_file = File.join(thor_root, "thor.yml") - yaml = YAML.load_file(yaml_file) if File.exists?(yaml_file) + yaml = YAML.load_file(yaml_file) if File.exists?(yaml_file) yaml || {} end end @@ -215,9 +215,6 @@ class Thor::Runner < Thor #:nodoc: # 5. c:\ <-- no Thorfiles found! # def thorfiles(relevant_to=nil, skip_lookup=false) - # TODO Remove this dealing with deprecated thor when :namespaces: is available as constants - save_yaml(thor_yaml) if Thor::Util.convert_constants_to_namespaces(thor_yaml) - thorfiles = [] unless skip_lookup @@ -253,47 +250,54 @@ class Thor::Runner < Thor #:nodoc: # Display information about the given klasses. If with_module is given, # it shows a table with information extracted from the yaml file. # - def display_klasses(with_modules=false, klasses=Thor.subclasses) - klasses -= [Thor, Thor::Runner] unless with_modules + def display_klasses(with_modules=false, show_internal=false, klasses=Thor::Base.subclasses) + klasses -= [Thor, Thor::Runner, Thor::Group] unless show_internal + raise Error, "No Thor tasks available" if klasses.empty? + show_modules if with_modules && !thor_yaml.empty? - if with_modules && !thor_yaml.empty? - info = [] - labels = ["Modules", "Namespaces"] + # Remove subclasses + klasses.dup.each do |klass| + klasses -= Thor::Util.thor_classes_in(klass) + end - info << labels - info << [ "-" * labels[0].size, "-" * labels[1].size ] + list = Hash.new { |h,k| h[k] = [] } + groups = klasses.select { |k| k.ancestors.include?(Thor::Group) } - thor_yaml.each do |name, hash| - info << [ name, hash[:namespaces].join(", ") ] - end + # Get classes which inherit from Thor + (klasses - groups).each { |k| list[k.namespace] += k.printable_tasks(false) } - print_table info - say "" - end + # Get classes which inherit from Thor::Base + groups.map! { |k| k.printable_tasks(false).first } + list["root"] = groups - unless klasses.empty? - klasses.dup.each do |klass| - klasses -= Thor::Util.thor_classes_in(klass) - end + # Order namespaces with default coming first + list = list.sort{ |a,b| a[0].sub(/^default/, '') <=> b[0].sub(/^default/, '') } + list.each { |n, tasks| display_tasks(n, tasks) unless tasks.empty? } + end - klasses.each { |k| display_tasks(k) } - else - say "\033[1;34mNo Thor tasks available\033[0m" - end + def display_tasks(namespace, list) #:nodoc: + list.sort!{ |a,b| a[0] <=> b[0] } + + say shell.set_color(namespace, :blue, true) + say "-" * namespace.size + + print_table(list, :truncate => true) + say end - # Display tasks from the given Thor class. - # - def display_tasks(klass) - unless klass.tasks.empty? - base = klass.namespace + def show_modules #:nodoc: + info = [] + labels = ["Modules", "Namespaces"] - color = base == "default" ? :magenta : :blue - say shell.set_color(base, color, true) - say "-" * base.length + info << labels + info << [ "-" * labels[0].size, "-" * labels[1].size ] - klass.help(shell, :short => true, :ident => 0, :namespace => true) + thor_yaml.each do |name, hash| + info << [ name, hash[:namespaces].join(", ") ] end + + print_table info + say "" end end diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/shell.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/shell.rb index 1dc8f0e5b4..64a173de83 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/shell.rb +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/shell.rb @@ -22,7 +22,7 @@ class Thor end module Shell - SHELL_DELEGATED_METHODS = [:ask, :yes?, :no?, :say, :say_status, :print_list, :print_table] + SHELL_DELEGATED_METHODS = [:ask, :yes?, :no?, :say, :say_status, :print_table] # Add shell to initialize config values. # diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/shell/basic.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/shell/basic.rb index f6be3575ca..a11f45b4e9 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/shell/basic.rb +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/shell/basic.rb @@ -75,30 +75,6 @@ class Thor !yes?(statement, color) end - # Prints a list of items. - # - # ==== Parameters - # list<Array[String, String, ...]> - # - # ==== Options - # mode:: Can be :rows or :inline. Defaults to :rows. - # ident:: Ident each item with the value given. - # - def print_list(list, options={}) - return if list.empty? - - ident = " " * (options[:ident] || 0) - content = case options[:mode] - when :inline - last = list.pop - "#{list.join(", ")}, and #{last}" - else # rows - ident + list.join("\n#{ident}") - end - - $stdout.puts content - end - # Prints a table. # # ==== Parameters @@ -110,20 +86,26 @@ class Thor def print_table(table, options={}) return if table.empty? - formats = [] + formats, ident = [], options[:ident].to_i + options[:truncate] = terminal_width if options[:truncate] == true + 0.upto(table.first.length - 2) do |i| maxima = table.max{ |a,b| a[i].size <=> b[i].size }[i].size formats << "%-#{maxima + 2}s" end - formats[0] = formats[0].insert(0, " " * options[:ident]) if options[:ident] + formats[0] = formats[0].insert(0, " " * ident) formats << "%s" table.each do |row| + sentence = "" + row.each_with_index do |column, i| - $stdout.print formats[i] % column.to_s + sentence << formats[i] % column.to_s end - $stdout.puts + + sentence = truncate(sentence, options[:truncate]) if options[:truncate] + $stdout.puts sentence end end @@ -214,6 +196,44 @@ HELP base && base.options[:quiet] end + # This code was copied from Rake, available under MIT-LICENSE + # Copyright (c) 2003, 2004 Jim Weirich + def terminal_width + if ENV['THOR_COLUMNS'] + result = ENV['THOR_COLUMNS'].to_i + else + result = unix? ? dynamic_width : 80 + end + (result < 10) ? 80 : result + rescue + 80 + end + + # Calculate the dynamic width of the terminal + def dynamic_width + @dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput) + end + + def dynamic_width_stty + %x{stty size 2>/dev/null}.split[1].to_i + end + + def dynamic_width_tput + %x{tput cols 2>/dev/null}.to_i + end + + def unix? + RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i + end + + def truncate(string, width) + if string.length <= width + string + else + ( string[0, width-3] || "" ) + "..." + end + end + end end end diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/shell/color.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/shell/color.rb index 24704f7885..b2bc66dfba 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/shell/color.rb +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/shell/color.rb @@ -63,7 +63,7 @@ class Thor # def show_diff(destination, content) #:nodoc: if diff_lcs_loaded? && ENV['THOR_DIFF'].nil? && ENV['RAILS_DIFF'].nil? - actual = File.read(destination).to_s.split("\n") + actual = File.binread(destination).to_s.split("\n") content = content.to_s.split("\n") Diff::LCS.sdiff(actual, content).each do |diff| diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/task.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/task.rb index 91c7564d3f..5c8877591b 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/task.rb +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/task.rb @@ -1,11 +1,11 @@ class Thor class Task < Struct.new(:name, :description, :usage, :options) + FILE_REGEXP = /^#{Regexp.escape(File.expand_path(__FILE__))}:[\w:]+ `run'$/ # A dynamic task that handles method missing scenarios. - # class Dynamic < Task - def initialize(name) - super(name.to_s, "A dynamically-generated task", name.to_s) + def initialize(name, options=nil) + super(name.to_s, "A dynamically-generated task", name.to_s, options) end def run(instance, args=[]) @@ -25,84 +25,73 @@ class Thor self.options = other.options.dup if other.options end - def short_description - description.split("\n").first if description - end - # By default, a task invokes a method in the thor class. You can change this # implementation to create custom tasks. - # def run(instance, args=[]) raise UndefinedTaskError, "the '#{name}' task of #{instance.class} is private" unless public_method?(instance) instance.send(name, *args) rescue ArgumentError => e + raise e if instance.class.respond_to?(:debugging) && instance.class.debugging parse_argument_error(instance, e, caller) rescue NoMethodError => e + raise e if instance.class.respond_to?(:debugging) && instance.class.debugging parse_no_method_error(instance, e) end - # Returns the formatted usage. If a class is given, the class arguments are - # injected in the usage. - # - def formatted_usage(klass=nil, namespace=false, show_options=true) - formatted = if namespace.is_a?(String) - "#{namespace}:" - elsif klass && namespace - "#{klass.namespace.gsub(/^default/,'')}:" + # Returns the formatted usage by injecting given required arguments + # and required options into the given usage. + def formatted_usage(klass, namespace=nil) + namespace = klass.namespace if namespace.nil? + + # Add namespace + formatted = if namespace + "#{namespace.gsub(/^(default|thor:runner:)/,'')}:" else "" end - formatted << formatted_arguments(klass) - formatted << " #{formatted_options}" if show_options - formatted.strip! - formatted - end - - # Injects the class arguments into the task usage. - # - def formatted_arguments(klass) - if klass && !klass.arguments.empty? + # Add usage with required arguments + formatted << if klass && !klass.arguments.empty? usage.to_s.gsub(/^#{name}/) do |match| - match << " " << klass.arguments.map{ |a| a.usage }.join(' ') + match << " " << klass.arguments.map{ |a| a.usage }.compact.join(' ') end else usage.to_s end - end - # Returns the options usage for this task. - # - def formatted_options - @formatted_options ||= options.map{ |_, o| o.usage }.sort.join(" ") + # Add required options + formatted << " #{required_options}" + + # Strip and go! + formatted.strip end protected + def required_options + @required_options ||= options.map{ |_, o| o.usage if o.required? }.compact.sort.join(" ") + end + # Given a target, checks if this class name is not a private/protected method. - # def public_method?(instance) #:nodoc: collection = instance.private_methods + instance.protected_methods (collection & [name.to_s, name.to_sym]).empty? end - # Clean everything that comes from the Thor gempath and remove the caller. - # - def sans_backtrace(backtrace, caller) #:nodoc: - dirname = /^#{Regexp.escape(File.dirname(__FILE__))}/ - saned = backtrace.reject { |frame| frame =~ dirname } - saned -= caller + # For Ruby <= 1.8.7, we have to match the method name that we are trying to call. + # In Ruby >= 1.9.1, we have to match the method run in this file. + def backtrace_match?(backtrace) #:nodoc: + method_name = /`#{Regexp.escape(name.split(':').last)}'/ + backtrace =~ method_name || backtrace =~ FILE_REGEXP end def parse_argument_error(instance, e, caller) #:nodoc: - backtrace = sans_backtrace(e.backtrace, caller) - - if backtrace.empty? && e.message =~ /wrong number of arguments/ + if e.message =~ /wrong number of arguments/ && backtrace_match?(e.backtrace.first.to_s) if instance.is_a?(Thor::Group) raise e, "'#{name}' was called incorrectly. Are you sure it has arity equals to 0?" else raise InvocationError, "'#{name}' was called incorrectly. Call as " << - "'#{formatted_usage(instance.class, true)}'" + "'#{formatted_usage(instance.class)}'" end else raise e diff --git a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/util.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/util.rb index ebae0a3193..c2aed89ccf 100644 --- a/railties/lib/rails/vendor/thor-0.12.1/lib/thor/util.rb +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/util.rb @@ -76,8 +76,10 @@ class Thor # Returns the thor classes declared inside the given class. # def self.thor_classes_in(klass) + stringfied_constants = klass.constants.map { |c| c.to_s } Thor::Base.subclasses.select do |subclass| - klass.constants.include?(subclass.name.gsub("#{klass.name}::", '')) + next unless subclass.name + stringfied_constants.include?(subclass.name.gsub("#{klass.name}::", '')) end end @@ -155,7 +157,7 @@ class Thor # inside the sandbox to avoid namespacing conflicts. # def self.load_thorfile(path, content=nil) - content ||= File.read(path) + content ||= File.binread(path) begin Thor::Sandbox.class_eval(content, path) @@ -164,26 +166,6 @@ class Thor end end - # Receives a yaml (hash) and updates all constants entries to namespace. - # This was added to deal with deprecated versions of Thor. - # - # TODO Deprecate this method in the future. - # - # ==== Returns - # TrueClass|FalseClass:: Returns true if any change to the yaml file was made. - # - def self.convert_constants_to_namespaces(yaml) - yaml_changed = false - - yaml.each do |k, v| - next unless v[:constants] && v[:namespaces].nil? - yaml_changed = true - yaml[k][:namespaces] = v[:constants].map{|c| Thor::Util.namespace_from_thor_class(c)} - end - - yaml_changed - end - def self.user_home @@user_home ||= if ENV["HOME"] ENV["HOME"] diff --git a/railties/lib/rails/vendor/thor-0.12.3/lib/thor/version.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/version.rb new file mode 100644 index 0000000000..3c9dd6f808 --- /dev/null +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/version.rb @@ -0,0 +1,3 @@ +class Thor + VERSION = "0.12.3".freeze +end diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index adb867ca6d..79dfacdcdb 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -24,6 +24,11 @@ module ApplicationTests assert_equal Pathname.new(app_path), Rails.application.root end + test "the application root can be seen from the application singleton" do + require "#{app_path}/config/environment" + assert_equal Pathname.new(app_path), AppTemplate::Application.root + end + test "the application root can be set" do copy_app add_to_config <<-RUBY diff --git a/railties/test/generators/actions_test.rb b/railties/test/generators/actions_test.rb index b69f23c965..27b6a49566 100644 --- a/railties/test/generators/actions_test.rb +++ b/railties/test/generators/actions_test.rb @@ -1,8 +1,10 @@ -require 'abstract_unit' require 'generators/generators_test_helper' require 'rails/generators/rails/app/app_generator' class ActionsTest < GeneratorsTestCase + tests Rails::Generators::AppGenerator + arguments [destination_root] + def setup super @git_plugin_uri = 'git://github.com/technoweenie/restful-authentication.git' @@ -178,14 +180,6 @@ class ActionsTest < GeneratorsTestCase protected - def run_generator - silence(:stdout) { Rails::Generators::AppGenerator.start [destination_root] } - end - - def generator(config={}) - @generator ||= Rails::Generators::Base.new([], {}, { :destination_root => destination_root }.merge!(config)) - end - def action(*args, &block) silence(:stdout){ generator.send(*args, &block) } end diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index 2cba42551e..7dd798db75 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -3,6 +3,7 @@ require 'generators/generators_test_helper' require 'rails/generators/rails/app/app_generator' class AppGeneratorTest < GeneratorsTestCase + arguments [destination_root] def setup super @@ -49,17 +50,27 @@ class AppGeneratorTest < GeneratorsTestCase end def test_invalid_database_option_raises_an_error - content = capture(:stderr){ run_generator(["-d", "unknown"]) } + content = capture(:stderr){ run_generator([destination_root, "-d", "unknown"]) } assert_match /Invalid value for \-\-database option/, content end + def test_invalid_application_name_raises_an_error + content = capture(:stderr){ Rails::Generators::AppGenerator.start [File.join(destination_root, "43-things")] } + assert_equal "Invalid application name 43-things. Please give a name which does not start with numbers.\n", content + end + + def test_invalid_application_name_is_fixed + silence(:stdout){ Rails::Generators::AppGenerator.start [File.join(destination_root, "things-43")] } + assert_file "things-43/config/environment.rb", /Things43::Application/ + end + def test_config_database_is_added_by_default run_generator assert_file "config/database.yml", /sqlite3/ end def test_config_database_is_not_added_if_skip_activerecord_is_given - run_generator ["--skip-activerecord"] + run_generator [destination_root, "--skip-activerecord"] assert_no_file "config/database.yml" end @@ -76,13 +87,13 @@ class AppGeneratorTest < GeneratorsTestCase end def test_prototype_and_test_unit_are_skipped_if_required - run_generator ["--skip-prototype", "--skip-testunit"] + run_generator [destination_root, "--skip-prototype", "--skip-testunit"] assert_no_file "public/javascripts/prototype.js" assert_no_file "test" end def test_shebang_is_added_to_files - run_generator ["--ruby", "foo/bar/baz"] + run_generator [destination_root, "--ruby", "foo/bar/baz"] %w( about @@ -97,7 +108,7 @@ class AppGeneratorTest < GeneratorsTestCase end def test_shebang_when_is_the_same_as_default_use_env - run_generator ["--ruby", Thor::Util.ruby_command] + run_generator [destination_root, "--ruby", Thor::Util.ruby_command] %w( about @@ -113,11 +124,11 @@ class AppGeneratorTest < GeneratorsTestCase def test_template_from_dir_pwd FileUtils.cd(Rails.root) - assert_match /It works from file!/, run_generator(["-m", "lib/template.rb"]) + assert_match /It works from file!/, run_generator([destination_root, "-m", "lib/template.rb"]) end def test_template_raises_an_error_with_invalid_path - content = capture(:stderr){ run_generator(["-m", "non/existant/path"]) } + content = capture(:stderr){ run_generator([destination_root, "-m", "non/existant/path"]) } assert_match /The template \[.*\] could not be loaded/, content assert_match /non\/existant\/path/, content end @@ -127,7 +138,7 @@ class AppGeneratorTest < GeneratorsTestCase template = %{ say "It works!" } template.instance_eval "def read; self; end" # Make the string respond to read - generator(:template => path, :database => "sqlite3").expects(:open).with(path).returns(template) + generator([destination_root], :template => path, :database => "sqlite3").expects(:open).with(path).returns(template) assert_match /It works!/, silence(:stdout){ generator.invoke } end @@ -151,28 +162,20 @@ class AppGeneratorTest < GeneratorsTestCase end def test_dev_option - run_generator ["--dev"] + run_generator [destination_root, "--dev"] rails_path = File.expand_path('../../..', Rails.root) dev_gem = %(gem "rails", :path => #{rails_path.inspect}) assert_file 'Gemfile', /^#{Regexp.escape(dev_gem)}$/ end def test_edge_option - run_generator ["--edge"] + run_generator [destination_root, "--edge"] edge_gem = %(gem "rails", :git => "git://github.com/rails/rails.git") assert_file 'Gemfile', /^#{Regexp.escape(edge_gem)}$/ end protected - def run_generator(args=[]) - silence(:stdout) { Rails::Generators::AppGenerator.start [destination_root].concat(args) } - end - - def generator(options={}) - @generator ||= Rails::Generators::AppGenerator.new([destination_root], options, :destination_root => destination_root) - end - def action(*args, &block) silence(:stdout){ generator.send(*args, &block) } end diff --git a/railties/test/generators/controller_generator_test.rb b/railties/test/generators/controller_generator_test.rb index 56bc688ad0..8e2fd3b9ed 100644 --- a/railties/test/generators/controller_generator_test.rb +++ b/railties/test/generators/controller_generator_test.rb @@ -1,12 +1,12 @@ -require 'abstract_unit' require 'generators/generators_test_helper' require 'rails/generators/rails/controller/controller_generator' class ControllerGeneratorTest < GeneratorsTestCase + arguments %w(Account foo bar) def test_help_does_not_show_invoked_generators_options_if_they_already_exist content = run_generator ["--help"] - assert_no_match /Helper options:/, content + assert_no_match /Helper options\:/, content end def test_controller_skeleton_is_created @@ -66,15 +66,8 @@ class ControllerGeneratorTest < GeneratorsTestCase run_generator assert_file "app/controllers/account_controller.rb" do |controller| - assert_instance_method controller, :foo - assert_instance_method controller, :bar + assert_instance_method :foo, controller + assert_instance_method :bar, controller end end - - protected - - def run_generator(args=["Account", "foo", "bar"]) - silence(:stdout) { Rails::Generators::ControllerGenerator.start args, :destination_root => destination_root } - end - end diff --git a/railties/test/generators/generator_generator_test.rb b/railties/test/generators/generator_generator_test.rb index aea3f4da51..28377f23b0 100644 --- a/railties/test/generators/generator_generator_test.rb +++ b/railties/test/generators/generator_generator_test.rb @@ -1,8 +1,8 @@ -require 'abstract_unit' require 'generators/generators_test_helper' require 'rails/generators/rails/generator/generator_generator' class GeneratorGeneratorTest < GeneratorsTestCase + arguments %w(awesome) def test_generator_skeleton_is_created run_generator @@ -16,11 +16,4 @@ class GeneratorGeneratorTest < GeneratorsTestCase assert_file "lib/generators/awesome/awesome_generator.rb", /class AwesomeGenerator < Rails::Generators::NamedBase/ end - - protected - - def run_generator(args=["awesome"], config={}) - silence(:stdout) { Rails::Generators::GeneratorGenerator.start args, config.merge(:destination_root => destination_root) } - end - end diff --git a/railties/test/generators/generators_test_helper.rb b/railties/test/generators/generators_test_helper.rb index 4ce48a453b..35567f7929 100644 --- a/railties/test/generators/generators_test_helper.rb +++ b/railties/test/generators/generators_test_helper.rb @@ -10,93 +10,23 @@ end Rails.application.config.root = Rails.root require 'rails/generators' +require 'rails/generators/test_case' + require 'rubygems' require 'active_record' require 'action_dispatch' -CURRENT_PATH = File.expand_path(Dir.pwd) -Rails::Generators.no_color! - -class GeneratorsTestCase < ActiveSupport::TestCase - include FileUtils - - def destination_root - File.join(Rails.root, "tmp") - end +class GeneratorsTestCase < Rails::Generators::TestCase + destination File.join(Rails.root, "tmp") + setup :prepare_destination - def setup - cd CURRENT_PATH - rm_rf(destination_root) - mkdir_p(destination_root) + def self.inherited(base) + base.tests Rails::Generators.const_get(base.name.sub(/Test$/, '')) + rescue + # Do nothing. end def test_truth - # don't complain, test/unit - end - - def capture(stream) - begin - stream = stream.to_s - eval "$#{stream} = StringIO.new" - yield - result = eval("$#{stream}").string - ensure - eval("$#{stream} = #{stream.upcase}") - end - - result - end - alias :silence :capture - - def assert_file(relative, *contents) - absolute = File.join(destination_root, relative) - assert File.exists?(absolute), "Expected file #{relative.inspect} to exist, but does not" - - read = File.read(absolute) if block_given? || !contents.empty? - yield read if block_given? - - contents.each do |content| - case content - when String - assert_equal content, read - when Regexp - assert_match content, read - end - end - end - - def assert_no_file(relative) - absolute = File.join(destination_root, relative) - assert !File.exists?(absolute), "Expected file #{relative.inspect} to not exist, but does" + # Don't cry test/unit end - - def assert_migration(relative, *contents, &block) - file_name = migration_file_name(relative) - assert file_name, "Expected migration #{relative} to exist, but was not found" - assert_file File.join(File.dirname(relative), file_name), *contents, &block - end - - def assert_no_migration(relative) - file_name = migration_file_name(relative) - assert_nil file_name, "Expected migration #{relative} to not exist, but found #{file_name}" - end - - def assert_class_method(content, method, &block) - assert_instance_method content, "self.#{method}", &block - end - - def assert_instance_method(content, method) - assert content =~ /def #{method}(\(.+\))?(.*?)\n end/m, "Expected to have method #{method}" - yield $2.strip if block_given? - end - - protected - - def migration_file_name(relative) - absolute = File.join(destination_root, relative) - dirname, file_name = File.dirname(absolute), File.basename(absolute).sub(/\.rb$/, '') - - migration = Dir.glob("#{dirname}/[0-9]*_*.rb").grep(/\d+_#{file_name}.rb$/).first - File.basename(migration) if migration - end -end +end
\ No newline at end of file diff --git a/railties/test/generators/helper_generator_test.rb b/railties/test/generators/helper_generator_test.rb index f8bfc517a2..cf18782986 100644 --- a/railties/test/generators/helper_generator_test.rb +++ b/railties/test/generators/helper_generator_test.rb @@ -1,4 +1,3 @@ -require 'abstract_unit' require 'generators/generators_test_helper' require 'rails/generators/rails/helper/helper_generator' @@ -6,6 +5,7 @@ ObjectHelper = Class.new AnotherObjectHelperTest = Class.new class HelperGeneratorTest < GeneratorsTestCase + arguments %w(admin) def test_helper_skeleton_is_created run_generator @@ -50,11 +50,4 @@ class HelperGeneratorTest < GeneratorsTestCase end end end - - protected - - def run_generator(args=["admin"]) - silence(:stdout) { Rails::Generators::HelperGenerator.start args, :destination_root => destination_root } - end - end diff --git a/railties/test/generators/integration_test_generator_test.rb b/railties/test/generators/integration_test_generator_test.rb index 6a504ceea2..88e18be5b2 100644 --- a/railties/test/generators/integration_test_generator_test.rb +++ b/railties/test/generators/integration_test_generator_test.rb @@ -1,18 +1,11 @@ -require 'abstract_unit' require 'generators/generators_test_helper' require 'rails/generators/rails/integration_test/integration_test_generator' class IntegrationTestGeneratorTest < GeneratorsTestCase + arguments %w(integration) def test_integration_test_skeleton_is_created run_generator assert_file "test/integration/integration_test.rb", /class IntegrationTest < ActionController::IntegrationTest/ end - - protected - - def run_generator(args=["integration"]) - silence(:stdout) { Rails::Generators::IntegrationTestGenerator.start args, :destination_root => destination_root } - end - end diff --git a/railties/test/generators/mailer_generator_test.rb b/railties/test/generators/mailer_generator_test.rb index 251474ad16..ee4346eb71 100644 --- a/railties/test/generators/mailer_generator_test.rb +++ b/railties/test/generators/mailer_generator_test.rb @@ -1,8 +1,8 @@ -require 'abstract_unit' require 'generators/generators_test_helper' require 'rails/generators/rails/mailer/mailer_generator' class MailerGeneratorTest < GeneratorsTestCase + arguments %w(notifier foo bar) def test_mailer_skeleton_is_created run_generator @@ -42,11 +42,4 @@ class MailerGeneratorTest < GeneratorsTestCase assert_file "app/models/notifier.rb", /def foo/ assert_file "app/models/notifier.rb", /def bar/ end - - protected - - def run_generator(args=["notifier", "foo", "bar"]) - silence(:stdout) { Rails::Generators::MailerGenerator.start args, :destination_root => destination_root } - end - end diff --git a/railties/test/generators/metal_generator_test.rb b/railties/test/generators/metal_generator_test.rb index 80bf342892..5d6a277561 100644 --- a/railties/test/generators/metal_generator_test.rb +++ b/railties/test/generators/metal_generator_test.rb @@ -1,8 +1,8 @@ -require 'abstract_unit' require 'generators/generators_test_helper' require 'rails/generators/rails/metal/metal_generator' class MetalGeneratorTest < GeneratorsTestCase + arguments %w(foo) def test_metal_skeleton_is_created run_generator @@ -13,11 +13,4 @@ class MetalGeneratorTest < GeneratorsTestCase content = capture(:stderr){ run_generator ["object"] } assert_match /The name 'Object' is either already used in your application or reserved/, content end - - protected - - def run_generator(args=["foo"]) - silence(:stdout) { Rails::Generators::MetalGenerator.start args, :destination_root => destination_root } - end - end diff --git a/railties/test/generators/migration_generator_test.rb b/railties/test/generators/migration_generator_test.rb index 35172a8be4..2fd3e5c056 100644 --- a/railties/test/generators/migration_generator_test.rb +++ b/railties/test/generators/migration_generator_test.rb @@ -1,32 +1,30 @@ -require 'abstract_unit' require 'generators/generators_test_helper' require 'rails/generators/rails/migration/migration_generator' class MigrationGeneratorTest < GeneratorsTestCase - def test_migration - @migration = "change_title_body_from_posts" - run_generator - assert_migration "db/migrate/#{@migration}.rb", /class ChangeTitleBodyFromPosts < ActiveRecord::Migration/ + migration = "change_title_body_from_posts" + run_generator [migration] + assert_migration "db/migrate/#{migration}.rb", /class ChangeTitleBodyFromPosts < ActiveRecord::Migration/ end def test_migration_with_class_name - @migration = "ChangeTitleBodyFromPosts" - run_generator - assert_migration "db/migrate/change_title_body_from_posts.rb", /class #{@migration} < ActiveRecord::Migration/ + migration = "ChangeTitleBodyFromPosts" + run_generator [migration] + assert_migration "db/migrate/change_title_body_from_posts.rb", /class #{migration} < ActiveRecord::Migration/ end def test_add_migration_with_attributes - @migration = "add_title_body_to_posts" - run_generator [@migration, "title:string", "body:text"] + migration = "add_title_body_to_posts" + run_generator [migration, "title:string", "body:text"] - assert_migration "db/migrate/#{@migration}.rb" do |content| - assert_class_method content, :up do |up| + assert_migration "db/migrate/#{migration}.rb" do |content| + assert_class_method :up, content do |up| assert_match /add_column :posts, :title, :string/, up assert_match /add_column :posts, :body, :text/, up end - assert_class_method content, :down do |down| + assert_class_method :down, content do |down| assert_match /remove_column :posts, :title/, down assert_match /remove_column :posts, :body/, down end @@ -34,26 +32,19 @@ class MigrationGeneratorTest < GeneratorsTestCase end def test_remove_migration_with_attributes - @migration = "remove_title_body_from_posts" - run_generator [@migration, "title:string", "body:text"] + migration = "remove_title_body_from_posts" + run_generator [migration, "title:string", "body:text"] - assert_migration "db/migrate/#{@migration}.rb" do |content| - assert_class_method content, :up do |up| + assert_migration "db/migrate/#{migration}.rb" do |content| + assert_class_method :up, content do |up| assert_match /remove_column :posts, :title/, up assert_match /remove_column :posts, :body/, up end - assert_class_method content, :down do |down| + assert_class_method :down, content do |down| assert_match /add_column :posts, :title, :string/, down assert_match /add_column :posts, :body, :text/, down end end end - - protected - - def run_generator(args=[@migration]) - silence(:stdout) { Rails::Generators::MigrationGenerator.start args, :destination_root => destination_root } - end - end diff --git a/railties/test/generators/model_generator_test.rb b/railties/test/generators/model_generator_test.rb index e073b11e1e..051a43706b 100644 --- a/railties/test/generators/model_generator_test.rb +++ b/railties/test/generators/model_generator_test.rb @@ -1,8 +1,8 @@ -require 'abstract_unit' require 'generators/generators_test_helper' require 'rails/generators/rails/model/model_generator' class ModelGeneratorTest < GeneratorsTestCase + arguments %w(Account name:string age:integer) def test_help_shows_invoked_generators_options content = run_generator ["--help"] @@ -84,13 +84,13 @@ class ModelGeneratorTest < GeneratorsTestCase run_generator ["product", "name:string", "supplier_id:integer"] assert_migration "db/migrate/create_products.rb" do |m| - assert_class_method m, :up do |up| + assert_class_method :up, m do |up| assert_match /create_table :products/, up assert_match /t\.string :name/, up assert_match /t\.integer :supplier_id/, up end - assert_class_method m, :down do |down| + assert_class_method :down, m do |down| assert_match /drop_table :products/, down end end @@ -126,7 +126,7 @@ class ModelGeneratorTest < GeneratorsTestCase run_generator ["account", "--no-timestamps"] assert_migration "db/migrate/create_accounts.rb" do |m| - assert_class_method m, :up do |up| + assert_class_method :up, m do |up| assert_no_match /t.timestamps/, up end end @@ -171,11 +171,4 @@ class ModelGeneratorTest < GeneratorsTestCase content = capture(:stderr){ run_generator ["object"] } assert_match /The name 'Object' is either already used in your application or reserved/, content end - - protected - - def run_generator(args=["Account", "name:string", "age:integer"], config={}) - silence(:stdout) { Rails::Generators::ModelGenerator.start args, config.merge(:destination_root => destination_root) } - end - end diff --git a/railties/test/generators/named_base_test.rb b/railties/test/generators/named_base_test.rb index 98cbf9b8f6..8c1df3b992 100644 --- a/railties/test/generators/named_base_test.rb +++ b/railties/test/generators/named_base_test.rb @@ -1,4 +1,3 @@ -require 'abstract_unit' require 'generators/generators_test_helper' require 'rails/generators/rails/scaffold_controller/scaffold_controller_generator' @@ -13,9 +12,10 @@ module ActiveRecord end class NamedBaseTest < GeneratorsTestCase + tests Rails::Generators::ScaffoldControllerGenerator def test_named_generator_attributes - g = Rails::Generators::ScaffoldControllerGenerator.new ["admin/foo"] + g = generator ["admin/foo"] assert_equal 'admin/foo', g.name assert_equal %w(admin), g.class_path assert_equal 1, g.class_nesting_depth @@ -28,12 +28,12 @@ class NamedBaseTest < GeneratorsTestCase def test_named_generator_attributes_without_pluralized ActiveRecord::Base.pluralize_table_names = false - g = Rails::Generators::ScaffoldControllerGenerator.new ["admin/foo"] + g = generator ["admin/foo"] assert_equal "admin_#{g.singular_name}", g.table_name end def test_scaffold_plural_names - g = Rails::Generators::ScaffoldControllerGenerator.new ["ProductLine"] + g = generator ["ProductLine"] assert_equal "ProductLines", g.controller_name assert_equal "ProductLines", g.controller_class_name assert_equal "product_lines", g.controller_file_name diff --git a/railties/test/generators/observer_generator_test.rb b/railties/test/generators/observer_generator_test.rb index 6fed2998dd..44d9e4a9f3 100644 --- a/railties/test/generators/observer_generator_test.rb +++ b/railties/test/generators/observer_generator_test.rb @@ -1,8 +1,8 @@ -require 'abstract_unit' require 'generators/generators_test_helper' require 'rails/generators/rails/observer/observer_generator' class ObserverGeneratorTest < GeneratorsTestCase + arguments %w(account) def test_invokes_default_orm run_generator @@ -23,11 +23,4 @@ class ObserverGeneratorTest < GeneratorsTestCase content = run_generator ["account", "--test-framework=rspec"] assert_match /rspec \[not found\]/, content end - - protected - - def run_generator(args=["account"]) - silence(:stdout) { Rails::Generators::ObserverGenerator.start args, :destination_root => destination_root } - end - end diff --git a/railties/test/generators/performance_test_generator_test.rb b/railties/test/generators/performance_test_generator_test.rb index d19128f79a..099575ea1d 100644 --- a/railties/test/generators/performance_test_generator_test.rb +++ b/railties/test/generators/performance_test_generator_test.rb @@ -1,18 +1,11 @@ -require 'abstract_unit' require 'generators/generators_test_helper' require 'rails/generators/rails/performance_test/performance_test_generator' class PerformanceTestGeneratorTest < GeneratorsTestCase + arguments %w(performance) def test_performance_test_skeleton_is_created run_generator assert_file "test/performance/performance_test.rb", /class PerformanceTest < ActionController::PerformanceTest/ end - - protected - - def run_generator(args=["performance"]) - silence(:stdout) { Rails::Generators::PerformanceTestGenerator.start args, :destination_root => destination_root } - end - end diff --git a/railties/test/generators/plugin_generator_test.rb b/railties/test/generators/plugin_generator_test.rb index f5b8b6ffb6..f84b8b6d50 100644 --- a/railties/test/generators/plugin_generator_test.rb +++ b/railties/test/generators/plugin_generator_test.rb @@ -1,8 +1,8 @@ -require 'abstract_unit' require 'generators/generators_test_helper' require 'rails/generators/rails/plugin/plugin_generator' class PluginGeneratorTest < GeneratorsTestCase + arguments %w(plugin_fu) def test_plugin_skeleton_is_created run_generator @@ -46,11 +46,4 @@ class PluginGeneratorTest < GeneratorsTestCase run_generator run_generator ["plugin_fu"], :behavior => :revoke end - - protected - - def run_generator(args=["plugin_fu"], config={}) - silence(:stdout) { Rails::Generators::PluginGenerator.start args, config.merge(:destination_root => destination_root) } - end - end diff --git a/railties/test/generators/resource_generator_test.rb b/railties/test/generators/resource_generator_test.rb index dff3908ea1..15c0ca0f01 100644 --- a/railties/test/generators/resource_generator_test.rb +++ b/railties/test/generators/resource_generator_test.rb @@ -1,8 +1,8 @@ -require 'abstract_unit' require 'generators/generators_test_helper' require 'rails/generators/rails/resource/resource_generator' class ResourceGeneratorTest < GeneratorsTestCase + arguments %w(account) def setup super @@ -50,8 +50,8 @@ class ResourceGeneratorTest < GeneratorsTestCase run_generator ["account", "--actions", "index", "new"] assert_file "app/controllers/accounts_controller.rb" do |controller| - assert_instance_method controller, :index - assert_instance_method controller, :new + assert_instance_method :index, controller + assert_instance_method :new, controller end assert_file "app/views/accounts/index.html.erb" @@ -96,11 +96,4 @@ class ResourceGeneratorTest < GeneratorsTestCase assert_no_match /resources :accounts$/, route end end - - protected - - def run_generator(args=["account"], config={}) - silence(:stdout) { Rails::Generators::ResourceGenerator.start args, config.merge(:destination_root => destination_root) } - end - end diff --git a/railties/test/generators/scaffold_controller_generator_test.rb b/railties/test/generators/scaffold_controller_generator_test.rb index 02155c295c..7593c14dd9 100644 --- a/railties/test/generators/scaffold_controller_generator_test.rb +++ b/railties/test/generators/scaffold_controller_generator_test.rb @@ -1,4 +1,3 @@ -require 'abstract_unit' require 'generators/generators_test_helper' require 'rails/generators/rails/scaffold_controller/scaffold_controller_generator' @@ -8,6 +7,7 @@ module Unknown end class ScaffoldControllerGeneratorTest < GeneratorsTestCase + arguments %w(User name:string age:integer) def test_controller_skeleton_is_created run_generator @@ -15,35 +15,35 @@ class ScaffoldControllerGeneratorTest < GeneratorsTestCase assert_file "app/controllers/users_controller.rb" do |content| assert_match /class UsersController < ApplicationController/, content - assert_instance_method content, :index do |m| + assert_instance_method :index, content do |m| assert_match /@users = User\.all/, m end - assert_instance_method content, :show do |m| + assert_instance_method :show, content do |m| assert_match /@user = User\.find\(params\[:id\]\)/, m end - assert_instance_method content, :new do |m| + assert_instance_method :new, content do |m| assert_match /@user = User\.new/, m end - assert_instance_method content, :edit do |m| + assert_instance_method :edit, content do |m| assert_match /@user = User\.find\(params\[:id\]\)/, m end - assert_instance_method content, :create do |m| + assert_instance_method :create, content do |m| assert_match /@user = User\.new\(params\[:user\]\)/, m assert_match /@user\.save/, m assert_match /@user\.errors/, m end - assert_instance_method content, :update do |m| + assert_instance_method :update, content do |m| assert_match /@user = User\.find\(params\[:id\]\)/, m assert_match /@user\.update_attributes\(params\[:user\]\)/, m assert_match /@user\.errors/, m end - assert_instance_method content, :destroy do |m| + assert_instance_method :destroy, content do |m| assert_match /@user = User\.find\(params\[:id\]\)/, m assert_match /@user\.destroy/, m end @@ -108,7 +108,7 @@ class ScaffoldControllerGeneratorTest < GeneratorsTestCase assert_file "app/controllers/users_controller.rb" do |content| assert_match /class UsersController < ApplicationController/, content - assert_instance_method content, :index do |m| + assert_instance_method :index, content do |m| assert_match /@users = User\.all/, m end end @@ -127,7 +127,7 @@ class ScaffoldControllerGeneratorTest < GeneratorsTestCase assert_file "app/controllers/users_controller.rb" do |content| assert_match /class UsersController < ApplicationController/, content - assert_instance_method content, :index do |m| + assert_instance_method :index, content do |m| assert_match /@users = User\.find\(:all\)/, m assert_no_match /@users = User\.all/, m end @@ -135,11 +135,4 @@ class ScaffoldControllerGeneratorTest < GeneratorsTestCase ensure Unknown::Generators.send :remove_const, :ActiveModel end - - protected - - def run_generator(args=["User", "name:string", "age:integer"]) - silence(:stdout) { Rails::Generators::ScaffoldControllerGenerator.start args, :destination_root => destination_root } - end - end diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb index 0b961cee19..4ddc7b1c89 100644 --- a/railties/test/generators/scaffold_generator_test.rb +++ b/railties/test/generators/scaffold_generator_test.rb @@ -1,8 +1,8 @@ -require 'abstract_unit' require 'generators/generators_test_helper' require 'rails/generators/rails/scaffold/scaffold_generator' class ScaffoldGeneratorTest < GeneratorsTestCase + arguments %w(product_line title:string price:integer) def setup super @@ -32,35 +32,35 @@ class ScaffoldGeneratorTest < GeneratorsTestCase assert_file "app/controllers/product_lines_controller.rb" do |content| assert_match /class ProductLinesController < ApplicationController/, content - assert_instance_method content, :index do |m| + assert_instance_method :index, content do |m| assert_match /@product_lines = ProductLine\.all/, m end - assert_instance_method content, :show do |m| + assert_instance_method :show, content do |m| assert_match /@product_line = ProductLine\.find\(params\[:id\]\)/, m end - assert_instance_method content, :new do |m| + assert_instance_method :new, content do |m| assert_match /@product_line = ProductLine\.new/, m end - assert_instance_method content, :edit do |m| + assert_instance_method :edit, content do |m| assert_match /@product_line = ProductLine\.find\(params\[:id\]\)/, m end - assert_instance_method content, :create do |m| + assert_instance_method :create, content do |m| assert_match /@product_line = ProductLine\.new\(params\[:product_line\]\)/, m assert_match /@product_line\.save/, m assert_match /@product_line\.errors/, m end - assert_instance_method content, :update do |m| + assert_instance_method :update, content do |m| assert_match /@product_line = ProductLine\.find\(params\[:id\]\)/, m assert_match /@product_line\.update_attributes\(params\[:product_line\]\)/, m assert_match /@product_line\.errors/, m end - assert_instance_method content, :destroy do |m| + assert_instance_method :destroy, content do |m| assert_match /@product_line = ProductLine\.find\(params\[:id\]\)/, m assert_match /@product_line\.destroy/, m end @@ -89,7 +89,7 @@ class ScaffoldGeneratorTest < GeneratorsTestCase def test_scaffold_on_revoke run_generator - run_generator :behavior => :revoke + run_generator ["product_line"], :behavior => :revoke # Model assert_no_file "app/models/product_line.rb" @@ -117,14 +117,4 @@ class ScaffoldGeneratorTest < GeneratorsTestCase # Stylesheets (should not be removed) assert_file "public/stylesheets/scaffold.css" end - - protected - - def run_generator(config={}) - silence(:stdout) do - Rails::Generators::ScaffoldGenerator.start ["product_line", "title:string", "price:integer"], - config.merge(:destination_root => destination_root) - end - end - end diff --git a/railties/test/generators/session_migration_generator_test.rb b/railties/test/generators/session_migration_generator_test.rb index 34fb996b7f..251ffb19ed 100644 --- a/railties/test/generators/session_migration_generator_test.rb +++ b/railties/test/generators/session_migration_generator_test.rb @@ -1,9 +1,7 @@ -require 'abstract_unit' require 'generators/generators_test_helper' require 'rails/generators/rails/session_migration/session_migration_generator' class SessionMigrationGeneratorTest < GeneratorsTestCase - def test_session_migration_with_default_name run_generator assert_migration "db/migrate/add_sessions_table.rb", /class AddSessionsTable < ActiveRecord::Migration/ @@ -24,11 +22,4 @@ class SessionMigrationGeneratorTest < GeneratorsTestCase ensure ActiveRecord::SessionStore::Session.table_name = "sessions" end - - protected - - def run_generator(args=[]) - silence(:stdout) { Rails::Generators::SessionMigrationGenerator.start args, :destination_root => destination_root } - end - end diff --git a/railties/test/generators/stylesheets_generator_test.rb b/railties/test/generators/stylesheets_generator_test.rb index 15263d4bb8..d9079327ba 100644 --- a/railties/test/generators/stylesheets_generator_test.rb +++ b/railties/test/generators/stylesheets_generator_test.rb @@ -1,9 +1,7 @@ -require 'abstract_unit' require 'generators/generators_test_helper' require 'rails/generators/rails/stylesheets/stylesheets_generator' class StylesheetsGeneratorTest < GeneratorsTestCase - def test_copy_stylesheets run_generator assert_file "public/stylesheets/scaffold.css" @@ -11,14 +9,7 @@ class StylesheetsGeneratorTest < GeneratorsTestCase def test_stylesheets_are_not_deleted_on_revoke run_generator - run_generator :behavior => :revoke + run_generator [], :behavior => :revoke assert_file "public/stylesheets/scaffold.css" end - - protected - - def run_generator(config={}) - silence(:stdout) { Rails::Generators::StylesheetsGenerator.start [], config.merge(:destination_root => destination_root) } - end - end diff --git a/railties/test/generators_test.rb b/railties/test/generators_test.rb index 4b7b80c7f5..2df218debc 100644 --- a/railties/test/generators_test.rb +++ b/railties/test/generators_test.rb @@ -9,6 +9,11 @@ class GeneratorsTest < GeneratorsTestCase Gem.stubs(:respond_to?).with(:loaded_specs).returns(false) end + def test_invoke_add_generators_to_raw_lookups + TestUnit::Generators::ModelGenerator.expects(:start).with(["Account"], {}) + Rails::Generators.invoke("test_unit:model", ["Account"]) + end + def test_invoke_when_generator_is_not_found output = capture(:stdout){ Rails::Generators.invoke :unknown } assert_equal "Could not find generator unknown.\n", output @@ -51,12 +56,6 @@ class GeneratorsTest < GeneratorsTestCase assert_equal "foobar:foobar", klass.namespace end - def test_find_by_namespace_add_generators_to_raw_lookups - klass = Rails::Generators.find_by_namespace("test_unit:model") - assert klass - assert_equal "test_unit:generators:model", klass.namespace - end - def test_find_by_namespace_lookup_to_the_rails_root_folder klass = Rails::Generators.find_by_namespace(:fixjour) assert klass @@ -96,7 +95,7 @@ class GeneratorsTest < GeneratorsTestCase end def test_builtin_generators - assert Rails::Generators.builtin.include? %w(rails model) + assert Rails::Generators.builtin.include?("rails:model") end def test_rails_generators_help_with_builtin_information @@ -107,7 +106,7 @@ class GeneratorsTest < GeneratorsTestCase def test_rails_generators_with_others_information output = capture(:stdout){ Rails::Generators.help }.split("\n").last - assert_equal "Others: active_record:fixjour, fixjour, foobar, mspec, rails:javascripts.", output + assert_equal "Others: active_record:fixjour, fixjour, foobar:foobar, mspec, rails:javascripts, xspec.", output end def test_warning_is_shown_if_generator_cant_be_loaded @@ -178,6 +177,8 @@ class GeneratorsTest < GeneratorsTestCase end assert_equal false, klass.class_options[:generate].default + ensure + Rails::Generators.subclasses.delete(klass) end def test_source_paths_for_not_namespaced_generators |