aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/plugins/rspec/lib/spec/runner
diff options
context:
space:
mode:
authorfrancis <francis>2008-01-23 01:54:49 +0000
committerfrancis <francis>2008-01-23 01:54:49 +0000
commitfdaa98e06ba6d6f8b62480a83e9ecffdbcb21402 (patch)
tree40b8b0d7602a7a17bead44e0fd3a2ea101b18bd6 /vendor/plugins/rspec/lib/spec/runner
parent60eaae4f7df1f1dae91defb87d3707451c359cf4 (diff)
Upgrade to rspec 1.1.2
Diffstat (limited to 'vendor/plugins/rspec/lib/spec/runner')
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/backtrace_tweaker.rb6
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/behaviour_runner.rb123
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/command_line.rb30
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/drb_command_line.rb9
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/extensions/kernel.rb50
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/extensions/object.rb32
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter.rb9
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/base_formatter.rb18
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/base_text_formatter.rb36
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/failing_behaviours_formatter.rb29
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/failing_examples_formatter.rb8
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/html_formatter.rb64
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/progress_bar_formatter.rb7
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/rdoc_formatter.rb24
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/specdoc_formatter.rb36
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/heckle_runner.rb18
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/option_parser.rb278
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/options.rb258
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/reporter.rb98
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/spec_parser.rb19
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