Added class collision checks.

This commit is contained in:
José Valim 2009-06-25 11:56:18 +02:00
parent 4573fd2e06
commit ed33c29a4e
7 changed files with 67 additions and 20 deletions

@ -29,6 +29,39 @@ def self.namespace(name=nil) #:nodoc:
protected
# Check whether the given class names are already taken by Ruby or Rails.
# In the future, expand to check other namespaces such as the rest of
# the user's app.
#
def class_collisions(*class_names)
return unless behavior == :invoke
class_names.flatten.each do |class_name|
class_name = class_name.to_s
next if class_name.strip.empty?
# Split the class from its module nesting
nesting = class_name.split('::')
last_name = nesting.pop
# Hack to limit const_defined? to non-inherited on 1.9
extra = []
extra << false unless Object.method(:const_defined?).arity == 1
# Extract the last Module in the nesting
last = nesting.inject(Object) do |last, nest|
break unless last.const_defined?(nest, *extra)
last.const_get(nest)
end
if last && last.const_defined?(last_name.camelize, *extra)
raise Error, "The name '#{class_name}' is either already used in your application " <<
"or reserved by Ruby on Rails. Please choose an alternative and run " <<
"this generator again."
end
end
end
# Use Rails default banner.
#
def self.banner

@ -1,7 +1,13 @@
module Rails::Generators
class MetalGenerator < NamedBase
def create_file
template "metal.rb", "app/metal/#{file_name}.rb"
module Rails
module Generators
class MetalGenerator < NamedBase
def check_class_collision
class_collisions class_name
end
def create_file
template "metal.rb", "app/metal/#{file_name}.rb"
end
end
end
end

@ -1,8 +1,9 @@
module Rails
module Generators
class ObserverGenerator < NamedBase
# TODO Check class collisions
# class_collisions "#{class_name}Observer", "#{class_name}ObserverTest"
def check_class_collision
class_collisions "#{class_name}Observer"
end
def create_observer_file
template 'observer.rb', File.join('app/models', class_path, "#{file_name}_observer.rb")

@ -7,8 +7,9 @@ class PluginGenerator < NamedBase
class_option :with_generator, :type => :boolean, :aliases => "-g", :default => false,
:desc => "When supplied creates generator base files."
# TODO Check class collision
# class_collision class_name
def check_class_collision
class_collisions class_name
end
def create_root
self.root = File.expand_path("vendor/plugins/#{file_name}", root)

@ -12,12 +12,8 @@ def destination_root
end
def setup
rm_rf(destination_root)
mkdir_p(destination_root)
rm_rf(destination_root)
end
def teardown
rm_rf(destination_root)
end
def test_truth

@ -9,10 +9,15 @@ def test_metal_skeleton_is_created
assert_file "app/metal/foo.rb", /class Foo/
end
def test_check_class_collision
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=[])
silence(:stdout) { Rails::Generators::MetalGenerator.start ["foo"].concat(args), :root => destination_root }
def run_generator(args=["foo"])
silence(:stdout) { Rails::Generators::MetalGenerator.start args, :root => destination_root }
end
end

@ -15,23 +15,28 @@ def test_plugin_skeleton_is_created
).each{ |path| assert_file path }
end
def test_check_class_collision
content = capture(:stderr){ run_generator ["object"] }
assert_match /The name 'Object' is either already used in your application or reserved/, content
end
def test_invokes_default_test_framework
run_generator
assert_file "vendor/plugins/plugin_fu/test/plugin_fu_test.rb"
end
def test_logs_if_the_test_framework_cannot_be_found
content = run_generator ["--test-framework=unknown"]
content = run_generator ["plugin_fu", "--test-framework=unknown"]
assert_match /Could not find and invoke 'unknown:generators:plugin'/, content
end
def test_creates_tasks_if_required
run_generator ["--with-tasks"]
run_generator ["plugin_fu", "--with-tasks"]
assert_file "vendor/plugins/plugin_fu/tasks/plugin_fu_tasks.rake"
end
def test_creates_generator_if_required
run_generator ["--with-generator"]
run_generator ["plugin_fu", "--with-generator"]
assert_file "vendor/plugins/plugin_fu/generators/plugin_fu/templates"
flag = /class PluginFuGenerator < Rails::Generators::NamedBase/
@ -40,8 +45,8 @@ def test_creates_generator_if_required
protected
def run_generator(args=[])
silence(:stdout) { Rails::Generators::PluginGenerator.start ["plugin_fu"].concat(args), :root => destination_root }
def run_generator(args=["plugin_fu"])
silence(:stdout) { Rails::Generators::PluginGenerator.start args, :root => destination_root }
end
end