aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/plugins/rspec/lib/spec/runner
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/plugins/rspec/lib/spec/runner')
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/backtrace_tweaker.rb62
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/class_and_arguments_parser.rb16
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/command_line.rb25
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/drb_command_line.rb12
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/example_group_runner.rb10
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/base_formatter.rb106
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/base_text_formatter.rb80
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/failing_example_groups_formatter.rb8
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/html_formatter.rb37
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/nested_text_formatter.rb36
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/profile_formatter.rb4
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/progress_bar_formatter.rb13
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/snippet_extractor.rb2
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/specdoc_formatter.rb12
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/story/html_formatter.rb128
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/story/plain_text_formatter.rb142
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/heckle_runner.rb112
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/heckle_runner_unsupported.rb2
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/option_parser.rb142
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/options.rb189
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/reporter.rb132
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/spec_parser.rb71
22 files changed, 595 insertions, 746 deletions
diff --git a/vendor/plugins/rspec/lib/spec/runner/backtrace_tweaker.rb b/vendor/plugins/rspec/lib/spec/runner/backtrace_tweaker.rb
index 587e57d90..a3cb7d9bd 100644
--- a/vendor/plugins/rspec/lib/spec/runner/backtrace_tweaker.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/backtrace_tweaker.rb
@@ -1,31 +1,53 @@
module Spec
module Runner
class BacktraceTweaker
+ def initialize(*patterns)
+ @ignore_patterns = []
+ end
+
def clean_up_double_slashes(line)
line.gsub!('//','/')
end
- end
- class NoisyBacktraceTweaker < BacktraceTweaker
+ def ignore_patterns(*patterns)
+ # do nothing. Only QuietBacktraceTweaker ignores patterns.
+ end
+
+ def ignored_patterns
+ []
+ end
+
def tweak_backtrace(error)
return if error.backtrace.nil?
- error.backtrace.each do |line|
- clean_up_double_slashes(line)
+ tweaked = error.backtrace.collect do |message|
+ clean_up_double_slashes(message)
+ kept_lines = message.split("\n").select do |line|
+ ignored_patterns.each do |ignore|
+ break if line =~ ignore
+ end
+ end
+ kept_lines.empty?? nil : kept_lines.join("\n")
end
+ error.set_backtrace(tweaked.select {|line| line})
end
end
+ class NoisyBacktraceTweaker < BacktraceTweaker
+ end
+
# Tweaks raised Exceptions to mask noisy (unneeded) parts of the backtrace
class QuietBacktraceTweaker < BacktraceTweaker
unless defined?(IGNORE_PATTERNS)
- root_dir = File.expand_path(File.join(__FILE__, '..', '..', '..', '..'))
- spec_files = Dir["#{root_dir}/lib/*"].map do |path|
- subpath = path[root_dir.length..-1]
+ spec_files = Dir["lib/*"].map do |path|
+ subpath = path[1..-1]
/#{subpath}/
end
IGNORE_PATTERNS = spec_files + [
+ /\/rspec-[^\/]*\/lib\/spec\//,
+ /\/spork-[^\/]*\/lib\/spork\//,
/\/lib\/ruby\//,
/bin\/spec:/,
+ /bin\/spork:/,
/bin\/rcov:/,
/lib\/rspec-rails/,
/vendor\/rails/,
@@ -37,20 +59,18 @@ module Spec
/spec_server/
]
end
-
- def tweak_backtrace(error)
- return if error.backtrace.nil?
- error.backtrace.collect! do |line|
- clean_up_double_slashes(line)
- IGNORE_PATTERNS.each do |ignore|
- if line =~ ignore
- line = nil
- break
- end
- end
- line
- end
- error.backtrace.compact!
+
+ def initialize(*patterns)
+ super
+ ignore_patterns(*patterns)
+ end
+
+ def ignore_patterns(*patterns)
+ @ignore_patterns += patterns.flatten.map { |pattern| Regexp.new(pattern) }
+ end
+
+ def ignored_patterns
+ IGNORE_PATTERNS + @ignore_patterns
end
end
end
diff --git a/vendor/plugins/rspec/lib/spec/runner/class_and_arguments_parser.rb b/vendor/plugins/rspec/lib/spec/runner/class_and_arguments_parser.rb
index 65dc4519c..a49ade26e 100644
--- a/vendor/plugins/rspec/lib/spec/runner/class_and_arguments_parser.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/class_and_arguments_parser.rb
@@ -1,16 +1,14 @@
module Spec
module Runner
class ClassAndArgumentsParser
- class << self
- def parse(s)
- if s =~ /([a-zA-Z_]+(?:::[a-zA-Z_]+)*):?(.*)/
- arg = $2 == "" ? nil : $2
- [$1, arg]
- else
- raise "Couldn't parse #{s.inspect}"
- end
+ def self.parse(s)
+ if s =~ /([a-zA-Z_]+(?:::[a-zA-Z_]+)*):?(.*)/
+ arg = $2 == "" ? nil : $2
+ [$1, arg]
+ else
+ raise "Couldn't parse #{s.inspect}"
end
end
end
end
-end \ No newline at end of file
+end
diff --git a/vendor/plugins/rspec/lib/spec/runner/command_line.rb b/vendor/plugins/rspec/lib/spec/runner/command_line.rb
index 9849c4853..35a7e3159 100644
--- a/vendor/plugins/rspec/lib/spec/runner/command_line.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/command_line.rb
@@ -2,26 +2,13 @@ require 'spec/runner/option_parser'
module Spec
module Runner
- # Facade to run specs without having to fork a new ruby process (using `spec ...`)
class CommandLine
- 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
+ def self.run(tmp_options=Spec::Runner.options)
+ orig_options = Spec::Runner.options
+ Spec::Runner.use tmp_options
+ tmp_options.run_examples
+ ensure
+ Spec::Runner.use orig_options
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 6c340cfea..058a8e1df 100644
--- a/vendor/plugins/rspec/lib/spec/runner/drb_command_line.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/drb_command_line.rb
@@ -8,11 +8,17 @@ module Spec
# CommandLine - making it possible for clients to use both interchangeably.
def self.run(options)
begin
- DRb.start_service
- spec_server = DRbObject.new_with_uri("druby://localhost:8989")
+ begin; \
+ DRb.start_service("druby://localhost:0"); \
+ rescue SocketError; \
+ DRb.start_service("druby://:0"); \
+ end
+ spec_server = DRbObject.new_with_uri("druby://127.0.0.1:8989")
spec_server.run(options.argv, options.error_stream, options.output_stream)
- rescue DRb::DRbConnError => e
+ true
+ rescue DRb::DRbConnError
options.error_stream.puts "No server is running"
+ false
end
end
end
diff --git a/vendor/plugins/rspec/lib/spec/runner/example_group_runner.rb b/vendor/plugins/rspec/lib/spec/runner/example_group_runner.rb
index 7275c6a88..67dc99509 100644
--- a/vendor/plugins/rspec/lib/spec/runner/example_group_runner.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/example_group_runner.rb
@@ -6,6 +6,7 @@ module Spec
end
def load_files(files)
+ $KCODE = 'u' if RUBY_VERSION.to_f < 1.9
# It's important that loading files (or choosing not to) stays the
# responsibility of the ExampleGroupRunner. Some implementations (like)
# the one using DRb may choose *not* to load files, but instead tell
@@ -19,14 +20,15 @@ module Spec
prepare
success = true
example_groups.each do |example_group|
- success = success & example_group.run
+ success = success & example_group.run(@options)
end
return success
ensure
finish
end
- protected
+ protected
+
def prepare
reporter.start(number_of_examples)
example_groups.reverse! if reverse
@@ -53,7 +55,5 @@ module Spec
@options.number_of_examples
end
end
- # TODO: BT - Deprecate BehaviourRunner?
- BehaviourRunner = ExampleGroupRunner
end
-end \ No newline at end of file
+end
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 a1269b513..0fbc12ce4 100644
--- a/vendor/plugins/rspec/lib/spec/runner/formatter/base_formatter.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/formatter/base_formatter.rb
@@ -1,12 +1,29 @@
module Spec
module Runner
module Formatter
- # Baseclass for formatters that implements all required methods as no-ops.
+ # Formatter base-class, which implements all required methods as no-ops, with the exception
class BaseFormatter
- attr_accessor :example_group, :options, :where
- def initialize(options, where)
- @options = options
- @where = where
+ # Formatters are initialized with <tt>options</tt> and <tt>output</tt>
+ # arguments. RSpec's built-in formatters already expect this, and any
+ # custom formatters should as well.
+ #
+ # ==== Parameters
+ # options::
+ # A struct containing boolean values for colour, autospec,
+ # and dry_run
+ # output::
+ # Used by RSpec's built-in formatters to determine where to
+ # write the output. Default is <tt>STDOUT</tt>, otherwise a
+ # filename is expected.
+ #
+ # === Example
+ # If you invoke the <tt>spec</tt> command with:
+ #
+ # --format progress:progress_report.txt
+ #
+ # ... the value of <tt>output</tt> will be progress_report.txt. If you
+ # don't identify an output destination, the default is STDOUT.
+ def initialize(options, output)
end
# This method is invoked before any examples are run, right after
@@ -14,42 +31,77 @@ 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_example_group
+ # is #example_group_started
+ #
+ # ==== Parameters
+ # example_count:: the total number of examples to be run
def start(example_count)
end
- # This method is invoked at the beginning of the execution of each example_group.
- # +example_group+ is the example_group.
+ # This method is invoked at the beginning of the execution of each
+ # example_group. The next method to be invoked after this is
+ # #example_started
#
- # The next method to be invoked after this is #example_failed or #example_finished
- def add_example_group(example_group)
- @example_group = example_group
+ # ==== Parameters
+ # example_group_proxy:: instance of Spec::Example::ExampleGroupProxy
+ def example_group_started(example_group_proxy)
+ end
+
+ # Deprecated - use example_group_started instead
+ def add_example_group(example_group_proxy)
+ Spec.deprecate("BaseFormatter#add_example_group", "BaseFormatter#example_group_started")
+ example_group_started(example_group_proxy)
end
- # This method is invoked when an +example+ starts.
- def example_started(example)
+ # This method is invoked when an +example+ starts. The next method to be
+ # invoked after this is #example_passed, #example_failed, or
+ # #example_pending
+ #
+ # ==== Parameters
+ # example_proxy:: instance of Spec::Example::ExampleProxy
+ def example_started(example_proxy)
end
# This method is invoked when an +example+ passes.
- def example_passed(example)
+ # +example_proxy+ is the same instance of Spec::Example::ExampleProxy
+ # that was passed to example_started
+ #
+ # ==== Parameters
+ # example_proxy:: instance of Spec::Example::ExampleProxy
+ def example_passed(example_proxy)
end
# This method is invoked when an +example+ fails, i.e. an exception occurred
- # inside it (such as a failed should or other exception). +counter+ is the
- # sequence number of the failure (starting at 1) and +failure+ is the associated
- # Failure object.
- def example_failed(example, counter, failure)
+ # inside it (such as a failed should or other exception).
+ #
+ # ==== Parameters
+ # example_proxy::
+ # The same instance of Spec::Example::ExampleProxy that was passed
+ # to <tt>example_started</tt>
+ #
+ # counter:: the sequential number of this failure
+ #
+ # failure:: instance of Spec::Runner::Reporter::Failure
+ def example_failed(example_proxy, counter, failure)
end
# 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.
# +message+ is the message from the ExamplePendingError, if it exists, or the
- # default value of "Not Yet Implemented"
- def example_pending(example, message)
+ # default value of "Not Yet Implemented". +deprecated_pending_location+ is
+ # deprecated - use example_proxy.location instead
+ #
+ # ==== Parameters
+ # example_proxy:: instance of Spec::Example::ExampleProxy
+ # message::
+ # the message passed to the pending message, or an internal
+ # default
+ #
+ def example_pending(example_proxy, message, deprecated_pending_location=nil)
end
# This method is invoked after all of the examples have executed. The next method
- # to be invoked after this one is #dump_failure (once for each failed example),
+ # to be invoked after this one is #dump_failure (once for each failed example)
def start_dump
end
@@ -57,14 +109,24 @@ module Spec
# This method is invoked for each failed example after all examples have run. +counter+ is the sequence number
# of the associated example. +failure+ is a Failure object, which contains detailed
# information about the failure.
+ #
+ # ==== Parameters
+ # counter:: the sequential number of this failure
+ # failure:: instance of Spec::Runner::Reporter::Failure
def dump_failure(counter, failure)
end
# This method is invoked after the dumping of examples and failures.
+ #
+ # ==== Parameters
+ # duration:: the total time for the entire run
+ # example_count:: the number of examples run
+ # failure_count:: the number of examples that failed
+ # pending_count:: the number of examples that are pending
def dump_summary(duration, example_count, failure_count, pending_count)
end
- # This gets invoked after the summary if option is set to do so.
+ # This gets invoked after the summary
def dump_pending
end
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 bad023db7..ee8db75a4 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,4 +1,5 @@
require 'spec/runner/formatter/base_formatter'
+require 'fileutils'
module Spec
module Runner
@@ -7,47 +8,47 @@ module Spec
# non-text based ones too - just ignore the +output+ constructor
# argument.
class BaseTextFormatter < BaseFormatter
- attr_reader :output, :pending_examples
- # Creates a new instance that will write to +where+. If +where+ is a
+ attr_reader :output, :example_group
+ # Creates a new instance that will write to +output+. If +output+ 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(options, where)
- super
- if where.is_a?(String)
- @output = File.open(where, 'w')
- elsif where == STDOUT
- @output = Kernel
- def @output.flush
- STDOUT.flush
- end
+ # +output+ is exected to be an IO (or an object that responds to #puts
+ # and #write).
+ def initialize(options, output)
+ @options = options
+ if String === output
+ FileUtils.mkdir_p(File.dirname(output))
+ @output = File.open(output, 'w')
else
- @output = where
+ @output = output
end
@pending_examples = []
end
+
+ def example_group_started(example_group_proxy)
+ @example_group = example_group_proxy
+ end
- def example_pending(example, message)
- @pending_examples << [example.__full_description, message]
+ def example_pending(example, message, deprecated_pending_location=nil)
+ @pending_examples << ["#{@example_group.description} #{example.description}", message, example.location]
end
def dump_failure(counter, failure)
@output.puts
@output.puts "#{counter.to_s})"
- @output.puts colourise("#{failure.header}\n#{failure.exception.message}", failure)
+ @output.puts colorize_failure("#{failure.header}\n#{failure.exception.message}", failure)
@output.puts format_backtrace(failure.exception.backtrace)
@output.flush
end
- def colourise(s, failure)
- if(failure.expectation_not_met?)
- red(s)
- elsif(failure.pending_fixed?)
- blue(s)
- else
- magenta(s)
- end
+ def colorize_failure(message, failure)
+ failure.pending_fixed? ? blue(message) : red(message)
end
-
+
+ def colourise(message, failure)
+ Spec::deprecate("BaseTextFormatter#colourise", "colorize_failure")
+ colorize_failure(message, failure)
+ end
+
def dump_summary(duration, example_count, failure_count, pending_count)
return if dry_run?
@output.puts
@@ -74,16 +75,15 @@ module Spec
@output.puts
@output.puts "Pending:"
@pending_examples.each do |pending_example|
- @output.puts "#{pending_example[0]} (#{pending_example[1]})"
+ @output.puts "\n#{pending_example[0]} (#{pending_example[1]})"
+ @output.puts "#{pending_example[2]}\n"
end
end
@output.flush
end
def close
- if IO === @output
- @output.close
- end
+ @output.close if (IO === @output) & (@output != $stdout)
end
def format_backtrace(backtrace)
@@ -94,11 +94,15 @@ module Spec
protected
def colour?
- @options.colour ? true : false
+ !!@options.colour
end
def dry_run?
- @options.dry_run ? true : false
+ !!@options.dry_run
+ end
+
+ def autospec?
+ !!@options.autospec || ENV.has_key?("AUTOTEST")
end
def backtrace_line(line)
@@ -106,13 +110,18 @@ module Spec
end
def colour(text, colour_code)
- return text unless colour? && output_to_tty?
+ return text if output_to_file?
+ return text unless ENV['RSPEC_COLOR'] || (colour? & (autospec? || output_to_tty?))
"#{colour_code}#{text}\e[0m"
end
+ def output_to_file?
+ File === @output
+ end
+
def output_to_tty?
begin
- @output == Kernel || @output.tty?
+ @output.tty?
rescue NoMethodError
false
end
@@ -120,10 +129,13 @@ module Spec
def green(text); colour(text, "\e[32m"); end
def red(text); colour(text, "\e[31m"); end
- def magenta(text); colour(text, "\e[35m"); end
def yellow(text); colour(text, "\e[33m"); end
def blue(text); colour(text, "\e[34m"); end
+ def magenta(text)
+ Spec::deprecate("BaseTextFormatter#magenta")
+ red(text)
+ end
end
end
end
diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/failing_example_groups_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/failing_example_groups_formatter.rb
index 8d39bc572..31729438b 100644
--- a/vendor/plugins/rspec/lib/spec/runner/formatter/failing_example_groups_formatter.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/formatter/failing_example_groups_formatter.rb
@@ -6,21 +6,19 @@ module Spec
class FailingExampleGroupsFormatter < BaseTextFormatter
def example_failed(example, counter, failure)
if @example_group
- description_parts = @example_group.description_parts.collect do |description|
- description =~ /(.*) \(druby.*\)$/ ? $1 : description
- end
- @output.puts ::Spec::Example::ExampleGroupMethods.description_text(*description_parts)
+ @output.puts @example_group.description.gsub(/ \(druby.*\)/,"")
@output.flush
@example_group = nil
end
end
-
+
def dump_failure(counter, failure)
end
def dump_summary(duration, example_count, failure_count, pending_count)
end
+
end
end
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 e5368f2cb..2d0c65d1b 100644
--- a/vendor/plugins/rspec/lib/spec/runner/formatter/html_formatter.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/formatter/html_formatter.rb
@@ -1,22 +1,21 @@
require 'erb'
require 'spec/runner/formatter/base_text_formatter'
+require 'spec/runner/formatter/no_op_method_missing'
module Spec
module Runner
module Formatter
class HtmlFormatter < BaseTextFormatter
include ERB::Util # for the #h method
+ include NOOPMethodMissing
def initialize(options, output)
super
@example_group_number = 0
@example_number = 0
+ @header_red = nil
end
- def method_missing(sym, *args)
- # no-op
- end
-
# The number of the currently running example_group
def example_group_number
@example_group_number
@@ -35,10 +34,9 @@ module Spec
@output.flush
end
- def add_example_group(example_group)
+ def example_group_started(example_group)
super
@example_group_red = false
- @example_group_red = false
@example_group_number += 1
unless example_group_number == 1
@output.puts " </dl>"
@@ -85,7 +83,7 @@ module Spec
@output.flush
end
- def example_pending(example, message)
+ def example_pending(example, message, deprecated_pending_location=nil)
@output.puts " <script type=\"text/javascript\">makeYellow('rspec-header');</script>" unless @header_red
@output.puts " <script type=\"text/javascript\">makeYellow('example_group_#{example_group_number}');</script>" unless @example_group_red
move_progress
@@ -154,14 +152,6 @@ module Spec
font-size: 80%;
}
</style>
-</head>
-<body>
-EOF
- end
-
- def report_header
- <<-EOF
-<div class="rspec-report">
<script type="text/javascript">
// <![CDATA[
#{global_scripts}
@@ -170,9 +160,19 @@ EOF
<style type="text/css">
#{global_styles}
</style>
+</head>
+<body>
+EOF
+ end
+
+ def report_header
+ <<-EOF
+<div class="rspec-report">
<div id="rspec-header">
- <h1>RSpec Results</h1>
+ <div id="label">
+ <h1>RSpec Code Examples</h1>
+ </div>
<div id="summary">
<p id="totals">&nbsp;</p>
@@ -212,7 +212,7 @@ EOF
def global_styles
<<-EOF
#rspec-header {
- background: #65C400; color: #fff;
+ background: #65C400; color: #fff; height: 4em;
}
.rspec-report h1 {
@@ -220,15 +220,16 @@ EOF
padding: 10px;
font-family: "Lucida Grande", Helvetica, sans-serif;
font-size: 1.8em;
+ position: absolute;
}
#summary {
margin: 0; padding: 5px 10px;
font-family: "Lucida Grande", Helvetica, sans-serif;
text-align: right;
- position: absolute;
top: 0px;
right: 0px;
+ float:right;
}
#summary p {
diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/nested_text_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/nested_text_formatter.rb
index f9aa5f67c..5caec5a4d 100644
--- a/vendor/plugins/rspec/lib/spec/runner/formatter/nested_text_formatter.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/formatter/nested_text_formatter.rb
@@ -4,33 +4,25 @@ module Spec
module Runner
module Formatter
class NestedTextFormatter < BaseTextFormatter
- attr_reader :previous_nested_example_groups
def initialize(options, where)
super
- @previous_nested_example_groups = []
+ @last_nested_descriptions = []
end
- def add_example_group(example_group)
+ def example_group_started(example_group)
super
- current_nested_example_groups = described_example_group_chain
- current_nested_example_groups.each_with_index do |nested_example_group, i|
- unless nested_example_group == previous_nested_example_groups[i]
- output.puts "#{' ' * i}#{nested_example_group.description_args}"
+ example_group.nested_descriptions.each_with_index do |nested_description, i|
+ unless nested_description == @last_nested_descriptions[i]
+ output.puts "#{' ' * i}#{nested_description}"
end
end
- @previous_nested_example_groups = described_example_group_chain
+ @last_nested_descriptions = example_group.nested_descriptions
end
def example_failed(example, counter, failure)
- message = if failure.expectation_not_met?
- "#{current_indentation}#{example.description} (FAILED - #{counter})"
- else
- "#{current_indentation}#{example.description} (ERROR - #{counter})"
- end
-
- output.puts(failure.expectation_not_met? ? red(message) : magenta(message))
+ output.puts(red("#{current_indentation}#{example.description} (FAILED - #{counter})"))
output.flush
end
@@ -40,24 +32,14 @@ module Spec
output.flush
end
- def example_pending(example, message)
+ def example_pending(example, message, deprecated_pending_location=nil)
super
output.puts yellow("#{current_indentation}#{example.description} (PENDING: #{message})")
output.flush
end
def current_indentation
- ' ' * previous_nested_example_groups.length
- end
-
- def described_example_group_chain
- example_group_chain = []
- example_group.send(:execute_in_class_hierarchy) do |parent_example_group|
- if parent_example_group.description_args && !parent_example_group.description_args.empty?
- example_group_chain << parent_example_group
- end
- end
- example_group_chain
+ ' ' * @last_nested_descriptions.length
end
end
end
diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/profile_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/profile_formatter.rb
index 8671d721e..3784f3ac7 100644
--- a/vendor/plugins/rspec/lib/spec/runner/formatter/profile_formatter.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/formatter/profile_formatter.rb
@@ -41,10 +41,6 @@ module Spec
end
@output.flush
end
-
- def method_missing(sym, *args)
- # ignore
- end
end
end
end
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 032a2872d..862f87a44 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,11 +1,14 @@
require 'spec/runner/formatter/base_text_formatter'
+require 'spec/runner/formatter/no_op_method_missing'
module Spec
module Runner
module Formatter
class ProgressBarFormatter < BaseTextFormatter
+ include NOOPMethodMissing
+
def example_failed(example, counter, failure)
- @output.print colourise('F', failure)
+ @output.print colorize_failure('F', failure)
@output.flush
end
@@ -14,9 +17,9 @@ module Spec
@output.flush
end
- def example_pending(example, message)
+ def example_pending(example, message, deprecated_pending_location=nil)
super
- @output.print yellow('P')
+ @output.print yellow('*')
@output.flush
end
@@ -24,10 +27,6 @@ module Spec
@output.puts
@output.flush
end
-
- def method_missing(sym, *args)
- # ignore
- end
end
end
end
diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/snippet_extractor.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/snippet_extractor.rb
index 41119fe46..4f34e5fee 100644
--- a/vendor/plugins/rspec/lib/spec/runner/formatter/snippet_extractor.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/formatter/snippet_extractor.rb
@@ -4,7 +4,7 @@ module Spec
# This class extracts code snippets by looking at the backtrace of the passed error
class SnippetExtractor #:nodoc:
class NullConverter; def convert(code, pre); code; end; end #:nodoc:
- begin; require 'rubygems'; require 'syntax/convertors/html'; @@converter = Syntax::Convertors::HTML.for_syntax "ruby"; rescue LoadError => e; @@converter = NullConverter.new; end
+ begin; require 'syntax/convertors/html'; @@converter = Syntax::Convertors::HTML.for_syntax "ruby"; rescue LoadError => e; @@converter = NullConverter.new; end
def snippet(error)
raw_code, line = snippet_for(error.backtrace[0])
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 facf1a65a..7204f2147 100644
--- a/vendor/plugins/rspec/lib/spec/runner/formatter/specdoc_formatter.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/formatter/specdoc_formatter.rb
@@ -4,7 +4,7 @@ module Spec
module Runner
module Formatter
class SpecdocFormatter < BaseTextFormatter
- def add_example_group(example_group)
+ def example_group_started(example_group)
super
output.puts
output.puts example_group.description
@@ -12,13 +12,7 @@ module Spec
end
def example_failed(example, counter, failure)
- 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.puts(red("- #{example.description} (FAILED - #{counter})"))
output.flush
end
@@ -28,7 +22,7 @@ module Spec
output.flush
end
- def example_pending(example, message)
+ def example_pending(example, message, deprecated_pending_location=nil)
super
output.puts yellow("- #{example.description} (PENDING: #{message})")
output.flush
diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/story/html_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/story/html_formatter.rb
deleted file mode 100644
index 5a8134683..000000000
--- a/vendor/plugins/rspec/lib/spec/runner/formatter/story/html_formatter.rb
+++ /dev/null
@@ -1,128 +0,0 @@
-require 'erb'
-require 'spec/runner/formatter/base_text_formatter'
-
-module Spec
- module Runner
- module Formatter
- module Story
- class HtmlFormatter < BaseTextFormatter
- include ERB::Util
-
- def run_started(count)
- @output.puts <<-EOF
-<?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>Stories</title>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <meta http-equiv="Expires" content="-1" />
- <meta http-equiv="Pragma" content="no-cache" />
- <script src="javascripts/prototype.js" type="text/javascript"></script>
- <script src="javascripts/scriptaculous.js" type="text/javascript"></script>
- <script src="javascripts/rspec.js" type="text/javascript"></script>
- <link href="stylesheets/rspec.css" rel="stylesheet" type="text/css" />
- </head>
- <body>
- <div id="container">
-EOF
- end
-
- def collected_steps(steps)
- unless steps.empty?
- @output.puts " <ul id=\"stock_steps\" style=\"display: none;\">"
- steps.each do |step|
- @output.puts " <li>#{step}</li>"
- end
- @output.puts " </ul>"
- end
- end
-
- def run_ended
- @output.puts <<-EOF
- </div>
- </body>
-</head>
-EOF
- end
-
- def story_started(title, narrative)
- @output.puts <<-EOF
- <dl class="story passed">
- <dt>Story: #{h title}</dt>
- <dd>
- <p>
- #{h(narrative).split("\n").join("<br />")}
- </p>
-EOF
- end
-
- def story_ended(title, narrative)
- @output.puts <<-EOF
- </dd>
- </dl>
-EOF
- end
-
- def scenario_started(story_title, scenario_name)
- @output.puts <<-EOF
- <dl class="passed">
- <dt>Scenario: #{h scenario_name}</dt>
- <dd>
- <ul class="steps">
-EOF
- end
-
- def scenario_ended
- @output.puts <<-EOF
- </ul>
- </dd>
- </dl>
-EOF
- end
-
- def found_scenario(type, description)
- end
-
- def scenario_succeeded(story_title, scenario_name)
- scenario_ended
- end
-
- def scenario_pending(story_title, scenario_name, reason)
- scenario_ended
- end
-
- def scenario_failed(story_title, scenario_name, err)
- scenario_ended
- end
-
- def step_upcoming(type, description, *args)
- end
-
- def step_succeeded(type, description, *args)
- print_step('passed', type, description, *args) # TODO: uses succeeded CSS class
- end
-
- def step_pending(type, description, *args)
- print_step('pending', type, description, *args)
- end
-
- def step_failed(type, description, *args)
- print_step('failed', type, description, *args)
- end
-
- def print_step(klass, type, description, *args)
- spans = args.map { |arg| "<span class=\"param\">#{arg}</span>" }
- desc_string = description.step_name
- arg_regexp = description.arg_regexp
- i = -1
- inner = type.to_s.capitalize + ' ' + desc_string.gsub(arg_regexp) { |param| spans[i+=1] }
- @output.puts " <li class=\"#{klass}\">#{inner}</li>"
- end
- end
- end
- end
- end
-end \ No newline at end of file
diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/story/plain_text_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/story/plain_text_formatter.rb
deleted file mode 100644
index 31cd614cb..000000000
--- a/vendor/plugins/rspec/lib/spec/runner/formatter/story/plain_text_formatter.rb
+++ /dev/null
@@ -1,142 +0,0 @@
-require 'spec/runner/formatter/base_text_formatter'
-
-module Spec
- module Runner
- module Formatter
- module Story
- class PlainTextFormatter < BaseTextFormatter
- def initialize(options, where)
- super
- @successful_scenario_count = 0
- @pending_scenario_count = 0
- @failed_scenarios = []
- @pending_steps = []
- @previous_type = nil
- end
-
- def run_started(count)
- @count = count
- @output.puts "Running #@count scenarios\n\n"
- end
-
- def story_started(title, narrative)
- @current_story_title = title
- @output.puts "Story: #{title}\n\n"
- narrative.each_line do |line|
- @output.print " "
- @output.print line
- end
- end
-
- def story_ended(title, narrative)
- @output.puts
- @output.puts
- end
-
- def scenario_started(story_title, scenario_name)
- @current_scenario_name = scenario_name
- @scenario_already_failed = false
- @output.print "\n\n Scenario: #{scenario_name}"
- @scenario_ok = true
- @scenario_pending = false
- end
-
- def scenario_succeeded(story_title, scenario_name)
- @successful_scenario_count += 1
- end
-
- def scenario_failed(story_title, scenario_name, err)
- @options.backtrace_tweaker.tweak_backtrace(err)
- @failed_scenarios << [story_title, scenario_name, err] unless @scenario_already_failed
- @scenario_already_failed = true
- end
-
- def scenario_pending(story_title, scenario_name, msg)
- @pending_scenario_count += 1 unless @scenario_already_failed
- @scenario_pending = true
- @scenario_already_failed = true
- end
-
- def run_ended
- @output.puts "#@count scenarios: #@successful_scenario_count succeeded, #{@failed_scenarios.size} failed, #@pending_scenario_count pending"
- unless @pending_steps.empty?
- @output.puts "\nPending Steps:"
- @pending_steps.each_with_index do |pending, i|
- story_name, scenario_name, msg = pending
- @output.puts "#{i+1}) #{story_name} (#{scenario_name}): #{msg}"
- end
- end
- unless @failed_scenarios.empty?
- @output.print "\nFAILURES:"
- @failed_scenarios.each_with_index do |failure, i|
- title, scenario_name, err = failure
- @output.print %[
- #{i+1}) #{title} (#{scenario_name}) FAILED
- #{err.class}: #{err.message}
- #{err.backtrace.join("\n")}
-]
- end
- end
- end
-
- def step_upcoming(type, description, *args)
- end
-
- def step_succeeded(type, description, *args)
- found_step(type, description, false, false, *args)
- end
-
- def step_pending(type, description, *args)
- found_step(type, description, false, true, *args)
- @pending_steps << [@current_story_title, @current_scenario_name, description]
- @output.print yellow(" (PENDING)")
- @scenario_pending = true
- @scenario_ok = false
- end
-
- def step_failed(type, description, *args)
- found_step(type, description, true, @scenario_pending, *args)
- if @scenario_pending
- @output.print yellow(" (SKIPPED)")
- else
- @output.print red(@scenario_ok ? " (FAILED)" : " (SKIPPED)")
- end
- @scenario_ok = false
- end
-
- def collected_steps(steps)
- end
-
- def method_missing(sym, *args, &block) #:nodoc:
- # noop - ignore unknown messages
- end
-
- private
-
- def found_step(type, description, failed, pending, *args)
- desc_string = description.step_name
- arg_regexp = description.arg_regexp
- text = if(type == @previous_type)
- "\n And "
- else
- "\n\n #{type.to_s.capitalize} "
- end
- i = -1
- text << desc_string.gsub(arg_regexp) { |param| args[i+=1] }
- if pending
- @output.print yellow(text)
- else
- @output.print(failed ? red(text) : green(text))
- end
-
- if type == :'given scenario'
- @previous_type = :given
- else
- @previous_type = type
- end
- end
- end
- end
- 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 7695fe794..5c81ea846 100644
--- a/vendor/plugins/rspec/lib/spec/runner/heckle_runner.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/heckle_runner.rb
@@ -1,72 +1,72 @@
-begin
- require 'rubygems'
- require 'heckle'
-rescue LoadError ; raise "You must gem install heckle to use --heckle" ; end
+if Spec::Ruby.version.to_f < 1.9
+ begin
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
+ require 'heckle'
+ rescue LoadError ; raise "You must gem install heckle to use --heckle" ; end
-module Spec
- module Runner
- # Creates a new Heckler configured to heckle all methods in the classes
- # whose name matches +filter+
- class HeckleRunner
- def initialize(filter, heckle_class=Heckler)
- @filter = filter
- @heckle_class = heckle_class
- end
-
- # Runs all the example groups held by +rspec_options+ once for each of the
- # methods in the matched classes.
- def heckle_with
- if @filter =~ /(.*)[#\.](.*)/
- heckle_method($1, $2)
- else
- heckle_class_or_module(@filter)
+ module Spec
+ module Runner
+ # Creates a new Heckler configured to heckle all methods in the classes
+ # whose name matches +filter+
+ class HeckleRunner
+ def initialize(filter, heckle_class=Heckler)
+ @filter = filter
+ @heckle_class = heckle_class
end
- end
- def heckle_method(class_name, method_name)
- verify_constant(class_name)
- heckle = @heckle_class.new(class_name, method_name, rspec_options)
- heckle.validate
- end
+ # Runs all the example groups held by +rspec_options+ once for each of the
+ # methods in the matched classes.
+ def heckle_with
+ if @filter =~ /(.*)[#\.](.*)/
+ heckle_method($1, $2)
+ else
+ heckle_class_or_module(@filter)
+ end
+ end
- def heckle_class_or_module(class_or_module_name)
- verify_constant(class_or_module_name)
- pattern = /^#{class_or_module_name}/
- classes = []
- ObjectSpace.each_object(Class) do |klass|
- classes << klass if klass.name =~ pattern
+ def heckle_method(class_name, method_name)
+ verify_constant(class_name)
+ heckle = @heckle_class.new(class_name, method_name, Spec::Runner.options)
+ heckle.validate
end
+
+ def heckle_class_or_module(class_or_module_name)
+ verify_constant(class_or_module_name)
+ pattern = /^#{class_or_module_name}/
+ classes = []
+ ObjectSpace.each_object(Class) do |klass|
+ classes << klass if klass.name =~ pattern
+ end
- classes.each do |klass|
- klass.instance_methods(false).each do |method_name|
- heckle = @heckle_class.new(klass.name, method_name, rspec_options)
- heckle.validate
+ classes.each do |klass|
+ klass.instance_methods(false).each do |method_name|
+ heckle = @heckle_class.new(klass.name, method_name, Spec::Runner.options)
+ heckle.validate
+ end
end
end
- end
- def verify_constant(name)
- begin
- # This is defined in Heckle
- name.to_class
- rescue
- raise "Heckling failed - \"#{name}\" is not a known class or module"
+ def verify_constant(name)
+ begin
+ # This is defined in Heckle
+ name.to_class
+ rescue
+ raise "Heckling failed - \"#{name}\" is not a known class or module"
+ end
end
end
- end
- #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, rspec_options)
- super(klass_name, method_name)
- @rspec_options = rspec_options
- end
+ class Heckler < Heckle
+ def initialize(klass_name, method_name, rspec_options)
+ super(klass_name, method_name)
+ @rspec_options = rspec_options
+ end
- def tests_pass?
- success = @rspec_options.run_examples
- success
- end
+ def tests_pass?
+ @rspec_options.run_examples
+ end
+ end
end
end
-end
+end \ No newline at end of file
diff --git a/vendor/plugins/rspec/lib/spec/runner/heckle_runner_unsupported.rb b/vendor/plugins/rspec/lib/spec/runner/heckle_runner_unsupported.rb
index 02aa37953..35ff86e10 100644
--- a/vendor/plugins/rspec/lib/spec/runner/heckle_runner_unsupported.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/heckle_runner_unsupported.rb
@@ -3,7 +3,7 @@ module Spec
# Dummy implementation for Windows that just fails (Heckle is not supported on Windows)
class HeckleRunner
def initialize(filter)
- raise "Heckle not supported on Windows"
+ raise "Heckle is not supported on Windows or Ruby 1.9"
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 91525e089..fbbf444a9 100644
--- a/vendor/plugins/rspec/lib/spec/runner/option_parser.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/option_parser.rb
@@ -10,6 +10,10 @@ module Spec
parser.parse(args)
parser.options
end
+
+ def spec_command?
+ $0.split('/').last == 'spec'
+ end
end
attr_reader :options
@@ -27,34 +31,30 @@ module Spec
:example => ["-e", "--example [NAME|FILE_NAME]", "Execute example(s) with matching name(s). If the argument is",
"the path to an existing file (typically generated by a previous",
"run using --format failing_examples:file.txt), then the examples",
- "on each line of thatfile will be executed. If the file is empty,",
+ "on each line of that file will be executed. If the file is empty,",
"all examples will be run (as if --example was not specified).",
" ",
"If the argument is not an existing file, then it is treated as",
"an example name directly, causing RSpec to run just the example",
"matching that name"],
:specification => ["-s", "--specification [NAME]", "DEPRECATED - use -e instead", "(This will be removed when autotest works with -e)"],
- :line => ["-l", "--line LINE_NUMBER", Integer, "Execute behaviout or specification at given line.",
- "(does not work for dynamically generated specs)"],
+ :line => ["-l", "--line LINE_NUMBER", Integer, "Execute example group or example at given line.",
+ "(does not work for dynamically generated examples)"],
:format => ["-f", "--format FORMAT[:WHERE]","Specifies what format to use for output. Specify WHERE to tell",
"the formatter where to write the output. All built-in formats",
- "expect WHERE to be a file name, and will write to STDOUT if it's",
+ "expect WHERE to be a file name, and will write to $stdout if it's",
"not specified. The --format option may be specified several times",
"if you want several outputs",
" ",
- "Builtin formats for examples: ",
- "progress|p : Text progress",
- "profile|o : Text progress with profiling of 10 slowest examples",
- "specdoc|s : Example doc as text",
- "indented|i : Example doc as indented text",
+ "Builtin formats:",
+ "silent|l : No output", "progress|p : Text-based progress bar",
+ "profile|o : Text-based progress bar with profiling of 10 slowest examples",
+ "specdoc|s : Code example doc strings",
+ "nested|n : Code example doc strings with nested groups indented",
"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",
- " ",
"FORMAT can also be the name of a custom formatter class",
"(in which case you should also specify --require to load it)"],
:require => ["-r", "--require FILE", "Require FILE before running specs",
@@ -78,6 +78,7 @@ module Spec
: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 Runner."],
+ :debug => ["-u", "--debugger", "Enable ruby-debugging."],
: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"]
@@ -91,37 +92,49 @@ module Spec
@file_factory = File
- self.banner = "Usage: spec (FILE|DIRECTORY|GLOB)+ [options]"
+ self.banner = "Usage: spec (FILE(:LINE)?|DIRECTORY|GLOB)+ [options]"
self.separator ""
- on(*OPTIONS[:pattern]) {|pattern| @options.filename_pattern = pattern}
- 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[:pattern]) {|pattern| @options.filename_pattern = pattern}
+ 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|}
on(*OPTIONS[:generate_options]) {|options_file|}
- on(*OPTIONS[:runner]) {|runner| @options.user_input_for_runner = runner}
- on(*OPTIONS[:drb]) {}
- on(*OPTIONS[:version]) {parse_version}
- on_tail(*OPTIONS[:help]) {parse_help}
+ on(*OPTIONS[:runner]) {|runner| @options.user_input_for_runner = runner}
+ on(*OPTIONS[:debug]) {@options.debug = true}
+ on(*OPTIONS[:drb]) {}
+ on(*OPTIONS[:version]) {parse_version}
+ on("--autospec") {@options.autospec = true}
+ on_tail(*OPTIONS[:help]) {parse_help}
end
def order!(argv, &blk)
- @argv = argv
+ @argv = argv.dup
+ @argv = (@argv.empty? & self.class.spec_command?) ? ['--help'] : @argv
+
+ # Parse options file first
+ parse_file_options(:options_file, :parse_options_file)
+
@options.argv = @argv.dup
- return if parse_generate_options
+ return if parse_file_options(:generate_options, :write_options_file)
return if parse_drb
-
+
super(@argv) do |file|
+ if file =~ /^(.+):(\d+)$/
+ file = $1
+ @options.line_number = $2.to_i
+ end
+
@options.files << file
blk.call(file) if blk
end
@@ -129,41 +142,46 @@ module Spec
@options
end
- protected
+ 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)
- # TODO - this is a brute force solution to http://rspec.lighthouseapp.com/projects/5645/tickets/293.
- # Let's look for a cleaner way. Might not be one. But let's look. If not, perhaps
- # this can be moved to a different method to indicate the special handling for drb?
- parse_drb(@argv)
- end
- def parse_generate_options
- # Remove the --generate-options option and the argument before writing to file
+ def parse_file_options(option_name, action)
+ # Remove the file option and the argument before handling the file
options_file = nil
- ['-G', '--generate-options'].each do |option|
+ options_list = OPTIONS[option_name][0..1]
+ options_list[1].gsub!(" PATH", "")
+ options_list.each do |option|
if index = @argv.index(option)
@argv.delete_at(index)
options_file = @argv.delete_at(index)
end
end
+ if options_file.nil? &&
+ File.exist?('spec/spec.opts') &&
+ !@argv.any?{|a| a =~ /^\-/ }
+ options_file = 'spec/spec.opts'
+ end
+
if options_file
- write_generated_options(options_file)
+ send(action, options_file)
return true
else
return false
end
end
-
- def write_generated_options(options_file)
+
+ def parse_options_file(options_file)
+ option_file_args = File.readlines(options_file).map {|l| l.chomp.split " "}.flatten
+ @argv.push(*option_file_args)
+ end
+
+ def write_options_file(options_file)
File.open(options_file, 'w') do |io|
io.puts @argv.join("\n")
end
@@ -172,28 +190,30 @@ module Spec
@options.examples_should_not_be_run
end
- def parse_drb(argv = nil)
- argv ||= @options.argv # TODO - see note about about http://rspec.lighthouseapp.com/projects/5645/tickets/293
+ def parse_drb
+ argv = @options.argv
is_drb = false
is_drb ||= argv.delete(OPTIONS[:drb][0])
is_drb ||= argv.delete(OPTIONS[:drb][1])
return false unless is_drb
- @options.examples_should_not_be_run
- DrbCommandLine.run(
- self.class.parse(argv, @error_stream, @out_stream)
- )
- true
+ if DrbCommandLine.run(self.class.parse(argv, @error_stream, @out_stream))
+ @options.examples_should_not_be_run
+ true
+ else
+ @error_stream.puts "Running specs locally:"
+ false
+ end
end
def parse_version
- @out_stream.puts ::Spec::VERSION::DESCRIPTION
+ @out_stream.puts ::Spec::VERSION::SUMMARY
exit if stdout?
end
def parse_help
@out_stream.puts self
exit if stdout?
- end
+ end
def stdout?
@out_stream == $stdout
diff --git a/vendor/plugins/rspec/lib/spec/runner/options.rb b/vendor/plugins/rspec/lib/spec/runner/options.rb
index 6716464af..e0179e80e 100644
--- a/vendor/plugins/rspec/lib/spec/runner/options.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/options.rb
@@ -1,3 +1,5 @@
+require 'ostruct'
+
module Spec
module Runner
class Options
@@ -6,9 +8,11 @@ module Spec
}
EXAMPLE_FORMATTERS = { # Load these lazily for better speed
+ 'silent' => ['spec/runner/formatter/silent_formatter', 'Formatter::SilentFormatter'],
+ 'l' => ['spec/runner/formatter/silent_formatter', 'Formatter::SilentFormatter'],
'specdoc' => ['spec/runner/formatter/specdoc_formatter', 'Formatter::SpecdocFormatter'],
's' => ['spec/runner/formatter/specdoc_formatter', 'Formatter::SpecdocFormatter'],
- 'nested' => ['spec/runner/formatter/nested_text_formatter', 'Formatter::NestedTextFormatter'],
+ 'nested' => ['spec/runner/formatter/nested_text_formatter', 'Formatter::NestedTextFormatter'],
'n' => ['spec/runner/formatter/nested_text_formatter', 'Formatter::NestedTextFormatter'],
'html' => ['spec/runner/formatter/html_formatter', 'Formatter::HtmlFormatter'],
'h' => ['spec/runner/formatter/html_formatter', 'Formatter::HtmlFormatter'],
@@ -23,22 +27,16 @@ module Spec
'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(
+ :autospec, # hack to tell
:filename_pattern,
:backtrace_tweaker,
:context_lines,
:diff_format,
:dry_run,
:profile,
- :examples,
:heckle_runner,
+ :debug,
:line_number,
:loadby,
:reporter,
@@ -48,12 +46,10 @@ module Spec
:user_input_for_runner,
:error_stream,
:output_stream,
- :before_suite_parts,
- :after_suite_parts,
# TODO: BT - Figure out a better name
:argv
)
- attr_reader :colour, :differ_class, :files, :example_groups
+ attr_reader :colour, :differ_class, :files, :examples, :example_groups
def initialize(error_stream, output_stream)
@error_stream = error_stream
@@ -64,6 +60,7 @@ module Spec
@colour = false
@profile = false
@dry_run = false
+ @debug = false
@reporter = Reporter.new(self)
@context_lines = 3
@diff_format = :unified
@@ -73,32 +70,80 @@ module Spec
@examples_run = false
@examples_should_be_run = nil
@user_input_for_runner = nil
- @before_suite_parts = []
@after_suite_parts = []
+ @files_loaded = false
+ @out_used = nil
end
def add_example_group(example_group)
@example_groups << example_group
end
+ def line_number_requested?
+ !!line_number
+ end
+
+ def example_line
+ Spec::Runner::LineNumberQuery.new(self).example_line_for(files.first, line_number)
+ end
+
def remove_example_group(example_group)
@example_groups.delete(example_group)
end
+ def require_ruby_debug
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
+ require 'ruby-debug'
+ end
+
+ def project_root # :nodoc:
+ require 'pathname'
+ @project_root ||= determine_project_root
+ end
+
+ def determine_project_root # :nodoc:
+ # This is borrowed (slightly modified) from Scott Taylors
+ # project_path project:
+ # http://github.com/smtlaissezfaire/project_path
+ Pathname(File.expand_path('.')).ascend do |path|
+ if File.exists?(File.join(path, "spec"))
+ return path
+ end
+ end
+ end
+
+ def add_dir_from_project_root_to_load_path(dir, load_path=$LOAD_PATH) # :nodoc:
+ return if project_root.nil?
+ full_dir = File.join(project_root, dir)
+ load_path.unshift full_dir unless load_path.include?(full_dir)
+ end
+
def run_examples
+ require_ruby_debug if debug
return true unless examples_should_be_run?
success = true
begin
- before_suite_parts.each do |part|
- part.call
- end
runner = custom_runner || ExampleGroupRunner.new(self)
unless @files_loaded
+ ['spec','lib'].each do |dir|
+ add_dir_from_project_root_to_load_path(dir)
+ end
runner.load_files(files_to_load)
@files_loaded = true
end
+ define_predicate_matchers
+ plugin_mock_framework
+ ignore_backtrace_patterns
+
+ # TODO - this has to happen after the files get loaded,
+ # otherwise the before_suite_parts are not populated
+ # from the configuration. There is no spec for this
+ # directly, but features/before_and_after_blocks/before_and_after_blocks.story
+ # will fail if this happens before the files are loaded.
+ before_suite_parts.each { |part| part.call }
+
if example_groups.empty?
true
else
@@ -110,25 +155,40 @@ module Spec
end
ensure
after_suite_parts.each do |part|
- part.call(success)
+ part.arity < 1 ? part.call : part.call(success)
end
end
end
+ def before_suite_parts
+ Spec::Example::BeforeAndAfterHooks.before_suite_parts
+ end
+
+ def after_suite_parts
+ Spec::Example::BeforeAndAfterHooks.after_suite_parts
+ end
+
def examples_run?
@examples_run
end
def examples_should_not_be_run
@examples_should_be_run = false
- end
+ end
+
+ def mock_framework
+ # TODO - don't like this dependency - perhaps store this in here instead?
+ Spec::Runner.configuration.mock_framework
+ end
def colour=(colour)
@colour = colour
- if @colour && RUBY_PLATFORM =~ /win32/ ;\
+ if @colour && RUBY_PLATFORM =~ /mswin|mingw/ ;\
begin ;\
- require 'rubygems' ;\
+ replace_output = @output_stream.equal?($stdout) ;\
+ require 'rubygems' unless ENV['NO_RUBYGEMS'] ;\
require 'Win32/Console/ANSI' ;\
+ @output_stream = $stdout if replace_output ;\
rescue LoadError ;\
warn "You must 'gem install win32console' to use colour on Windows" ;\
@colour = false ;\
@@ -152,7 +212,7 @@ module Spec
def parse_example(example)
if(File.file?(example))
- @examples = File.open(example).read.split("\n")
+ @examples = [File.open(example).read.split("\n")].flatten
else
@examples = [example]
end
@@ -168,17 +228,12 @@ module Spec
@format_options ||= []
@format_options << [format, where]
end
-
+
def formatters
@format_options ||= [['progress', @output_stream]]
@formatters ||= load_formatters(@format_options, EXAMPLE_FORMATTERS)
end
- 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]
@@ -187,22 +242,31 @@ module Spec
else
load_class(format, 'formatter', '--format')
end
- formatter_type.new(self, where)
+ formatter_type.new(formatter_options, where)
end
end
+ def formatter_options
+ @formatter_options ||= OpenStruct.new(
+ :colour => colour,
+ :autospec => autospec,
+ :dry_run => dry_run
+ )
+ end
+
+ def which_heckle_runner
+ ([/mswin/, /java/].detect{|p| p =~ RUBY_PLATFORM} || Spec::Ruby.version.to_f == 1.9) ? "spec/runner/heckle_runner_unsupported" : "spec/runner/heckle_runner"
+ end
+
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)
+ @format_options ||= [['silent', @output_stream]]
+ require which_heckle_runner
+ @heckle_runner = ::Spec::Runner::HeckleRunner.new(heckle)
end
def number_of_examples
- total = 0
- @example_groups.each do |example_group|
- total += example_group.number_of_examples
- end
- total
+ return examples.size unless examples.empty?
+ @example_groups.inject(0) {|sum, group| sum + group.number_of_examples}
end
def files_to_load
@@ -220,13 +284,40 @@ module Spec
end
result
end
-
- protected
+
+ def dry_run?
+ @dry_run == true
+ end
+
+ protected
+
+ def define_predicate_matchers
+ Spec::Runner.configuration.predicate_matchers.each_pair do |matcher_method, method_on_object|
+ Spec::Example::ExampleMethods::__send__ :define_method, matcher_method do |*args|
+ eval("be_#{method_on_object.to_s.gsub('?','')}(*args)")
+ end
+ end
+ end
+
+ def plugin_mock_framework
+ case mock_framework
+ when Module
+ Spec::Example::ExampleMethods.__send__ :include, mock_framework
+ else
+ require mock_framework
+ Spec::Example::ExampleMethods.__send__ :include, Spec::Adapters::MockFramework
+ end
+ end
+
+ def ignore_backtrace_patterns
+ @backtrace_tweaker.ignore_patterns Spec::Runner.configuration.ignored_backtrace_patterns
+ end
+
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
@@ -250,24 +341,24 @@ module Spec
if $_spec_spec ; raise e ; else exit(1) ; end
end
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')
+ runner_type = load_class(klass_name, 'example group runner', '--runner')
return runner_type.new(self, arg)
end
def custom_runner?
return user_input_for_runner ? true : false
end
-
+
def heckle
heckle_runner = self.heckle_runner
self.heckle_runner = nil
heckle_runner.heckle_with
end
-
+
def sorted_files
return sorter ? files.sort(&sorter) : files
end
@@ -277,26 +368,26 @@ module Spec
end
def default_differ
- require 'spec/expectations/differs/default'
- self.differ_class = Spec::Expectations::Differs::Default
+ require 'spec/runner/differs/default'
+ self.differ_class = ::Spec::Expectations::Differs::Default
end
def set_spec_from_line_number
if examples.empty?
if files.length == 1
if File.directory?(files[0])
- error_stream.puts "You must specify one file, not a directory when using the --line option"
+ error_stream.puts "You must specify one file, not a directory when providing a line number"
exit(1) if stderr?
else
- example = SpecParser.new.spec_name_for(files[0], line_number)
+ example = LineNumberQuery.new(self).spec_name_for(files[0], line_number)
@examples = [example]
end
else
- error_stream.puts "Only one file can be specified when using the --line option: #{files.inspect}"
+ error_stream.puts "Only one file can be specified when providing a line number: #{files.inspect}"
exit(3) if stderr?
end
else
- error_stream.puts "You cannot use both --line and --example"
+ error_stream.puts "You cannot use --example and specify a line number"
exit(4) if stderr?
end
end
diff --git a/vendor/plugins/rspec/lib/spec/runner/reporter.rb b/vendor/plugins/rspec/lib/spec/runner/reporter.rb
index 66db38406..0fae7d137 100644
--- a/vendor/plugins/rspec/lib/spec/runner/reporter.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/reporter.rb
@@ -1,19 +1,23 @@
module Spec
module Runner
class Reporter
- attr_reader :options, :example_groups
+ attr_reader :options
def initialize(options)
@options = options
@options.reporter = self
- clear
+ @failures = []
+ @pending_count = 0
+ @example_count = 0
+ @start_time = nil
+ @end_time = nil
end
- def add_example_group(example_group)
+ def example_group_started(example_group)
+ @example_group = example_group
formatters.each do |f|
- f.add_example_group(example_group)
+ f.example_group_started(example_group)
end
- example_groups << example_group
end
def example_started(example)
@@ -21,29 +25,27 @@ module Spec
end
def example_finished(example, error=nil)
- @examples << example
+ @example_count += 1
if error.nil?
example_passed(example)
elsif Spec::Example::ExamplePendingError === error
- example_pending(example, error.message)
+ example_pending(example, example.location, error.message)
else
example_failed(example, error)
end
end
- def failure(example, error)
+ def example_failed(example, error)
backtrace_tweaker.tweak_backtrace(error)
- failure = Failure.new(example, error)
+ failure = Failure.new(@example_group.description, example.description, 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
@start_time = Time.new
formatters.each{|f| f.start(number_of_examples)}
end
@@ -58,12 +60,51 @@ module Spec
dump_pending
dump_failures
formatters.each do |f|
- f.dump_summary(duration, @examples.length, @failures.length, @pending_count)
+ f.dump_summary(duration, @example_count, @failures.length, @pending_count)
f.close
end
@failures.length
end
+ class Failure
+ def initialize(group_description, example_description, exception) # :nodoc:
+ @example_name = "#{group_description} #{example_description}"
+ @exception = exception
+ end
+
+ # The Exception object raised
+ attr_reader :exception
+
+ # Header messsage for reporting this failure, including the name of the
+ # example and an indicator of the type of failure. FAILED indicates a
+ # failed expectation. FIXED indicates a pending example that passes, and
+ # no longer needs to be pending. RuntimeError indicates that a
+ # RuntimeError occured.
+ #
+ # == Examples
+ #
+ # 'A new account should have a zero balance' FAILED
+ # 'A new account should have a zero balance' FIXED
+ # RuntimeError in 'A new account should have a zero balance'
+ def header
+ if expectation_not_met?
+ "'#{@example_name}' FAILED"
+ elsif pending_fixed?
+ "'#{@example_name}' FIXED"
+ else
+ "#{@exception.class.name} in '#{@example_name}'"
+ end
+ end
+
+ def pending_fixed? # :nodoc:
+ @exception.is_a?(Spec::Example::PendingExampleFixedError)
+ end
+
+ def expectation_not_met? # :nodoc:
+ @exception.is_a?(Spec::Expectations::ExpectationNotMetError)
+ end
+ end
+
private
def formatters
@@ -74,15 +115,6 @@ module Spec
@options.backtrace_tweaker
end
- def clear
- @example_groups = []
- @failures = []
- @pending_count = 0
- @examples = []
- @start_time = nil
- @end_time = nil
- end
-
def dump_failures
return if @failures.empty?
@failures.inject(1) do |index, failure|
@@ -103,45 +135,37 @@ module Spec
def example_passed(example)
formatters.each{|f| f.example_passed(example)}
end
+
+ EXAMPLE_PENDING_DEPRECATION_WARNING = <<-WARNING
+
+*********************************************************************
+DEPRECATION WARNING: RSpec's formatters have changed example_pending
+to accept two arguments instead of three. Please see the rdoc
+for Spec::Runner::Formatter::BaseFormatter#example_pending
+for more information.
+
+Please update any custom formatters to accept only two arguments
+to example_pending. Support for example_pending with two arguments
+and this warning message will be removed after the RSpec 2.0 release.
+*********************************************************************
+WARNING
- def example_pending(example, message="Not Yet Implemented")
+ def example_pending(example, ignore, message="Not Yet Implemented")
@pending_count += 1
- formatters.each do |f|
- f.example_pending(example, message)
- end
- end
-
- class Failure
- attr_reader :example, :exception
-
- def initialize(example, exception)
- @example = example
- @exception = exception
- end
-
- def header
- if expectation_not_met?
- "'#{example_name}' FAILED"
- elsif pending_fixed?
- "'#{example_name}' FIXED"
+ formatters.each do |formatter|
+ if formatter_uses_deprecated_example_pending_method?(formatter)
+ Spec.warn EXAMPLE_PENDING_DEPRECATION_WARNING
+ formatter.example_pending(example, message, example.location)
else
- "#{@exception.class.name} in '#{example_name}'"
+ formatter.example_pending(example, message)
end
end
-
- def pending_fixed?
- @exception.is_a?(Spec::Example::PendingExampleFixedError)
- end
-
- def expectation_not_met?
- @exception.is_a?(Spec::Expectations::ExpectationNotMetError)
- end
-
- protected
- def example_name
- @example.__full_description
- end
end
+
+ def formatter_uses_deprecated_example_pending_method?(formatter)
+ formatter.method(:example_pending).arity == 3
+ end
+
end
end
end
diff --git a/vendor/plugins/rspec/lib/spec/runner/spec_parser.rb b/vendor/plugins/rspec/lib/spec/runner/spec_parser.rb
deleted file mode 100644
index 8beb384e9..000000000
--- a/vendor/plugins/rspec/lib/spec/runner/spec_parser.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-module Spec
- module Runner
- # Parses a spec file and finds the nearest example for a given line number.
- class SpecParser
- attr_reader :best_match
-
- def initialize
- @best_match = {}
- end
-
- def spec_name_for(file, line_number)
- best_match.clear
- file = File.expand_path(file)
- rspec_options.example_groups.each do |example_group|
- consider_example_groups_for_best_match example_group, file, line_number
-
- example_group.examples.each do |example|
- consider_example_for_best_match example, example_group, file, line_number
- end
- end
- if best_match[:example_group]
- if best_match[:example]
- "#{best_match[:example_group].description} #{best_match[:example].description}"
- else
- best_match[:example_group].description
- end
- else
- nil
- end
- end
-
- protected
-
- def consider_example_groups_for_best_match(example_group, file, line_number)
- parsed_backtrace = parse_backtrace(example_group.registration_backtrace)
- parsed_backtrace.each do |example_file, example_line|
- if is_best_match?(file, line_number, example_file, example_line)
- best_match.clear
- best_match[:example_group] = example_group
- best_match[:line] = example_line
- end
- end
- end
-
- def consider_example_for_best_match(example, example_group, file, line_number)
- parsed_backtrace = parse_backtrace(example.implementation_backtrace)
- parsed_backtrace.each do |example_file, example_line|
- if is_best_match?(file, line_number, example_file, example_line)
- best_match.clear
- best_match[:example_group] = example_group
- best_match[:example] = example
- best_match[:line] = example_line
- end
- end
- end
-
- def is_best_match?(file, line_number, example_file, example_line)
- file == File.expand_path(example_file) &&
- example_line <= line_number &&
- example_line > best_match[:line].to_i
- end
-
- def parse_backtrace(backtrace)
- backtrace.collect do |trace_line|
- split_line = trace_line.split(':')
- [split_line[0], Integer(split_line[1])]
- end
- end
- end
- end
-end