Skip to content

Commit

Permalink
support multiple formatters
Browse files Browse the repository at this point in the history
- Closes #213.
  • Loading branch information
dchelimsky committed Dec 31, 2010
1 parent 801e7bc commit a5f9ffd
Show file tree
Hide file tree
Showing 16 changed files with 256 additions and 111 deletions.
1 change: 1 addition & 0 deletions History.markdown
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
(Clifford Heath) (Clifford Heath)
* HTML Formatter _finally_ properly displays nested groups (Jarmo Pertman) * HTML Formatter _finally_ properly displays nested groups (Jarmo Pertman)
* apply hook filtering to examples as well as groups (Myron Marston) * apply hook filtering to examples as well as groups (Myron Marston)
* support multiple formatters, each with their own output


* Bug fixes * Bug fixes
* send debugger warning message to $stdout if RSpec.configuration.error_stream * send debugger warning message to $stdout if RSpec.configuration.error_stream
Expand Down
6 changes: 6 additions & 0 deletions features/command_line/README.md
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,6 @@
The `rspec` command comes with several options you can use to customize RSpec's
behavior, including output formats, filtering examples, etc.

For a full list of options, run the `rspec` command with the `--help` flag:

$ rspec --help
2 changes: 1 addition & 1 deletion features/command_line/configure.feature
Original file line number Original file line Diff line number Diff line change
@@ -1,4 +1,4 @@
Feature: configure Feature: --configure option


Use the --configure option on the command line to generate configuration Use the --configure option on the command line to generate configuration
files. files.
Expand Down
6 changes: 3 additions & 3 deletions features/command_line/example_name_option.feature
Original file line number Original file line Diff line number Diff line change
@@ -1,13 +1,13 @@
Feature: example name option Feature: --example option


Use the --example (or -e) option to filter the examples to be run by name. Use the --example (or -e) option to filter examples by name.


The argument is compiled to a Ruby Regexp, and matched against the full The argument is compiled to a Ruby Regexp, and matched against the full
description of the example, which is the concatenation of descriptions of the description of the example, which is the concatenation of descriptions of the
group (including any nested groups) and the example. group (including any nested groups) and the example.


This allows you to run a single uniquely named example, all examples with This allows you to run a single uniquely named example, all examples with
similar names, all the example in a uniquely named group, etc, etc. similar names, all the examples in a uniquely named group, etc, etc.


Background: Background:
Given a file named "first_spec.rb" with: Given a file named "first_spec.rb" with:
Expand Down
73 changes: 73 additions & 0 deletions features/command_line/format_option.feature
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,73 @@
Feature: --formatt option

This comment has been minimized.

Copy link
@jarmo

jarmo Jan 1, 2011

Contributor

Minor typo in here.

This comment has been minimized.

Copy link
@dchelimsky

dchelimsky Jan 1, 2011

Author Contributor

Already fixed: 07c97d1#L0L1


Use the --format option to tell RSpec how to format the output.

RSpec ships with a few formatters built in. By default, it uses the progress
formatter, which generates output like this:

....F.....*.....

A '.' represents a passing example, 'F' is failing, and '*' is pending.

To see the documentation strings passed to each describe(), context(), and it()
method, use the documentation formatter:

$ rspec spec --format documentation

You can also specify an output target (STDOUT by default) by appending a
filename to the argument:

$ rspec spec --format documentation:rspec.output.txt

Background:
Given a file named "example_spec.rb" with:
"""
describe "something" do
it "does something that passes" do
5.should eq(5)
end
it "does something that fails" do
5.should eq(4)
end
it "does something that is pending", :pending => true do
5.should be > 3
end
end
"""

Scenario: progress bar format (default)
When I run "rspec example_spec.rb"
Then the output should contain ".F*"

Scenario: documentation format
When I run "rspec example_spec.rb --format documentation"
Then the output should contain:
"""
something
does something that passes
does something that fails (FAILED - 1)
does something that is pending (PENDING: Not Yet Implemented)
"""

Scenario: documentation format saved to a file
When I run "rspec example_spec.rb --format documentation --out rspec.txt"
Then the file "rspec.txt" should contain:
"""
something
does something that passes
does something that fails (FAILED - 1)
does something that is pending (PENDING: Not Yet Implemented)
"""

Scenario: multiple formats
When I run "rspec example_spec.rb --format progress --format documentation --out rspec.txt"
Then the output should contain ".F*"
And the file "rspec.txt" should contain:
"""
something
does something that passes
does something that fails (FAILED - 1)
does something that is pending (PENDING: Not Yet Implemented)
"""
2 changes: 1 addition & 1 deletion features/command_line/line_number_appended_to_path.feature
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Feature: line number appended to file path


