From b4df25366a3c8f133f8329bc35f1d53926704b5a Mon Sep 17 00:00:00 2001 From: Prem Sichanugrist and Chris Toomey Date: Fri, 25 Jan 2013 13:44:36 -0500 Subject: Add `rails test` command to run the test suite To run the whole test suite: $ rails test To run the test file(s): $ rails test test/unit/foo_test.rb [test/unit/bar_test.rb ...] To run the test suite $ rails test [models,helpers,units,controllers,mailers,...] For more information, see `rails test --help`. This command will eventually replacing `rake test:*`, and `rake test` command will actually invoking `rails test` instead. --- railties/lib/rails/commands.rb | 15 +++++ railties/lib/rails/commands/test_runner.rb | 92 ++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 railties/lib/rails/commands/test_runner.rb (limited to 'railties/lib/rails') diff --git a/railties/lib/rails/commands.rb b/railties/lib/rails/commands.rb index aacde52cfc..c76af7d01f 100644 --- a/railties/lib/rails/commands.rb +++ b/railties/lib/rails/commands.rb @@ -5,6 +5,7 @@ aliases = { "d" => "destroy", "c" => "console", "s" => "server", + "t" => "test", "db" => "dbconsole", "r" => "runner" } @@ -16,6 +17,7 @@ The most common rails commands are: generate Generate new code (short-cut alias: "g") console Start the Rails console (short-cut alias: "c") server Start the Rails server (short-cut alias: "s") + test Running the test file (short-cut alias: "t") dbconsole Start a console for the database specified in config/database.yml (short-cut alias: "db") new Create a new Rails application. "rails new my_app" creates a @@ -78,6 +80,19 @@ when 'server' server.start end +when 'test' + $LOAD_PATH.unshift("./test") + require 'rails/commands/test_runner' + if ["-h", "--help"].include?(ARGV.first) + Rails::TestRunner.help_message + exit + else + require APP_PATH + Rails.application.require_environment! + Rails.application.load_tasks + Rails::TestRunner.start(ARGV) + end + when 'dbconsole' require 'rails/commands/dbconsole' Rails::DBConsole.start diff --git a/railties/lib/rails/commands/test_runner.rb b/railties/lib/rails/commands/test_runner.rb new file mode 100644 index 0000000000..a65b508505 --- /dev/null +++ b/railties/lib/rails/commands/test_runner.rb @@ -0,0 +1,92 @@ +require 'optparse' +require 'minitest/unit' + +module Rails + # Handling the all the logic behind +rails test+ command. + class TestRunner + class << self + # Parse the test suite name from the arguments array and pass in a list + # of file to a new +TestRunner+ object, then invoke the evaluation. If + # the argument is not a test suite name, it will be treated as a file + # name and passed to the +TestRunner+ instance right away. + def start(arguments) + case arguments.first + when nil + new(Dir['test/**/*_test.rb']).run + when 'models' + new(Dir['test/models/**/*_test.rb']).run + when 'helpers' + new(Dir['test/helpers/**/*_test.rb']).run + when 'units' + new(Dir['test/{models,helpers,unit}/**/*_test.rb']).run + when 'controllers' + new(Dir['test/controllers/**/*_test.rb']).run + when 'mailers' + new(Dir['test/mailers/**/*_test.rb']).run + when 'functionals' + new(Dir['test/{controllers,mailers,functional}/**/*_test.rb']).run + when 'integration' + new(Dir['test/integration/**/*_test.rb']).run + else + new(arguments).run + end + end + + # Print out the help message which listed all of the test suite names. + def help_message + puts "Usage: rails test [path to test file(s) or test suite type]" + puts "" + puts "Run single test file, or a test suite, under Rails'" + puts "environment. If the file name(s) or suit name is omitted," + puts "Rails will run all the test suites." + puts "" + puts "Support types of test suites:" + puts "-------------------------------------------------------------" + puts "* models (test/models/**/*)" + puts "* helpers (test/helpers/**/*)" + puts "* units (test/{models,helpers,unit}/**/*" + puts "* controllers (test/controllers/**/*)" + puts "* mailers (test/mailers/**/*)" + puts "* functionals (test/{controllers,mailers,functional}/**/*)" + puts "* integration (test/integration/**/*)" + puts "-------------------------------------------------------------" + end + end + + # Create a new +TestRunner+ object with a list of test file paths. + def initialize(files) + @files = files + Rake::Task['test:prepare'].invoke + MiniTest::Unit.output = SilentUntilSyncStream.new(MiniTest::Unit.output) + end + + # Run the test files by evaluate each of them. + def run + @files.each { |filename| load(filename) } + end + + # A null stream object which ignores everything until +sync+ has been set + # to true. This is only to be used to silence unnecessary output from + # MiniTest, as MiniTest calls +output.sync = true+ right before output the + # first test result. + class SilentUntilSyncStream < File + # Create a +SilentUntilSyncStream+ object by given a stream object that + # this stream should set +MiniTest::Unit.output+ to after +sync+ has been + # set to true. + def initialize(target_stream) + @target_stream = target_stream + super(File::NULL, 'w') + end + + # Swap +MiniTest::Unit.output+ to another stream when +sync+ is true. + def sync=(sync) + if sync + @target_stream.sync = true + MiniTest::Unit.output = @target_stream + end + + super + end + end + end +end -- cgit v1.2.3