From 8b8d7ef6599e69082b55947383661f89d2fc339b Mon Sep 17 00:00:00 2001 From: Eugene Bolshakov Date: Mon, 13 Oct 2008 13:03:59 -0400 Subject: [PATCH] Helper test generator --- railties/helpers/test_helper.rb | 8 ++++ .../generators/components/controller/USAGE | 23 ++++++------ .../components/controller/controller_generator.rb | 8 ++++- .../components/controller/templates/helper_test.rb | 4 ++ .../generators/components/helper/USAGE | 24 +++++++++++++ .../components/helper/helper_generator.rb | 25 +++++++++++++ .../components/helper/templates/helper.rb | 2 + .../components/helper/templates/helper_test.rb | 4 ++ .../generators/components/resource/USAGE | 4 +- .../components/resource/resource_generator.rb | 2 + .../components/resource/templates/helper_test.rb | 4 ++ .../components/scaffold/scaffold_generator.rb | 2 + .../components/scaffold/templates/helper_test.rb | 4 ++ railties/lib/tasks/testing.rake | 2 +- railties/lib/test_help.rb | 1 + railties/test/generators/generator_test_helper.rb | 33 +++++++++++++----- .../generators/rails_controller_generator_test.rb | 2 + .../test/generators/rails_helper_generator_test.rb | 37 ++++++++++++++++++++ .../generators/rails_resource_generator_test.rb | 2 + .../generators/rails_scaffold_generator_test.rb | 5 +++ 20 files changed, 172 insertions(+), 24 deletions(-) create mode 100755 railties/lib/rails_generator/generators/components/controller/templates/helper_test.rb create mode 100755 railties/lib/rails_generator/generators/components/helper/USAGE create mode 100755 railties/lib/rails_generator/generators/components/helper/helper_generator.rb create mode 100755 railties/lib/rails_generator/generators/components/helper/templates/helper.rb create mode 100755 railties/lib/rails_generator/generators/components/helper/templates/helper_test.rb create mode 100755 railties/lib/rails_generator/generators/components/resource/templates/helper_test.rb create mode 100755 railties/lib/rails_generator/generators/components/scaffold/templates/helper_test.rb create mode 100755 railties/test/generators/rails_helper_generator_test.rb diff --git a/railties/helpers/test_helper.rb b/railties/helpers/test_helper.rb index 9f19269..469573b 100644 --- a/railties/helpers/test_helper.rb +++ b/railties/helpers/test_helper.rb @@ -36,3 +36,11 @@ class Test::Unit::TestCase # Add more helper methods to be used by all tests here... end + +class ActionView::TestCase + # Enable UrlWriter when testing helpers + include ActionController::UrlWriter + + # Default host for helper tests + default_url_options[:host] = 'localhost' +end diff --git a/railties/lib/rails_generator/generators/components/controller/USAGE b/railties/lib/rails_generator/generators/components/controller/USAGE index d4fae60..882da7d 100644 --- a/railties/lib/rails_generator/generators/components/controller/USAGE +++ b/railties/lib/rails_generator/generators/components/controller/USAGE @@ -6,24 +6,25 @@ Description: path like 'parent_module/controller_name'. This generates a controller class in app/controllers, view templates in - app/views/controller_name, a helper class in app/helpers, and a functional - test suite in test/functional. + app/views/controller_name, a helper class in app/helpers, a functional + test suite in test/functional and a helper test suite in test/unit/helpers. Example: `./script/generate controller CreditCard open debit credit close` Credit card controller with URLs like /credit_card/debit. - Controller: app/controllers/credit_card_controller.rb - Views: app/views/credit_card/debit.html.erb [...] - Helper: app/helpers/credit_card_helper.rb - Test: test/functional/credit_card_controller_test.rb + Controller: app/controllers/credit_card_controller.rb + Functional Test: test/functional/credit_card_controller_test.rb + Views: app/views/credit_card/debit.html.erb [...] + Helper: app/helpers/credit_card_helper.rb + Helper Test: test/unit/helpers/credit_card_helper_test.rb Modules Example: `./script/generate controller 'admin/credit_card' suspend late_fee` Credit card admin controller with URLs /admin/credit_card/suspend. - Controller: app/controllers/admin/credit_card_controller.rb - Views: app/views/admin/credit_card/debit.html.erb [...] - Helper: app/helpers/admin/credit_card_helper.rb - Test: test/functional/admin/credit_card_controller_test.rb - + Controller: app/controllers/admin/credit_card_controller.rb + Functional Test: test/functional/admin/credit_card_controller_test.rb + Views: app/views/admin/credit_card/debit.html.erb [...] + Helper: app/helpers/admin/credit_card_helper.rb + Helper Test: test/unit/helpers/admin/credit_card_helper_test.rb diff --git a/railties/lib/rails_generator/generators/components/controller/controller_generator.rb b/railties/lib/rails_generator/generators/components/controller/controller_generator.rb index c37ff45..ea0a3ac 100644 --- a/railties/lib/rails_generator/generators/components/controller/controller_generator.rb +++ b/railties/lib/rails_generator/generators/components/controller/controller_generator.rb @@ -2,13 +2,14 @@ class ControllerGenerator < Rails::Generator::NamedBase def manifest record do |m| # Check for class naming collisions. - m.class_collisions class_path, "#{class_name}Controller", "#{class_name}ControllerTest", "#{class_name}Helper" + m.class_collisions class_path, "#{class_name}Controller", "#{class_name}ControllerTest", "#{class_name}Helper", "#{class_name}HelperTest" # Controller, helper, views, and test directories. m.directory File.join('app/controllers', class_path) m.directory File.join('app/helpers', class_path) m.directory File.join('app/views', class_path, file_name) m.directory File.join('test/functional', class_path) + m.directory File.join('test/unit/helpers', class_path) # Controller class, functional test, and helper class. m.template 'controller.rb', @@ -25,6 +26,11 @@ class ControllerGenerator < Rails::Generator::NamedBase File.join('app/helpers', class_path, "#{file_name}_helper.rb") + + m.template 'helper_test.rb', + File.join('test/unit/helpers', + class_path, + "#{file_name}_helper_test.rb") # View template for each action. actions.each do |action| diff --git a/railties/lib/rails_generator/generators/components/controller/templates/helper_test.rb b/railties/lib/rails_generator/generators/components/controller/templates/helper_test.rb new file mode 100755 index 0000000..591e409 --- /dev/null +++ b/railties/lib/rails_generator/generators/components/controller/templates/helper_test.rb @@ -0,0 +1,4 @@ +require 'test_helper' + +class <%= class_name %>HelperTest < ActionView::TestCase +end diff --git a/railties/lib/rails_generator/generators/components/helper/USAGE b/railties/lib/rails_generator/generators/components/helper/USAGE new file mode 100755 index 0000000..ef27ca6 --- /dev/null +++ b/railties/lib/rails_generator/generators/components/helper/USAGE @@ -0,0 +1,24 @@ +Description: + Stubs out a new helper. Pass the helper name, either + CamelCased or under_scored. + + To create a helper within a module, specify the helper name as a + path like 'parent_module/helper_name'. + + This generates a helper class in app/helpers and a helper test + suite in test/unit/helpers. + +Example: + `./script/generate helper CreditCard` + + Credit card helper. + Helper: app/helpers/credit_card_helper.rb + Test: test/unit/helpers/credit_card_helper_test.rb + +Modules Example: + `./script/generate helper 'admin/credit_card'` + + Credit card admin helper. + Helper: app/helpers/admin/credit_card_helper.rb + Test: test/unit/helpers/admin/credit_card_helper_test.rb + diff --git a/railties/lib/rails_generator/generators/components/helper/helper_generator.rb b/railties/lib/rails_generator/generators/components/helper/helper_generator.rb new file mode 100755 index 0000000..5666452 --- /dev/null +++ b/railties/lib/rails_generator/generators/components/helper/helper_generator.rb @@ -0,0 +1,25 @@ +class HelperGenerator < Rails::Generator::NamedBase + def manifest + record do |m| + # Check for class naming collisions. + m.class_collisions class_path, "#{class_name}Helper", "#{class_name}HelperTest" + + # Helper and helper test directories. + m.directory File.join('app/helpers', class_path) + m.directory File.join('test/unit/helpers', class_path) + + # Helper and helper test class. + + m.template 'helper.rb', + File.join('app/helpers', + class_path, + "#{file_name}_helper.rb") + + m.template 'helper_test.rb', + File.join('test/unit/helpers', + class_path, + "#{file_name}_helper_test.rb") + + end + end +end diff --git a/railties/lib/rails_generator/generators/components/helper/templates/helper.rb b/railties/lib/rails_generator/generators/components/helper/templates/helper.rb new file mode 100755 index 0000000..3fe2ecd --- /dev/null +++ b/railties/lib/rails_generator/generators/components/helper/templates/helper.rb @@ -0,0 +1,2 @@ +module <%= class_name %>Helper +end diff --git a/railties/lib/rails_generator/generators/components/helper/templates/helper_test.rb b/railties/lib/rails_generator/generators/components/helper/templates/helper_test.rb new file mode 100755 index 0000000..591e409 --- /dev/null +++ b/railties/lib/rails_generator/generators/components/helper/templates/helper_test.rb @@ -0,0 +1,4 @@ +require 'test_helper' + +class <%= class_name %>HelperTest < ActionView::TestCase +end diff --git a/railties/lib/rails_generator/generators/components/resource/USAGE b/railties/lib/rails_generator/generators/components/resource/USAGE index 83cc9d7..586eebb 100644 --- a/railties/lib/rails_generator/generators/components/resource/USAGE +++ b/railties/lib/rails_generator/generators/components/resource/USAGE @@ -11,8 +11,8 @@ Description: You don't have to think up every attribute up front, but it helps to sketch out a few so you can start working with the resource immediately. - This creates a model, controller, tests and fixtures for both, and the - corresponding map.resources declaration in config/routes.rb + This creates a model, controller, helper, tests and fixtures for all of them, + and the corresponding map.resources declaration in config/routes.rb Unlike the scaffold generator, the resource generator does not create views or add any methods to the generated controller. diff --git a/railties/lib/rails_generator/generators/components/resource/resource_generator.rb b/railties/lib/rails_generator/generators/components/resource/resource_generator.rb index d5491ec..10c7f38 100644 --- a/railties/lib/rails_generator/generators/components/resource/resource_generator.rb +++ b/railties/lib/rails_generator/generators/components/resource/resource_generator.rb @@ -40,6 +40,7 @@ class ResourceGenerator < Rails::Generator::NamedBase m.directory(File.join('app/views', controller_class_path, controller_file_name)) m.directory(File.join('test/functional', controller_class_path)) m.directory(File.join('test/unit', class_path)) + m.directory(File.join('test/unit/helpers', class_path)) m.dependency 'model', [name] + @args, :collision => :skip @@ -49,6 +50,7 @@ class ResourceGenerator < Rails::Generator::NamedBase m.template('functional_test.rb', File.join('test/functional', controller_class_path, "#{controller_file_name}_controller_test.rb")) m.template('helper.rb', File.join('app/helpers', controller_class_path, "#{controller_file_name}_helper.rb")) + m.template('helper_test.rb', File.join('test/unit/helpers', controller_class_path, "#{controller_file_name}_helper_test.rb")) m.route_resources controller_file_name end diff --git a/railties/lib/rails_generator/generators/components/resource/templates/helper_test.rb b/railties/lib/rails_generator/generators/components/resource/templates/helper_test.rb new file mode 100755 index 0000000..061f64a --- /dev/null +++ b/railties/lib/rails_generator/generators/components/resource/templates/helper_test.rb @@ -0,0 +1,4 @@ +require 'test_helper' + +class <%= controller_class_name %>HelperTest < ActionView::TestCase +end diff --git a/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb b/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb index 5fecfe0..29a59ee 100644 --- a/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb +++ b/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb @@ -47,6 +47,7 @@ class ScaffoldGenerator < Rails::Generator::NamedBase m.directory(File.join('app/views/layouts', controller_class_path)) m.directory(File.join('test/functional', controller_class_path)) m.directory(File.join('test/unit', class_path)) + m.directory(File.join('test/unit/helpers', class_path)) m.directory(File.join('public/stylesheets', class_path)) for action in scaffold_views @@ -66,6 +67,7 @@ class ScaffoldGenerator < Rails::Generator::NamedBase m.template('functional_test.rb', File.join('test/functional', controller_class_path, "#{controller_file_name}_controller_test.rb")) m.template('helper.rb', File.join('app/helpers', controller_class_path, "#{controller_file_name}_helper.rb")) + m.template('helper_test.rb', File.join('test/unit/helpers', controller_class_path, "#{controller_file_name}_helper_test.rb")) m.route_resources controller_file_name diff --git a/railties/lib/rails_generator/generators/components/scaffold/templates/helper_test.rb b/railties/lib/rails_generator/generators/components/scaffold/templates/helper_test.rb new file mode 100755 index 0000000..061f64a --- /dev/null +++ b/railties/lib/rails_generator/generators/components/scaffold/templates/helper_test.rb @@ -0,0 +1,4 @@ +require 'test_helper' + +class <%= controller_class_name %>HelperTest < ActionView::TestCase +end diff --git a/railties/lib/tasks/testing.rake b/railties/lib/tasks/testing.rake index 328bde7..afafdd6 100644 --- a/railties/lib/tasks/testing.rake +++ b/railties/lib/tasks/testing.rake @@ -94,7 +94,7 @@ namespace :test do t.verbose = true end Rake::Task['test:units'].comment = "Run the unit tests in test/unit" - + Rake::TestTask.new(:functionals => "db:test:prepare") do |t| t.libs << "test" t.pattern = 'test/functional/**/*_test.rb' diff --git a/railties/lib/test_help.rb b/railties/lib/test_help.rb index 3cc61d7..cdd1cd1 100644 --- a/railties/lib/test_help.rb +++ b/railties/lib/test_help.rb @@ -6,6 +6,7 @@ silence_warnings { RAILS_ENV = "test" } require 'test/unit' require 'active_support/test_case' +require 'action_view/test_case' require 'active_record/fixtures' require 'action_controller/test_case' require 'action_controller/integration' diff --git a/railties/test/generators/generator_test_helper.rb b/railties/test/generators/generator_test_helper.rb index 0901b21..76f7c2f 100644 --- a/railties/test/generators/generator_test_helper.rb +++ b/railties/test/generators/generator_test_helper.rb @@ -144,6 +144,19 @@ class GeneratorTestCase < Test::Unit::TestCase yield body if block_given? end end + + # Asserts that the given helper test test was generated. + # It takes a name or symbol without the _helper_test part and an optional super class. + # The contents of the class source file is passed to a block. + def assert_generated_helper_test_for(name, parent = "ActionView::TestCase") + path = "test/unit/helpers/#{name.to_s.underscore}_helper_test" + # Have to pass the path without the "test/" part so that class_name_from_path will return a correct result + class_name = class_name_from_path(path.gsub(/^test\//, '')) + + assert_generated_class path,parent,class_name do |body| + yield body if block_given? + end + end # Asserts that the given unit test was generated. # It takes a name or symbol without the _test part and an optional super class. @@ -172,20 +185,22 @@ class GeneratorTestCase < Test::Unit::TestCase # Asserts that the given class source file was generated. # It takes a path without the .rb part and an optional super class. # The contents of the class source file is passed to a block. - def assert_generated_class(path, parent = nil) + def assert_generated_class(path, parent = nil, class_name = class_name_from_path(path)) + assert_generated_file("#{path}.rb") do |body| + assert_match /class #{class_name}#{parent.nil? ? '':" < #{parent}"}/, body, "the file '#{path}.rb' should be a class" + yield body if block_given? + end + end + + def class_name_from_path(path) # FIXME: Sucky way to detect namespaced classes if path.split('/').size > 3 path =~ /\/?(\d+_)?(\w+)\/(\w+)$/ - class_name = "#{$2.camelize}::#{$3.camelize}" + "#{$2.camelize}::#{$3.camelize}" else path =~ /\/?(\d+_)?(\w+)$/ - class_name = $2.camelize - end - - assert_generated_file("#{path}.rb") do |body| - assert_match /class #{class_name}#{parent.nil? ? '':" < #{parent}"}/, body, "the file '#{path}.rb' should be a class" - yield body if block_given? - end + $2.camelize + end end # Asserts that the given module source file was generated. diff --git a/railties/test/generators/rails_controller_generator_test.rb b/railties/test/generators/rails_controller_generator_test.rb index 8304fb5..b68bed7 100644 --- a/railties/test/generators/rails_controller_generator_test.rb +++ b/railties/test/generators/rails_controller_generator_test.rb @@ -8,6 +8,7 @@ class RailsControllerGeneratorTest < GeneratorTestCase assert_generated_controller_for :products assert_generated_functional_test_for :products assert_generated_helper_for :products + assert_generated_helper_test_for :products end def test_controller_generates_namespaced_controller @@ -16,6 +17,7 @@ class RailsControllerGeneratorTest < GeneratorTestCase assert_generated_controller_for "admin::products" assert_generated_functional_test_for "admin::products" assert_generated_helper_for "admin::products" + assert_generated_helper_test_for "admin::products" end def test_controller_generates_namespaced_and_not_namespaced_controllers diff --git a/railties/test/generators/rails_helper_generator_test.rb b/railties/test/generators/rails_helper_generator_test.rb new file mode 100755 index 0000000..03be7c9 --- /dev/null +++ b/railties/test/generators/rails_helper_generator_test.rb @@ -0,0 +1,37 @@ +require File.dirname(__FILE__) + '/generator_test_helper' + +class RailsHelperGeneratorTest < GeneratorTestCase + + def test_helper_generates_helper + run_generator('helper', %w(products)) + + assert_generated_helper_for :products + assert_generated_helper_test_for :products + end + + def test_helper_generates_namespaced_helper + run_generator('helper', %w(admin::products)) + + assert_generated_helper_for "admin::products" + assert_generated_helper_test_for "admin::products" + end + + def test_helper_generates_namespaced_and_not_namespaced_helpers + run_generator('helper', %w(products)) + + # We have to require the generated helper to show the problem because + # the test helpers just check for generated files and contents but + # do not actually load them. But they have to be loaded (as in a real environment) + # to make the second generator run fail + require "#{RAILS_ROOT}/app/helpers/products_helper" + + assert_nothing_raised do + begin + run_generator('helper', %w(admin::products)) + ensure + # cleanup + Object.send(:remove_const, :ProductsHelper) + end + end + end +end diff --git a/railties/test/generators/rails_resource_generator_test.rb b/railties/test/generators/rails_resource_generator_test.rb index 45e4850..c0be089 100644 --- a/railties/test/generators/rails_resource_generator_test.rb +++ b/railties/test/generators/rails_resource_generator_test.rb @@ -10,6 +10,7 @@ class RailsResourceGeneratorTest < GeneratorTestCase assert_generated_fixtures_for :products assert_generated_functional_test_for :products assert_generated_helper_for :products + assert_generated_helper_test_for :products assert_generated_migration :create_products assert_added_route_for :products end @@ -22,6 +23,7 @@ class RailsResourceGeneratorTest < GeneratorTestCase assert_generated_fixtures_for :products assert_generated_functional_test_for :products assert_generated_helper_for :products + assert_generated_helper_test_for :products assert_skipped_migration :create_products assert_added_route_for :products end diff --git a/railties/test/generators/rails_scaffold_generator_test.rb b/railties/test/generators/rails_scaffold_generator_test.rb index de6b38d..4a3306e 100644 --- a/railties/test/generators/rails_scaffold_generator_test.rb +++ b/railties/test/generators/rails_scaffold_generator_test.rb @@ -43,6 +43,7 @@ class RailsScaffoldGeneratorTest < GeneratorTestCase assert_generated_unit_test_for :product assert_generated_fixtures_for :products assert_generated_helper_for :products + assert_generated_helper_test_for :products assert_generated_stylesheet :scaffold assert_generated_views_for :products, "index.html.erb", "new.html.erb", "edit.html.erb", "show.html.erb" @@ -58,6 +59,7 @@ class RailsScaffoldGeneratorTest < GeneratorTestCase assert_generated_unit_test_for :product assert_generated_fixtures_for :products assert_generated_helper_for :products + assert_generated_helper_test_for :products assert_generated_stylesheet :scaffold assert_generated_views_for :products, "index.html.erb","new.html.erb","edit.html.erb","show.html.erb" assert_skipped_migration :create_products @@ -93,6 +95,7 @@ class RailsScaffoldGeneratorTest < GeneratorTestCase assert_generated_unit_test_for :product assert_generated_fixtures_for :products assert_generated_helper_for :products + assert_generated_helper_test_for :products assert_generated_stylesheet :scaffold assert_generated_views_for :products, "index.html.erb", "new.html.erb", "edit.html.erb", "show.html.erb" @@ -126,6 +129,7 @@ class RailsScaffoldGeneratorTest < GeneratorTestCase assert_generated_unit_test_for :product assert_generated_fixtures_for :products assert_generated_helper_for :products + assert_generated_helper_test_for :products assert_generated_stylesheet :scaffold assert_generated_views_for :products, "index.html.erb","new.html.erb","edit.html.erb","show.html.erb" assert_skipped_migration :create_products @@ -140,6 +144,7 @@ class RailsScaffoldGeneratorTest < GeneratorTestCase assert_generated_unit_test_for :products assert_generated_fixtures_for :products assert_generated_helper_for :products + assert_generated_helper_test_for :products assert_generated_stylesheet :scaffold assert_generated_views_for :products, "index.html.erb","new.html.erb","edit.html.erb","show.html.erb" assert_skipped_migration :create_products -- 1.5.4.3