To run a single example or group, you can append the line number to the path, e.g. To run a single example or group, you can append the line number to the path, e.g.


rspec path/to/example_spec.rb:37 rspec path/to/example_spec.rb:37


Background: Background:
Given a file named "example_spec.rb" with: Given a file named "example_spec.rb" with:
Expand Down
4 changes: 2 additions & 2 deletions features/command_line/line_number_option.feature
Original file line number Original file line Diff line number Diff line change
@@ -1,8 +1,8 @@
Feature: line number option Feature: --line option


To run a single example or group, you can use the --line option: To run a single example or group, you can use the --line option:


rspec path/to/example_spec.rb --line 37 rspec path/to/example_spec.rb --line 37


Scenario: standard examples Scenario: standard examples
Given a file named "example_spec.rb" with: Given a file named "example_spec.rb" with:
Expand Down
14 changes: 7 additions & 7 deletions features/command_line/tag.feature
Original file line number Original file line Diff line number Diff line change
@@ -1,18 +1,18 @@
Feature: tag option Feature: --tag option


Use the --tag (or -t) option to filter the examples to be run by tag. Use the --tag (or -t) option to filter the examples by tags.


The tag can be a simple name or a name:value pair. In the first case, The tag can be a simple name or a name:value pair. In the first case,
examples with :name => true will be filtered. In the second case, examples examples with :name => true will be filtered. In the second case, examples
with :name => value will be filtered, where value is always a string. with :name => value will be filtered, where value is always a string. In
In both cases, name is converted to a symbol. both cases, name is converted to a symbol.


Tags can also be used to exclude examples by adding a ~ before the tag. Tags can also be used to exclude examples by adding a ~ before the tag. For
For example ~tag will exclude all examples marked with :tag => true and example ~tag will exclude all examples marked with :tag => true and
~tag:value will exclude all examples marked with :tag => value. ~tag:value will exclude all examples marked with :tag => value.


To be compatible with the Cucumber syntax, tags can optionally start with To be compatible with the Cucumber syntax, tags can optionally start with
a @, that will be ignored. an @ symbol, which will be ignored.


Background: Background:
Given a file named "tagged_spec.rb" with: Given a file named "tagged_spec.rb" with:
Expand Down
28 changes: 2 additions & 26 deletions features/configuration/read_options_from_file.feature
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Feature: read command line configuration options from files
""" """
describe "formatter set in custom options file" do describe "formatter set in custom options file" do
it "sets formatter" do it "sets formatter" do
RSpec.configuration.formatter. RSpec.configuration.formatters.first.
should be_a(RSpec::Core::Formatters::DocumentationFormatter) should be_a(RSpec::Core::Formatters::DocumentationFormatter)
end end
end end
Expand Down Expand Up @@ -70,30 +70,6 @@ Feature: read command line configuration options from files
When I run "rspec spec/example_spec.rb --options my.options" When I run "rspec spec/example_spec.rb --options my.options"
Then the output should contain "1 example, 0 failures" Then the output should contain "1 example, 0 failures"


Scenario: formatter set in RSpec.configure overrides .rspec
Given a file named ".rspec" with:
"""
--format progress
"""
And a file named "spec/spec_helper.rb" with:
"""
RSpec.configure {|c| c.formatter = 'documentation'}
"""
And a file named "spec/example_spec.rb" with:
"""
require "spec_helper"
describe "formatter" do
context "when set with RSpec.configure and in spec.opts" do
it "takes the value set in spec.opts" do
RSpec.configuration.formatter.should be_an(RSpec::Core::Formatters::DocumentationFormatter)
end
end
end
"""
When I run "rspec ./spec/example_spec.rb"
Then the output should contain "1 example, 0 failures"

Scenario: using ERB in .rspec Scenario: using ERB in .rspec
Given a file named ".rspec" with: Given a file named ".rspec" with:
""" """
Expand All @@ -103,7 +79,7 @@ Feature: read command line configuration options from files
""" """
describe "formatter" do describe "formatter" do
it "is set to documentation" do it "is set to documentation" do
RSpec.configuration.formatter.should be_an(RSpec::Core::Formatters::DocumentationFormatter) RSpec.configuration.formatters.first.should be_an(RSpec::Core::Formatters::DocumentationFormatter)
end end
end end
""" """
Expand Down
4 changes: 4 additions & 0 deletions features/step_definitions/additional_cli_steps.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@
Then %q{the output should contain "0 failures"} Then %q{the output should contain "0 failures"}
Then %q{the exit status should be 0} Then %q{the exit status should be 0}
end end

