diff options
author | francis <francis> | 2008-01-23 01:54:49 +0000 |
---|---|---|
committer | francis <francis> | 2008-01-23 01:54:49 +0000 |
commit | fdaa98e06ba6d6f8b62480a83e9ecffdbcb21402 (patch) | |
tree | 40b8b0d7602a7a17bead44e0fd3a2ea101b18bd6 /vendor/plugins/rspec/lib/spec/runner | |
parent | 60eaae4f7df1f1dae91defb87d3707451c359cf4 (diff) |
Upgrade to rspec 1.1.2
Diffstat (limited to 'vendor/plugins/rspec/lib/spec/runner')
20 files changed, 505 insertions, 647 deletions
diff --git a/vendor/plugins/rspec/lib/spec/runner/backtrace_tweaker.rb b/vendor/plugins/rspec/lib/spec/runner/backtrace_tweaker.rb index aacc2c8b8..5fd2fb99f 100644 --- a/vendor/plugins/rspec/lib/spec/runner/backtrace_tweaker.rb +++ b/vendor/plugins/rspec/lib/spec/runner/backtrace_tweaker.rb @@ -7,7 +7,7 @@ module Spec end class NoisyBacktraceTweaker < BacktraceTweaker - def tweak_backtrace(error, spec_name) + def tweak_backtrace(error) return if error.backtrace.nil? error.backtrace.each do |line| clean_up_double_slashes(line) @@ -19,7 +19,7 @@ module Spec class QuietBacktraceTweaker < BacktraceTweaker unless defined?(IGNORE_PATTERNS) root_dir = File.expand_path(File.join(__FILE__, '..', '..', '..', '..')) - spec_files = Dir["#{root_dir}/lib/spec/*"].map do |path| + spec_files = Dir["#{root_dir}/lib/*"].map do |path| subpath = path[root_dir.length..-1] /#{subpath}/ end @@ -38,7 +38,7 @@ module Spec ] end - def tweak_backtrace(error, spec_name) + def tweak_backtrace(error) return if error.backtrace.nil? error.backtrace.collect! do |line| clean_up_double_slashes(line) diff --git a/vendor/plugins/rspec/lib/spec/runner/behaviour_runner.rb b/vendor/plugins/rspec/lib/spec/runner/behaviour_runner.rb deleted file mode 100644 index 1ac891f3c..000000000 --- a/vendor/plugins/rspec/lib/spec/runner/behaviour_runner.rb +++ /dev/null @@ -1,123 +0,0 @@ -module Spec - module Runner - class BehaviourRunner - - def initialize(options, arg=nil) - @behaviours = [] - @options = options - end - - def add_behaviour(behaviour) - if !specified_examples.nil? && !specified_examples.empty? - behaviour.retain_examples_matching!(specified_examples) - end - @behaviours << behaviour if behaviour.number_of_examples != 0 && !behaviour.shared? - end - - # Runs all behaviours and returns the number of failures. - def run(paths, exit_when_done) - prepare!(paths) - begin - run_behaviours - rescue Interrupt - ensure - report_end - end - failure_count = report_dump - - heckle if(failure_count == 0 && !@options.heckle_runner.nil?) - - if(exit_when_done) - exit_code = (failure_count == 0) ? 0 : 1 - exit(exit_code) - end - failure_count - end - - def report_end - @options.reporter.end - end - - def report_dump - @options.reporter.dump - end - - def prepare!(paths) - unless paths.nil? # It's nil when running single specs with ruby - paths = find_paths(paths) - sorted_paths = sort_paths(paths) - load_specs(sorted_paths) # This will populate @behaviours via callbacks to add_behaviour - end - @options.reporter.start(number_of_examples) - @behaviours.reverse! if @options.reverse - set_sequence_numbers - end - - def run_behaviours - @behaviours.each do |behaviour| - behaviour.run(@options.reporter, @options.dry_run, @options.reverse, @options.timeout) - end - end - - def number_of_examples - @behaviours.inject(0) {|sum, behaviour| sum + behaviour.number_of_examples} - end - - FILE_SORTERS = { - 'mtime' => lambda {|file_a, file_b| File.mtime(file_b) <=> File.mtime(file_a)} - } - - def sorter(paths) - FILE_SORTERS[@options.loadby] - end - - def sort_paths(paths) - sorter = sorter(paths) - paths = paths.sort(&sorter) unless sorter.nil? - paths - end - - private - - # Sets the #number on each Example - def set_sequence_numbers - number = 0 - @behaviours.each do |behaviour| - number = behaviour.set_sequence_numbers(number, @options.reverse) - end - end - - def find_paths(paths) - result = [] - paths.each do |path| - if File.directory?(path) - result += Dir["#{path}/**/*.rb"] - elsif File.file?(path) - result << path - else - raise "File or directory not found: #{path}" - end - end - result - end - - def load_specs(paths) - paths.each do |path| - load path - end - end - - def specified_examples - @options.examples - end - - def heckle - heckle_runner = @options.heckle_runner - @options.heckle_runner = nil - behaviour_runner = self.class.new(@options) - behaviour_runner.instance_variable_set(:@behaviours, @behaviours) - heckle_runner.heckle_with(behaviour_runner) - end - end - end -end diff --git a/vendor/plugins/rspec/lib/spec/runner/command_line.rb b/vendor/plugins/rspec/lib/spec/runner/command_line.rb index 0d70337e1..9849c4853 100644 --- a/vendor/plugins/rspec/lib/spec/runner/command_line.rb +++ b/vendor/plugins/rspec/lib/spec/runner/command_line.rb @@ -4,18 +4,24 @@ module Spec module Runner # Facade to run specs without having to fork a new ruby process (using `spec ...`) class CommandLine - # Runs specs. +argv+ is the commandline args as per the spec commandline API, +err+ - # and +out+ are the streams output will be written to. +exit+ tells whether or - # not a system exit should be called after the specs are run and - # +warn_if_no_files+ tells whether or not a warning (the help message) - # should be printed to +err+ in case no files are specified. - def self.run(argv, err, out, exit=true, warn_if_no_files=true) - old_behaviour_runner = defined?($behaviour_runner) ? $behaviour_runner : nil - $behaviour_runner = OptionParser.new.create_behaviour_runner(argv, err, out, warn_if_no_files) - return if $behaviour_runner.nil? # This is the case if we use --drb - - $behaviour_runner.run(argv, exit) - $behaviour_runner = old_behaviour_runner + class << self + # Runs specs. +argv+ is the commandline args as per the spec commandline API, +err+ + # and +out+ are the streams output will be written to. + def run(instance_rspec_options) + # NOTE - this call to init_rspec_options is not spec'd, but neither is any of this + # swapping of $rspec_options. That is all here to enable rspec to run against itself + # and maintain coverage in a single process. Therefore, DO NOT mess with this stuff + # unless you know what you are doing! + init_rspec_options(instance_rspec_options) + orig_rspec_options = rspec_options + begin + $rspec_options = instance_rspec_options + return $rspec_options.run_examples + ensure + ::Spec.run = true + $rspec_options = orig_rspec_options + end + end end end end diff --git a/vendor/plugins/rspec/lib/spec/runner/drb_command_line.rb b/vendor/plugins/rspec/lib/spec/runner/drb_command_line.rb index 7e745fb71..6c340cfea 100644 --- a/vendor/plugins/rspec/lib/spec/runner/drb_command_line.rb +++ b/vendor/plugins/rspec/lib/spec/runner/drb_command_line.rb @@ -6,14 +6,13 @@ module Spec class DrbCommandLine # Runs specs on a DRB server. Note that this API is similar to that of # CommandLine - making it possible for clients to use both interchangeably. - def self.run(argv, stderr, stdout, exit=true, warn_if_no_files=true) + def self.run(options) begin DRb.start_service spec_server = DRbObject.new_with_uri("druby://localhost:8989") - spec_server.run(argv, stderr, stdout) - rescue DRb::DRbConnError - stderr.puts "No server is running" - exit 1 if exit + spec_server.run(options.argv, options.error_stream, options.output_stream) + rescue DRb::DRbConnError => e + options.error_stream.puts "No server is running" end end end diff --git a/vendor/plugins/rspec/lib/spec/runner/extensions/kernel.rb b/vendor/plugins/rspec/lib/spec/runner/extensions/kernel.rb deleted file mode 100644 index 75f2c335e..000000000 --- a/vendor/plugins/rspec/lib/spec/runner/extensions/kernel.rb +++ /dev/null @@ -1,50 +0,0 @@ -module Kernel - # Creates and registers an instance of a Spec::DSL::Behaviour (or a subclass). - # The instantiated behaviour class depends on the directory of the file - # calling this method. For example, Spec::Rails will use different - # classes for specs living in <tt>spec/models</tt>, <tt>spec/helpers</tt>, - # <tt>spec/views</tt> and <tt>spec/controllers</tt>. - # - # It is also possible to override autodiscovery of the behaviour class - # with an options Hash as the last argument: - # - # describe "name", :behaviour_type => :something_special do ... - # - # The reason for using different behaviour classes is to have - # different matcher methods available from within the <tt>describe</tt> - # block. - # - # See Spec::DSL::BehaviourFactory#add_behaviour_class for details about - # how to register special Spec::DSL::Behaviour implementations. - # - def describe(*args, &block) - raise ArgumentError if args.empty? - args << {} unless Hash === args.last - args.last[:spec_path] = caller(0)[1] - register_behaviour(Spec::DSL::BehaviourFactory.create(*args, &block)) - end - alias :context :describe - - def respond_to(*names) - Spec::Matchers::RespondTo.new(*names) - end - -private - - def register_behaviour(behaviour) - if behaviour.shared? - Spec::DSL::Behaviour.add_shared_behaviour(behaviour) - else - behaviour_runner.add_behaviour(behaviour) - end - end - - def behaviour_runner - # TODO: Figure out a better way to get this considered "covered" and keep this statement on multiple lines - unless $behaviour_runner; \ - $behaviour_runner = ::Spec::Runner::OptionParser.new.create_behaviour_runner(ARGV.dup, STDERR, STDOUT, false); \ - at_exit { $behaviour_runner.run(nil, false) }; \ - end - $behaviour_runner - end -end diff --git a/vendor/plugins/rspec/lib/spec/runner/extensions/object.rb b/vendor/plugins/rspec/lib/spec/runner/extensions/object.rb deleted file mode 100644 index 49745352f..000000000 --- a/vendor/plugins/rspec/lib/spec/runner/extensions/object.rb +++ /dev/null @@ -1,32 +0,0 @@ -# The following copyright applies to Object#copy_instance_variables_from, -# which we borrowed from active_support. -# -# Copyright (c) 2004 David Heinemeier Hansson -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -class Object - # From active_support - def copy_instance_variables_from(object, exclude = []) # :nodoc: - exclude += object.protected_instance_variables if object.respond_to? :protected_instance_variables - - instance_variables = object.instance_variables - exclude.map { |name| name.to_s } - instance_variables.each { |name| instance_variable_set(name, object.instance_variable_get(name)) } - end -end diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter.rb deleted file mode 100644 index 17512d958..000000000 --- a/vendor/plugins/rspec/lib/spec/runner/formatter.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'spec/runner/formatter/base_formatter' -require 'spec/runner/formatter/base_text_formatter' -require 'spec/runner/formatter/progress_bar_formatter' -require 'spec/runner/formatter/rdoc_formatter' -require 'spec/runner/formatter/specdoc_formatter' -require 'spec/runner/formatter/html_formatter' -require 'spec/runner/formatter/failing_examples_formatter' -require 'spec/runner/formatter/failing_behaviours_formatter' -require 'spec/runner/formatter/snippet_extractor' diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/base_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/base_formatter.rb index 7cc43ef0e..c8647cf50 100644 --- a/vendor/plugins/rspec/lib/spec/runner/formatter/base_formatter.rb +++ b/vendor/plugins/rspec/lib/spec/runner/formatter/base_formatter.rb @@ -3,7 +3,9 @@ module Spec module Formatter # Baseclass for formatters that implements all required methods as no-ops. class BaseFormatter - def initialize(where) + attr_accessor :example_group, :options, :where + def initialize(options, where) + @options = options @where = where end @@ -12,16 +14,17 @@ module Spec # formatters that need to provide progress on feedback (graphical ones) # # This method will only be invoked once, and the next one to be invoked - # is #add_behaviour + # is #add_example_group def start(example_count) end - # This method is invoked at the beginning of the execution of each behaviour. - # +name+ is the name of the behaviour and +first+ is true if it is the - # first behaviour - otherwise it's false. + # This method is invoked at the beginning of the execution of each example_group. + # +name+ is the name of the example_group and +first+ is true if it is the + # first example_group - otherwise it's false. # # The next method to be invoked after this is #example_failed or #example_finished - def add_behaviour(name) + def add_example_group(example_group) + @example_group = example_group end # This method is invoked when an +example+ starts. @@ -41,10 +44,9 @@ module Spec # This method is invoked when an example is not yet implemented (i.e. has not # been provided a block), or when an ExamplePendingError is raised. - # +name+ is the name of the example. # +message+ is the message from the ExamplePendingError, if it exists, or the # default value of "Not Yet Implemented" - def example_pending(behaviour_name, example_name, message) + def example_pending(example_group_description, example, message) end # This method is invoked after all of the examples have executed. The next method diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/base_text_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/base_text_formatter.rb index c3cf01b76..859b2641d 100644 --- a/vendor/plugins/rspec/lib/spec/runner/formatter/base_text_formatter.rb +++ b/vendor/plugins/rspec/lib/spec/runner/formatter/base_text_formatter.rb @@ -1,3 +1,5 @@ +require 'spec/runner/formatter/base_formatter' + module Spec module Runner module Formatter @@ -5,13 +7,12 @@ module Spec # non-text based ones too - just ignore the +output+ constructor # argument. class BaseTextFormatter < BaseFormatter - attr_writer :dry_run - + attr_reader :output, :pending_examples # Creates a new instance that will write to +where+. If +where+ is a # String, output will be written to the File with that name, otherwise # +where+ is exected to be an IO (or an object that responds to #puts and #write). - def initialize(where) - super(where) + def initialize(options, where) + super if where.is_a?(String) @output = File.open(where, 'w') elsif where == STDOUT @@ -22,21 +23,13 @@ module Spec else @output = where end - @colour = false - @dry_run = false - @snippet_extractor = SnippetExtractor.new @pending_examples = [] end - def example_pending(behaviour_name, example_name, message) - @pending_examples << ["#{behaviour_name} #{example_name}", message] + def example_pending(example_group_description, example, message) + @pending_examples << ["#{example_group_description} #{example.description}", message] end - def colour=(colour) - @colour = colour - begin ; require 'Win32/Console/ANSI' if @colour && PLATFORM =~ /win32/ ; rescue LoadError ; raise "You must gem install win32console to use colour on Windows" ; end - end - def dump_failure(counter, failure) @output.puts @output.puts "#{counter.to_s})" @@ -56,7 +49,7 @@ module Spec end def dump_summary(duration, example_count, failure_count, pending_count) - return if @dry_run + return if dry_run? @output.puts @output.puts "Finished in #{duration} seconds" @output.puts @@ -74,7 +67,6 @@ module Spec @output.puts red(summary) end @output.flush - dump_pending end def dump_pending @@ -100,13 +92,21 @@ module Spec end protected - + + def colour? + @options.colour ? true : false + end + + def dry_run? + @options.dry_run ? true : false + end + def backtrace_line(line) line.sub(/\A([^:]+:\d+)$/, '\\1:') end def colour(text, colour_code) - return text unless @colour && output_to_tty? + return text unless colour? && output_to_tty? "#{colour_code}#{text}\e[0m" end diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/failing_behaviours_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/failing_behaviours_formatter.rb deleted file mode 100644 index 2b3940fd3..000000000 --- a/vendor/plugins/rspec/lib/spec/runner/formatter/failing_behaviours_formatter.rb +++ /dev/null @@ -1,29 +0,0 @@ -module Spec - module Runner - module Formatter - class FailingBehavioursFormatter < BaseTextFormatter - def add_behaviour(behaviour_name) - if behaviour_name =~ /(.*) \(druby.*\)$/ - @behaviour_name = $1 - else - @behaviour_name = behaviour_name - end - end - - def example_failed(example, counter, failure) - unless @behaviour_name.nil? - @output.puts @behaviour_name - @behaviour_name = nil - @output.flush - end - end - - def dump_failure(counter, failure) - end - - def dump_summary(duration, example_count, failure_count, pending_count) - end - end - end - end -end diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/failing_examples_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/failing_examples_formatter.rb index 9728deaf0..e3a271c8b 100644 --- a/vendor/plugins/rspec/lib/spec/runner/formatter/failing_examples_formatter.rb +++ b/vendor/plugins/rspec/lib/spec/runner/formatter/failing_examples_formatter.rb @@ -1,13 +1,11 @@ +require 'spec/runner/formatter/base_text_formatter' + module Spec module Runner module Formatter class FailingExamplesFormatter < BaseTextFormatter - def add_behaviour(behaviour_name) - @behaviour_name = behaviour_name - end - def example_failed(example, counter, failure) - @output.puts "#{@behaviour_name} #{example.description}" + @output.puts "#{example_group.description} #{example.description}" @output.flush end diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/html_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/html_formatter.rb index d9c422e55..ad153c8dc 100644 --- a/vendor/plugins/rspec/lib/spec/runner/formatter/html_formatter.rb +++ b/vendor/plugins/rspec/lib/spec/runner/formatter/html_formatter.rb @@ -1,4 +1,5 @@ require 'erb' +require 'spec/runner/formatter/base_text_formatter' module Spec module Runner @@ -6,15 +7,15 @@ module Spec class HtmlFormatter < BaseTextFormatter include ERB::Util # for the #h method - def initialize(output) + def initialize(options, output) super - @current_behaviour_number = 0 + @current_example_group_number = 0 @current_example_number = 0 end - # The number of the currently running behaviour - def current_behaviour_number - @current_behaviour_number + # The number of the currently running example_group + def current_example_group_number + @current_example_group_number end # The number of the currently running example (a global counter) @@ -30,17 +31,18 @@ module Spec @output.flush end - def add_behaviour(name) - @behaviour_red = false - @behaviour_red = false - @current_behaviour_number += 1 - unless current_behaviour_number == 1 + def add_example_group(example_group) + super + @example_group_red = false + @example_group_red = false + @current_example_group_number += 1 + unless current_example_group_number == 1 @output.puts " </dl>" @output.puts "</div>" end - @output.puts "<div class=\"behaviour\">" + @output.puts "<div class=\"example_group\">" @output.puts " <dl>" - @output.puts " <dt id=\"behaviour_#{current_behaviour_number}\">#{h(name)}</dt>" + @output.puts " <dt id=\"example_group_#{current_example_group_number}\">#{h(example_group.description)}</dt>" @output.flush end @@ -51,7 +53,7 @@ module Spec end def example_started(example) - @current_example_number = example.number + @current_example_number += 1 end def example_passed(example) @@ -65,8 +67,8 @@ module Spec failure_style = failure.pending_fixed? ? 'pending_fixed' : 'failed' @output.puts " <script type=\"text/javascript\">makeRed('rspec-header');</script>" unless @header_red @header_red = true - @output.puts " <script type=\"text/javascript\">makeRed('behaviour_#{current_behaviour_number}');</script>" unless @behaviour_red - @behaviour_red = true + @output.puts " <script type=\"text/javascript\">makeRed('example_group_#{current_example_group_number}');</script>" unless @example_group_red + @example_group_red = true move_progress @output.puts " <dd class=\"spec #{failure_style}\">" @output.puts " <span class=\"failed_spec_name\">#{h(example.description)}</span>" @@ -79,11 +81,11 @@ module Spec @output.flush end - def example_pending(behaviour_name, example_name, message) + def example_pending(example_group_description, example, message) @output.puts " <script type=\"text/javascript\">makeYellow('rspec-header');</script>" unless @header_red - @output.puts " <script type=\"text/javascript\">makeYellow('behaviour_#{current_behaviour_number}');</script>" unless @behaviour_red + @output.puts " <script type=\"text/javascript\">makeYellow('example_group_#{current_example_group_number}');</script>" unless @example_group_red move_progress - @output.puts " <dd class=\"spec not_implemented\"><span class=\"not_implemented_spec_name\">#{h(example_name)}</span></dd>" + @output.puts " <dd class=\"spec not_implemented\"><span class=\"not_implemented_spec_name\">#{h(example.description)} (PENDING: #{h(message)})</span></dd>" @output.flush end @@ -91,20 +93,29 @@ module Spec # could output links to images or other files produced during the specs. # def extra_failure_content(failure) + require 'spec/runner/formatter/snippet_extractor' + @snippet_extractor ||= SnippetExtractor.new " <pre class=\"ruby\"><code>#{@snippet_extractor.snippet(failure.exception)}</code></pre>" end def move_progress - percent_done = @example_count == 0 ? 100.0 : ((current_example_number + 1).to_f / @example_count.to_f * 1000).to_i / 10.0 @output.puts " <script type=\"text/javascript\">moveProgressBar('#{percent_done}');</script>" @output.flush end + def percent_done + result = 100.0 + if @example_count != 0 + result = ((current_example_number).to_f / @example_count.to_f * 1000).to_i / 10.0 + end + result + end + def dump_failure(counter, failure) end def dump_summary(duration, example_count, failure_count, pending_count) - if @dry_run + if dry_run? totals = "This was a dry-run" else totals = "#{example_count} example#{'s' unless example_count == 1}, #{failure_count} failure#{'s' unless failure_count == 1}" @@ -121,15 +132,14 @@ module Spec def html_header <<-EOF -<?xml version="1.0" encoding="iso-8859-1"?> -<!DOCTYPE html - PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <title>RSpec results</title> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Expires" content="-1" /> <meta http-equiv="Pragma" content="no-cache" /> <style type="text/css"> @@ -225,7 +235,7 @@ EOF font-size: 1.2em; } -.behaviour { +.example_group { margin: 0 10px 5px; background: #fff; } diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/progress_bar_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/progress_bar_formatter.rb index 624f06e7c..8d0e50432 100644 --- a/vendor/plugins/rspec/lib/spec/runner/formatter/progress_bar_formatter.rb +++ b/vendor/plugins/rspec/lib/spec/runner/formatter/progress_bar_formatter.rb @@ -1,10 +1,9 @@ +require 'spec/runner/formatter/base_text_formatter' + module Spec module Runner module Formatter class ProgressBarFormatter < BaseTextFormatter - def add_behaviour(name) - end - def example_failed(example, counter, failure) @output.print colourise('F', failure) @output.flush @@ -15,7 +14,7 @@ module Spec @output.flush end - def example_pending(behaviour_name, example_name, message) + def example_pending(example_group_description, example, message) super @output.print yellow('P') @output.flush diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/rdoc_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/rdoc_formatter.rb deleted file mode 100644 index 0fd22ba6c..000000000 --- a/vendor/plugins/rspec/lib/spec/runner/formatter/rdoc_formatter.rb +++ /dev/null @@ -1,24 +0,0 @@ -module Spec - module Runner - module Formatter - class RdocFormatter < BaseTextFormatter - def add_behaviour(name) - @output.puts "# #{name}" - end - - def example_passed(example) - @output.puts "# * #{example.description}" - @output.flush - end - - def example_failed(example, counter, failure) - @output.puts "# * #{example.description} [#{counter} - FAILED]" - end - - def example_pending(behaviour_name, example_name, message) - @output.puts "# * #{behaviour_name} #{example_name} [PENDING: #{message}]" - end - end - end - end -end diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/specdoc_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/specdoc_formatter.rb index ad794b238..f426dc948 100644 --- a/vendor/plugins/rspec/lib/spec/runner/formatter/specdoc_formatter.rb +++ b/vendor/plugins/rspec/lib/spec/runner/formatter/specdoc_formatter.rb @@ -1,27 +1,37 @@ +require 'spec/runner/formatter/base_text_formatter' + module Spec module Runner module Formatter - class SpecdocFormatter < BaseTextFormatter - def add_behaviour(name) - @output.puts - @output.puts name - @output.flush + class SpecdocFormatter < BaseTextFormatter + def add_example_group(example_group) + super + output.puts + output.puts example_group.description + output.flush end def example_failed(example, counter, failure) - @output.puts failure.expectation_not_met? ? red("- #{example.description} (FAILED - #{counter})") : magenta("- #{example.description} (ERROR - #{counter})") - @output.flush + message = if failure.expectation_not_met? + "- #{example.description} (FAILED - #{counter})" + else + "- #{example.description} (ERROR - #{counter})" + end + + output.puts(failure.expectation_not_met? ? red(message) : magenta(message)) + output.flush end - + def example_passed(example) - @output.puts green("- #{example.description}") - @output.flush + message = "- #{example.description}" + output.puts green(message) + output.flush end - def example_pending(behaviour_name, example_name, message) + def example_pending(example_group_description, example, message) super - @output.puts yellow("- #{example_name} (PENDING: #{message})") - @output.flush + output.puts yellow("- #{example.description} (PENDING: #{message})") + output.flush end end end diff --git a/vendor/plugins/rspec/lib/spec/runner/heckle_runner.rb b/vendor/plugins/rspec/lib/spec/runner/heckle_runner.rb index b6de4ef73..7695fe794 100644 --- a/vendor/plugins/rspec/lib/spec/runner/heckle_runner.rb +++ b/vendor/plugins/rspec/lib/spec/runner/heckle_runner.rb @@ -13,9 +13,9 @@ module Spec @heckle_class = heckle_class end - # Runs all the contexts held by +behaviour_runner+ once for each of the + # Runs all the example groups held by +rspec_options+ once for each of the # methods in the matched classes. - def heckle_with(behaviour_runner) + def heckle_with if @filter =~ /(.*)[#\.](.*)/ heckle_method($1, $2) else @@ -25,7 +25,7 @@ module Spec def heckle_method(class_name, method_name) verify_constant(class_name) - heckle = @heckle_class.new(class_name, method_name, behaviour_runner) + heckle = @heckle_class.new(class_name, method_name, rspec_options) heckle.validate end @@ -39,7 +39,7 @@ module Spec classes.each do |klass| klass.instance_methods(false).each do |method_name| - heckle = @heckle_class.new(klass.name, method_name, behaviour_runner) + heckle = @heckle_class.new(klass.name, method_name, rspec_options) heckle.validate end end @@ -57,16 +57,16 @@ module Spec #Supports Heckle 1.2 and prior (earlier versions used Heckle::Base) class Heckler < (Heckle.const_defined?(:Base) ? Heckle::Base : Heckle) - def initialize(klass_name, method_name, behaviour_runner) + def initialize(klass_name, method_name, rspec_options) super(klass_name, method_name) - @behaviour_runner = behaviour_runner + @rspec_options = rspec_options end def tests_pass? - paths = [] # We can pass an empty array of paths - our specs are already loaded. - failure_count = @behaviour_runner.run(paths, false) - failure_count == 0 + success = @rspec_options.run_examples + success end + end end end diff --git a/vendor/plugins/rspec/lib/spec/runner/option_parser.rb b/vendor/plugins/rspec/lib/spec/runner/option_parser.rb index 1facb85a8..09cedccac 100644 --- a/vendor/plugins/rspec/lib/spec/runner/option_parser.rb +++ b/vendor/plugins/rspec/lib/spec/runner/option_parser.rb @@ -3,23 +3,18 @@ require 'stringio' module Spec module Runner - class OptionParser - BUILT_IN_FORMATTERS = { - 'specdoc' => Formatter::SpecdocFormatter, - 's' => Formatter::SpecdocFormatter, - 'html' => Formatter::HtmlFormatter, - 'h' => Formatter::HtmlFormatter, - 'rdoc' => Formatter::RdocFormatter, - 'r' => Formatter::RdocFormatter, - 'progress' => Formatter::ProgressBarFormatter, - 'p' => Formatter::ProgressBarFormatter, - 'failing_examples' => Formatter::FailingExamplesFormatter, - 'e' => Formatter::FailingExamplesFormatter, - 'failing_behaviours' => Formatter::FailingBehavioursFormatter, - 'b' => Formatter::FailingBehavioursFormatter - } + class OptionParser < ::OptionParser + class << self + def parse(args, err, out) + parser = new(err, out) + parser.parse(args) + parser.options + end + end + + attr_reader :options - COMMAND_LINE = { + OPTIONS = { :diff => ["-D", "--diff [FORMAT]", "Show diff of objects that are expected to be equal when they are not", "Builtin formats: unified|u|context|c", "You can also specify a custom differ class", @@ -43,13 +38,17 @@ module Spec "not specified. The --format option may be specified several times", "if you want several outputs", " ", - "Builtin formats: ", - "progress|p : Text progress", - "specdoc|s : Behaviour doc as text", - "rdoc|r : Behaviour doc as RDoc", + "Builtin formats for examples: ", + "progress|p : Text progress", + "profile|o : Text progress with profiling of 10 slowest examples", + "specdoc|s : Example doc as text", + "html|h : A nice HTML report", + "failing_examples|e : Write all failing examples - input for --example", + "failing_example_groups|g : Write all failing example groups - input for --example", + " ", + "Builtin formats for stories: ", + "plain|p : Plain Text", "html|h : A nice HTML report", - "failing_examples|e : Write all failing examples - input for --example", - "failing_behaviours|b : Write all failing behaviours - input for --example", " ", "FORMAT can also be the name of a custom formatter class", "(in which case you should also specify --require to load it)"], @@ -73,155 +72,158 @@ module Spec :dry_run => ["-d", "--dry-run", "Invokes formatters without executing the examples."], :options_file => ["-O", "--options PATH", "Read options from a file"], :generate_options => ["-G", "--generate-options PATH", "Generate an options file for --options"], - :runner => ["-U", "--runner RUNNER", "Use a custom BehaviourRunner."], + :runner => ["-U", "--runner RUNNER", "Use a custom Runner."], :drb => ["-X", "--drb", "Run examples via DRb. (For example against script/spec_server)"], :version => ["-v", "--version", "Show version"], :help => ["-h", "--help", "You're looking at it"] } - def initialize + def initialize(err, out) + super() + @error_stream = err + @out_stream = out + @options = Options.new(@error_stream, @out_stream) + @spec_parser = SpecParser.new @file_factory = File - end - - def create_behaviour_runner(args, err, out, warn_if_no_files) - options = parse(args, err, out, warn_if_no_files) - # Some exit points in parse (--generate-options, --drb) don't return the options, - # but hand over control. In that case we don't want to continue. - return nil unless options.is_a?(Options) - options.configure - options.behaviour_runner - end - - def parse(args, err, out, warn_if_no_files) - options_file = nil - args_copy = args.dup - options = Options.new(err, out) - - opts = ::OptionParser.new do |opts| - opts.banner = "Usage: spec (FILE|DIRECTORY|GLOB)+ [options]" - opts.separator "" - - def opts.rspec_on(name, &block) - on(*COMMAND_LINE[name], &block) - end - - opts.rspec_on(:diff) {|diff| options.parse_diff(diff)} - - opts.rspec_on(:colour) {options.colour = true} - - opts.rspec_on(:example) {|example| options.parse_example(example)} - - opts.rspec_on(:specification) {|example| options.parse_example(example)} - - opts.rspec_on(:line) {|line_number| options.line_number = line_number.to_i} - - opts.rspec_on(:format) {|format| options.parse_format(format)} - - opts.rspec_on(:require) {|req| options.parse_require(req)} - - opts.rspec_on(:backtrace) {options.backtrace_tweaker = NoisyBacktraceTweaker.new} - - opts.rspec_on(:loadby) {|loadby| options.loadby = loadby} - - opts.rspec_on(:reverse) {options.reverse = true} - - opts.rspec_on(:timeout) {|timeout| options.timeout = timeout.to_f} - - opts.rspec_on(:heckle) {|heckle| options.parse_heckle(heckle)} - - opts.rspec_on(:dry_run) {options.dry_run = true} - opts.rspec_on(:options_file) do |options_file| - return parse_options_file(options_file, out, err, args_copy, warn_if_no_files) - end - - opts.rspec_on(:generate_options) do |options_file| - options.parse_generate_options(options_file, args_copy, out) - end - - opts.rspec_on(:runner) do |runner| - options.runner_arg = runner - end - - opts.rspec_on(:drb) do - return parse_drb(args_copy, out, err, warn_if_no_files) - end - - opts.rspec_on(:version) {parse_version(out)} - - opts.on_tail(*COMMAND_LINE[:help]) {parse_help(opts, out)} + self.banner = "Usage: spec (FILE|DIRECTORY|GLOB)+ [options]" + self.separator "" + on(*OPTIONS[:diff]) {|diff| @options.parse_diff(diff)} + on(*OPTIONS[:colour]) {@options.colour = true} + on(*OPTIONS[:example]) {|example| @options.parse_example(example)} + on(*OPTIONS[:specification]) {|example| @options.parse_example(example)} + on(*OPTIONS[:line]) {|line_number| @options.line_number = line_number.to_i} + on(*OPTIONS[:format]) {|format| @options.parse_format(format)} + on(*OPTIONS[:require]) {|requires| invoke_requires(requires)} + on(*OPTIONS[:backtrace]) {@options.backtrace_tweaker = NoisyBacktraceTweaker.new} + on(*OPTIONS[:loadby]) {|loadby| @options.loadby = loadby} + on(*OPTIONS[:reverse]) {@options.reverse = true} + on(*OPTIONS[:timeout]) {|timeout| @options.timeout = timeout.to_f} + on(*OPTIONS[:heckle]) {|heckle| @options.load_heckle_runner(heckle)} + on(*OPTIONS[:dry_run]) {@options.dry_run = true} + on(*OPTIONS[:options_file]) {|options_file| parse_options_file(options_file)} + on(*OPTIONS[:generate_options]) do |options_file| end - opts.parse!(args) - - if args.empty? && warn_if_no_files - err.puts "No files specified." - err.puts opts - exit(6) if err == $stderr + on(*OPTIONS[:runner]) do |runner| + @options.user_input_for_runner = runner end + on(*OPTIONS[:drb]) {} + on(*OPTIONS[:version]) {parse_version} + on_tail(*OPTIONS[:help]) {parse_help} + end - if options.line_number - set_spec_from_line_number(options, args, err) + def order!(argv, &blk) + @argv = argv + @options.argv = @argv.dup + return if parse_generate_options + return if parse_drb + + super(@argv) do |file| + @options.files << file + blk.call(file) if blk end - if options.formatters.empty? - options.formatters << Formatter::ProgressBarFormatter.new(out) + if @options.line_number + set_spec_from_line_number end - options + @options end - def parse_options_file(options_file, out_stream, error_stream, args_copy, warn_if_no_files) - # Remove the --options option and the argument before writing to file - index = args_copy.index("-O") || args_copy.index("--options") - args_copy.delete_at(index) - args_copy.delete_at(index) - - new_args = args_copy + IO.readlines(options_file).map {|l| l.chomp.split " "}.flatten - return CommandLine.run(new_args, error_stream, out_stream, true, warn_if_no_files) + protected + def invoke_requires(requires) + requires.split(",").each do |file| + require file + end + end + + def parse_options_file(options_file) + option_file_args = IO.readlines(options_file).map {|l| l.chomp.split " "}.flatten + @argv.push(*option_file_args) end - def parse_drb(args_copy, out_stream, error_stream, warn_if_no_files) - # Remove the --drb option - index = args_copy.index("-X") || args_copy.index("--drb") - args_copy.delete_at(index) + def parse_generate_options + # Remove the --generate-options option and the argument before writing to file + options_file = nil + ['-G', '--generate-options'].each do |option| + if index = @argv.index(option) + @argv.delete_at(index) + options_file = @argv.delete_at(index) + end + end + + if options_file + write_generated_options(options_file) + return true + else + return false + end + end + + def write_generated_options(options_file) + File.open(options_file, 'w') do |io| + io.puts @argv.join("\n") + end + @out_stream.puts "\nOptions written to #{options_file}. You can now use these options with:" + @out_stream.puts "spec --options #{options_file}" + @options.examples_should_not_be_run + end - return DrbCommandLine.run(args_copy, error_stream, out_stream, true, warn_if_no_files) + def parse_drb + is_drb = false + argv = @options.argv + is_drb ||= argv.delete(OPTIONS[:drb][0]) + is_drb ||= argv.delete(OPTIONS[:drb][1]) + return nil unless is_drb + @options.examples_should_not_be_run + DrbCommandLine.run( + self.class.parse(argv, @error_stream, @out_stream) + ) + true end - def parse_version(out_stream) - out_stream.puts ::Spec::VERSION::DESCRIPTION - exit if out_stream == $stdout + def parse_version + @out_stream.puts ::Spec::VERSION::DESCRIPTION + exit if stdout? end - def parse_help(opts, out_stream) - out_stream.puts opts - exit if out_stream == $stdout + def parse_help + @out_stream.puts self + exit if stdout? end - def set_spec_from_line_number(options, args, err) - if options.examples.empty? - if args.length == 1 - if @file_factory.file?(args[0]) - source = @file_factory.open(args[0]) - example = @spec_parser.spec_name_for(source, options.line_number) - options.parse_example(example) - elsif @file_factory.directory?(args[0]) - err.puts "You must specify one file, not a directory when using the --line option" - exit(1) if err == $stderr + def set_spec_from_line_number + if @options.examples.empty? + if @options.files.length == 1 + if @file_factory.file?(@options.files[0]) + source = @file_factory.open(@options.files[0]) + example = @spec_parser.spec_name_for(source, @options.line_number) + @options.parse_example(example) + elsif @file_factory.directory?(@options.files[0]) + @error_stream.puts "You must specify one file, not a directory when using the --line option" + exit(1) if stderr? else - err.puts "#{args[0]} does not exist" - exit(2) if err == $stderr + @error_stream.puts "#{@options.files[0]} does not exist" + exit(2) if stderr? end else - err.puts "Only one file can be specified when using the --line option: #{args.inspect}" - exit(3) if err == $stderr + @error_stream.puts "Only one file can be specified when using the --line option: #{@options.files.inspect}" + exit(3) if stderr? end else - err.puts "You cannot use both --line and --example" - exit(4) if err == $stderr + @error_stream.puts "You cannot use both --line and --example" + exit(4) if stderr? end end + + def stdout? + @out_stream == $stdout + end + + def stderr? + @error_stream == $stderr + end end end end diff --git a/vendor/plugins/rspec/lib/spec/runner/options.rb b/vendor/plugins/rspec/lib/spec/runner/options.rb index a940133eb..a5a07548d 100644 --- a/vendor/plugins/rspec/lib/spec/runner/options.rb +++ b/vendor/plugins/rspec/lib/spec/runner/options.rb @@ -1,32 +1,40 @@ module Spec module Runner class Options - BUILT_IN_FORMATTERS = { - 'specdoc' => Formatter::SpecdocFormatter, - 's' => Formatter::SpecdocFormatter, - 'html' => Formatter::HtmlFormatter, - 'h' => Formatter::HtmlFormatter, - 'rdoc' => Formatter::RdocFormatter, - 'r' => Formatter::RdocFormatter, - 'progress' => Formatter::ProgressBarFormatter, - 'p' => Formatter::ProgressBarFormatter, - 'failing_examples' => Formatter::FailingExamplesFormatter, - 'e' => Formatter::FailingExamplesFormatter, - 'failing_behaviours' => Formatter::FailingBehavioursFormatter, - 'b' => Formatter::FailingBehavioursFormatter + FILE_SORTERS = { + 'mtime' => lambda {|file_a, file_b| File.mtime(file_b) <=> File.mtime(file_a)} } - + + EXAMPLE_FORMATTERS = { # Load these lazily for better speed + 'specdoc' => ['spec/runner/formatter/specdoc_formatter', 'Formatter::SpecdocFormatter'], + 's' => ['spec/runner/formatter/specdoc_formatter', 'Formatter::SpecdocFormatter'], + 'html' => ['spec/runner/formatter/html_formatter', 'Formatter::HtmlFormatter'], + 'h' => ['spec/runner/formatter/html_formatter', 'Formatter::HtmlFormatter'], + 'progress' => ['spec/runner/formatter/progress_bar_formatter', 'Formatter::ProgressBarFormatter'], + 'p' => ['spec/runner/formatter/progress_bar_formatter', 'Formatter::ProgressBarFormatter'], + 'failing_examples' => ['spec/runner/formatter/failing_examples_formatter', 'Formatter::FailingExamplesFormatter'], + 'e' => ['spec/runner/formatter/failing_examples_formatter', 'Formatter::FailingExamplesFormatter'], +'failing_example_groups' => ['spec/runner/formatter/failing_example_groups_formatter', 'Formatter::FailingExampleGroupsFormatter'], + 'g' => ['spec/runner/formatter/failing_example_groups_formatter', 'Formatter::FailingExampleGroupsFormatter'], + 'profile' => ['spec/runner/formatter/profile_formatter', 'Formatter::ProfileFormatter'], + 'o' => ['spec/runner/formatter/profile_formatter', 'Formatter::ProfileFormatter'], + 'textmate' => ['spec/runner/formatter/text_mate_formatter', 'Formatter::TextMateFormatter'] + } + + STORY_FORMATTERS = { + 'plain' => ['spec/runner/formatter/story/plain_text_formatter', 'Formatter::Story::PlainTextFormatter'], + 'p' => ['spec/runner/formatter/story/plain_text_formatter', 'Formatter::Story::PlainTextFormatter'], + 'html' => ['spec/runner/formatter/story/html_formatter', 'Formatter::Story::HtmlFormatter'], + 'h' => ['spec/runner/formatter/story/html_formatter', 'Formatter::Story::HtmlFormatter'] + } + attr_accessor( :backtrace_tweaker, - :colour, :context_lines, :diff_format, - :differ_class, :dry_run, + :profile, :examples, - :failure_file, - :formatters, - :generate, :heckle_runner, :line_number, :loadby, @@ -34,69 +42,83 @@ module Spec :reverse, :timeout, :verbose, - :runner_arg, - :behaviour_runner + :user_input_for_runner, + :error_stream, + :output_stream, + # TODO: BT - Figure out a better name + :argv ) + attr_reader :colour, :differ_class, :files, :example_groups - def initialize(err, out) - @err, @out = err, out + def initialize(error_stream, output_stream) + @error_stream = error_stream + @output_stream = output_stream @backtrace_tweaker = QuietBacktraceTweaker.new @examples = [] - @formatters = [] @colour = false + @profile = false @dry_run = false + @reporter = Reporter.new(self) + @context_lines = 3 + @diff_format = :unified + @files = [] + @example_groups = [] + @examples_run = false + @examples_should_be_run = nil + @user_input_for_runner = nil end - def configure - configure_formatters - create_reporter - configure_differ - create_behaviour_runner + def add_example_group(example_group) + @example_groups << example_group end - def create_behaviour_runner - return nil if @generate - @behaviour_runner = if @runner_arg - klass_name, arg = split_at_colon(@runner_arg) - runner_type = load_class(klass_name, 'behaviour runner', '--runner') - runner_type.new(self, arg) - else - BehaviourRunner.new(self) - end + def remove_example_group(example_group) + @example_groups.delete(example_group) end - def configure_formatters - @formatters.each do |formatter| - formatter.colour = @colour if formatter.respond_to?(:colour=) - formatter.dry_run = @dry_run if formatter.respond_to?(:dry_run=) + def run_examples + return true unless examples_should_be_run? + runner = custom_runner || ExampleGroupRunner.new(self) + + runner.load_files(files_to_load) + if example_groups.empty? + true + else + success = runner.run + @examples_run = true + heckle if heckle_runner + success end end - def create_reporter - @reporter = Reporter.new(@formatters, @backtrace_tweaker) + def examples_run? + @examples_run end - def configure_differ - if @differ_class - Spec::Expectations.differ = @differ_class.new(@diff_format, @context_lines, @colour) + def examples_should_not_be_run + @examples_should_be_run = false + end + + def colour=(colour) + @colour = colour + begin; \ + require 'Win32/Console/ANSI' if @colour && PLATFORM =~ /win32/; \ + rescue LoadError ; \ + raise "You must gem install win32console to use colour on Windows" ; \ end end def parse_diff(format) - @context_lines = 3 case format - when :context, 'context', 'c' - @diff_format = :context - when :unified, 'unified', 'u', '', nil - @diff_format = :unified - end - - if [:context,:unified].include? @diff_format - require 'spec/expectations/differs/default' - @differ_class = Spec::Expectations::Differs::Default + when :context, 'context', 'c' + @diff_format = :context + default_differ + when :unified, 'unified', 'u', '', nil + @diff_format = :unified + default_differ else @diff_format = :custom - @differ_class = load_class(format, 'differ', '--diff') + self.differ_class = load_class(format, 'differ', '--diff') end end @@ -109,67 +131,123 @@ module Spec end def parse_format(format_arg) - format, where = split_at_colon(format_arg) - # This funky regexp checks whether we have a FILE_NAME or not - if where.nil? + format, where = ClassAndArgumentsParser.parse(format_arg) + unless where raise "When using several --format options only one of them can be without a file" if @out_used - where = @out + where = @output_stream @out_used = true end - - formatter_type = BUILT_IN_FORMATTERS[format] || load_class(format, 'formatter', '--format') - @formatters << formatter_type.new(where) + @format_options ||= [] + @format_options << [format, where] + end + + def formatters + @format_options ||= [['progress', @output_stream]] + @formatters ||= load_formatters(@format_options, EXAMPLE_FORMATTERS) end - def parse_require(req) - req.split(",").each{|file| require file} + def story_formatters + @format_options ||= [['plain', @output_stream]] + @formatters ||= load_formatters(@format_options, STORY_FORMATTERS) + end + + def load_formatters(format_options, formatters) + format_options.map do |format, where| + formatter_type = if formatters[format] + require formatters[format][0] + eval(formatters[format][1], binding, __FILE__, __LINE__) + else + load_class(format, 'formatter', '--format') + end + formatter_type.new(self, where) + end end - def parse_heckle(heckle) - heckle_require = [/mswin/, /java/].detect{|p| p =~ RUBY_PLATFORM} ? 'spec/runner/heckle_runner_unsupported' : 'spec/runner/heckle_runner' - require heckle_require + def load_heckle_runner(heckle) + suffix = [/mswin/, /java/].detect{|p| p =~ RUBY_PLATFORM} ? '_unsupported' : '' + require "spec/runner/heckle_runner#{suffix}" @heckle_runner = HeckleRunner.new(heckle) end - def parse_generate_options(options_file, args_copy, out_stream) - # Remove the --generate-options option and the argument before writing to file - index = args_copy.index("-G") || args_copy.index("--generate-options") - args_copy.delete_at(index) - args_copy.delete_at(index) - File.open(options_file, 'w') do |io| - io.puts args_copy.join("\n") + def number_of_examples + @example_groups.inject(0) do |sum, example_group| + sum + example_group.number_of_examples end - out_stream.puts "\nOptions written to #{options_file}. You can now use these options with:" - out_stream.puts "spec --options #{options_file}" - @generate = true end - def split_at_colon(s) - if s =~ /([a-zA-Z_]+(?:::[a-zA-Z_]+)*):?(.*)/ - arg = $2 == "" ? nil : $2 - [$1, arg] - else - raise "Couldn't parse #{s.inspect}" - end + protected + def examples_should_be_run? + return @examples_should_be_run unless @examples_should_be_run.nil? + @examples_should_be_run = true end + def differ_class=(klass) + return unless klass + @differ_class = klass + Spec::Expectations.differ = self.differ_class.new(self) + end + def load_class(name, kind, option) if name =~ /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ arg = $2 == "" ? nil : $2 [$1, arg] else m = "#{name.inspect} is not a valid class name" - @err.puts m + @error_stream.puts m raise m end begin eval(name, binding, __FILE__, __LINE__) rescue NameError => e - @err.puts "Couldn't find #{kind} class #{name}" - @err.puts "Make sure the --require option is specified *before* #{option}" + @error_stream.puts "Couldn't find #{kind} class #{name}" + @error_stream.puts "Make sure the --require option is specified *before* #{option}" if $_spec_spec ; raise e ; else exit(1) ; end end end + + def files_to_load + result = [] + sorted_files.each do |file| + if test ?d, file + result += Dir[File.expand_path("#{file}/**/*.rb")] + elsif test ?f, file + result << file + else + raise "File or directory not found: #{file}" + end + end + result + end + + def custom_runner + return nil unless custom_runner? + klass_name, arg = ClassAndArgumentsParser.parse(user_input_for_runner) + runner_type = load_class(klass_name, 'behaviour runner', '--runner') + return runner_type.new(self, arg) + end + + def custom_runner? + return user_input_for_runner ? true : false + end + + def heckle + returns = self.heckle_runner.heckle_with + self.heckle_runner = nil + returns + end + + def sorted_files + return sorter ? files.sort(&sorter) : files + end + + def sorter + FILE_SORTERS[loadby] + end + + def default_differ + require 'spec/expectations/differs/default' + self.differ_class = Spec::Expectations::Differs::Default + end end end end diff --git a/vendor/plugins/rspec/lib/spec/runner/reporter.rb b/vendor/plugins/rspec/lib/spec/runner/reporter.rb index b1dc2a27a..cfc511baf 100644 --- a/vendor/plugins/rspec/lib/spec/runner/reporter.rb +++ b/vendor/plugins/rspec/lib/spec/runner/reporter.rb @@ -1,40 +1,52 @@ module Spec module Runner class Reporter + attr_reader :options, :example_groups - def initialize(formatters, backtrace_tweaker) - @formatters = formatters - @backtrace_tweaker = backtrace_tweaker - clear! + def initialize(options) + @options = options + @options.reporter = self + clear end - def add_behaviour(name) - @formatters.each{|f| f.add_behaviour(name)} - @behaviour_names << name + def add_example_group(example_group) + formatters.each do |f| + f.add_example_group(example_group) + end + example_groups << example_group end - def example_started(name) - @formatters.each{|f| f.example_started(name)} + def example_started(example) + formatters.each{|f| f.example_started(example)} end - def example_finished(name, error=nil, failure_location=nil, not_implemented = false) - @example_names << name + def example_finished(example, error=nil) + @examples << example - if not_implemented - example_pending(@behaviour_names.last, name) - elsif error.nil? - example_passed(name) - elsif Spec::DSL::ExamplePendingError === error - example_pending(@behaviour_names.last, name, error.message) + if error.nil? + example_passed(example) + elsif Spec::Example::ExamplePendingError === error + example_pending(example_groups.last, example, error.message) else - example_failed(name, error, failure_location) + example_failed(example, error) + end + end + + def failure(example, error) + backtrace_tweaker.tweak_backtrace(error) + example_name = "#{example_groups.last.description} #{example.description}" + failure = Failure.new(example_name, error) + @failures << failure + formatters.each do |f| + f.example_failed(example, @failures.length, failure) end end + alias_method :example_failed, :failure def start(number_of_examples) - clear! + clear @start_time = Time.new - @formatters.each{|f| f.start(number_of_examples)} + formatters.each{|f| f.start(number_of_examples)} end def end @@ -43,22 +55,31 @@ module Spec # Dumps the summary and returns the total number of failures def dump - @formatters.each{|f| f.start_dump} + formatters.each{|f| f.start_dump} + dump_pending dump_failures - @formatters.each do |f| - f.dump_summary(duration, @example_names.length, @failures.length, @pending_count) + formatters.each do |f| + f.dump_summary(duration, @examples.length, @failures.length, @pending_count) f.close end @failures.length end private + + def formatters + @options.formatters + end + + def backtrace_tweaker + @options.backtrace_tweaker + end - def clear! - @behaviour_names = [] + def clear + @example_groups = [] @failures = [] @pending_count = 0 - @example_names = [] + @examples = [] @start_time = nil @end_time = nil end @@ -66,31 +87,28 @@ module Spec def dump_failures return if @failures.empty? @failures.inject(1) do |index, failure| - @formatters.each{|f| f.dump_failure(index, failure)} + formatters.each{|f| f.dump_failure(index, failure)} index + 1 end end + def dump_pending + formatters.each{|f| f.dump_pending} + end def duration return @end_time - @start_time unless (@end_time.nil? or @start_time.nil?) return "0.0" end - def example_passed(name) - @formatters.each{|f| f.example_passed(name)} - end - - def example_failed(name, error, failure_location) - @backtrace_tweaker.tweak_backtrace(error, failure_location) - example_name = "#{@behaviour_names.last} #{name}" - failure = Failure.new(example_name, error) - @failures << failure - @formatters.each{|f| f.example_failed(name, @failures.length, failure)} + def example_passed(example) + formatters.each{|f| f.example_passed(example)} end - def example_pending(behaviour_name, example_name, message="Not Yet Implemented") + def example_pending(example_group, example, message="Not Yet Implemented") @pending_count += 1 - @formatters.each{|f| f.example_pending(behaviour_name, example_name, message)} + formatters.each do |f| + f.example_pending(example_group.description, example, message) + end end class Failure @@ -112,7 +130,7 @@ module Spec end def pending_fixed? - @exception.is_a?(Spec::DSL::PendingFixedError) + @exception.is_a?(Spec::Example::PendingExampleFixedError) end def expectation_not_met? diff --git a/vendor/plugins/rspec/lib/spec/runner/spec_parser.rb b/vendor/plugins/rspec/lib/spec/runner/spec_parser.rb index bc9170065..5ce51e3b2 100644 --- a/vendor/plugins/rspec/lib/spec/runner/spec_parser.rb +++ b/vendor/plugins/rspec/lib/spec/runner/spec_parser.rb @@ -4,12 +4,12 @@ module Spec class SpecParser def spec_name_for(io, line_number) source = io.read - behaviour, behaviour_line = behaviour_at_line(source, line_number) + example_group, example_group_line = example_group_at_line(source, line_number) example, example_line = example_at_line(source, line_number) - if behaviour && example && (behaviour_line < example_line) - "#{behaviour} #{example}" - elsif behaviour - behaviour + if example_group && example && (example_group_line < example_line) + "#{example_group} #{example}" + elsif example_group + example_group else nil end @@ -17,7 +17,7 @@ module Spec protected - def behaviour_at_line(source, line_number) + def example_group_at_line(source, line_number) find_above(source, line_number, /^\s*(context|describe)\s+(.*)\s+do/) end @@ -40,8 +40,11 @@ module Spec def parse_description(str) return str[1..-2] if str =~ /^['"].*['"]$/ - if matches = /^(.*)\s*,\s*['"](.*)['"]$/.match(str) - return ::Spec::DSL::Description.generate_description(matches[1], matches[2]) + if matches = /^['"](.*)['"](,.*)?$/.match(str) + return ::Spec::Example::ExampleGroupMethods.description_text(matches[1]) + end + if matches = /^(.*)\s*,\s*['"](.*)['"](,.*)?$/.match(str) + return ::Spec::Example::ExampleGroupMethods.description_text(matches[1], matches[2]) end return str end |