Then /^the file "([^"]*)" should contain:$/ do |file, partial_content|
check_file_content(file, partial_content, true)
end
33 changes: 19 additions & 14 deletions lib/rspec/core/configuration.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -263,28 +263,33 @@ def full_description=(description)
filter_run({ :full_description => /#{description}/ }, true) filter_run({ :full_description => /#{description}/ }, true)
end end


attr_writer :formatter_class def add_formatter(formatter_to_use, output=nil)

formatter_class =
def formatter_class
@formatter_class ||= begin
require 'rspec/core/formatters/progress_formatter'
RSpec::Core::Formatters::ProgressFormatter
end
end

def formatter=(formatter_to_use)
self.formatter_class =
built_in_formatter(formatter_to_use) || built_in_formatter(formatter_to_use) ||
custom_formatter(formatter_to_use) || custom_formatter(formatter_to_use) ||
(raise ArgumentError, "Formatter '#{formatter_to_use}' unknown - maybe you meant 'documentation' or 'progress'?.") (raise ArgumentError, "Formatter '#{formatter_to_use}' unknown - maybe you meant 'documentation' or 'progress'?.")

formatters << formatter_class.new(output || self.output)
end end


def formatter alias_method :formatter=, :add_formatter
@formatter ||= formatter_class.new(output)
def formatters
@formatters ||= []
end end


def reporter def reporter
@reporter ||= Reporter.new(formatter) @reporter ||= begin
add_formatter('progress') if formatters.empty?
Reporter.new(*formatters)
end
end

def default_formatter
@default_formatter ||= begin
require 'rspec/core/formatters/progress_formatter'
RSpec::Core::Formatters::ProgressFormatter.new(output)
end
end end


def files_or_directories_to_run=(*files) def files_or_directories_to_run=(*files)
Expand Down
15 changes: 14 additions & 1 deletion lib/rspec/core/configuration_options.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -18,9 +18,15 @@ def configure(config)
keys = options.keys keys = options.keys
keys.unshift(:requires) if keys.delete(:requires) keys.unshift(:requires) if keys.delete(:requires)
keys.unshift(:libs) if keys.delete(:libs) keys.unshift(:libs) if keys.delete(:libs)
formatters = options[:formatters] if keys.delete(:formatters)
keys.each do |key| keys.each do |key|
config.send("#{key}=", options[key]) if config.respond_to?("#{key}=") config.send("#{key}=", options[key]) if config.respond_to?("#{key}=")
end end
if formatters
formatters.each do |pair|
config.add_formatter(*pair)
end
end
end end


def drb_argv def drb_argv
Expand All @@ -30,10 +36,17 @@ def drb_argv
argv << "--backtrace" if options[:full_backtrace] argv << "--backtrace" if options[:full_backtrace]
argv << "--tty" if options[:tty] argv << "--tty" if options[:tty]
argv << "--fail-fast" if options[:fail_fast] argv << "--fail-fast" if options[:fail_fast]
argv << "--format" << options[:formatter] if options[:formatter]
argv << "--line_number" << options[:line_number] if options[:line_number] argv << "--line_number" << options[:line_number] if options[:line_number]
argv << "--options" << options[:custom_options_file] if options[:custom_options_file] argv << "--options" << options[:custom_options_file] if options[:custom_options_file]
argv << "--example" << options[:full_description].source if options[:full_description] argv << "--example" << options[:full_description].source if options[:full_description]
if options[:formatters]
options[:formatters].each do |pair|
argv << "--format" << pair.shift
unless pair.empty?
argv << "--out" << pair.shift
end
end
end
(options[:libs] || []).each do |path| (options[:libs] || []).each do |path|
argv << "-I" << path argv << "-I" << path
end end
Expand Down
18 changes: 12 additions & 6 deletions lib/rspec/core/option_parser.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -47,12 +47,18 @@ def parser(options)
' [d]ocumentation (group and example names)', ' [d]ocumentation (group and example names)',
' [h]tml', ' [h]tml',
' [t]extmate', ' [t]extmate',
' custom formatter class name') do |o| ' custom formatter class name') do |f|
options[:formatter] = o options[:formatters] ||= []
end options[:formatters] << [f]

end
parser.on('-o', '--out FILE', 'output to a file instead of STDOUT') do |o|
options[:output_stream] = File.open(o,'w') parser.on('-o', '--out FILE',
'Write output to a file instead of STDOUT. This option applies',
'to the previously specified --format, or the default format if',
'no format is specified.'
) do |o|
options[:formatters] ||= [['progress']]
options[:formatters].last << File.open(o,'w')
end end


parser.on_tail('-h', '--help', "You're looking at it.") do parser.on_tail('-h', '--help', "You're looking at it.") do
Expand Down
Loading

0 comments on commit a5f9ffd

Please sign in to comment.