# ## Built-in Formatters## * progress (default) - prints dots for passing examples, `F` for failures, `*` for pending# * documentation - prints the docstrings passed to `describe` and `it` methods (and their aliases)# * html# * textmate - html plus links to editor# * json - useful for archiving data for subsequent analysis## The progress formatter is the default, but you can choose any one or more of# the other formatters by passing with the `--format` (or `-f` for short)# command-line option, e.g.## rspec --format documentation## You can also send the output of multiple formatters to different streams, e.g.## rspec --format documentation --format html --out results.html## This example sends the output of the documentation formatter to `$stdout`, and# the output of the html formatter to results.html.## ## Custom Formatters## You can tell RSpec to use a custom formatter by passing its path and name to# the `rspec` commmand. For example, if you define MyCustomFormatter in# path/to/my_custom_formatter.rb, you would type this command:## rspec --require path/to/my_custom_formatter.rb --format MyCustomFormatter## The reporter calls every formatter with this protocol:## * `start(expected_example_count)`# * zero or more of the following# * `example_group_started(group)`# * `example_started(example)`# * `example_passed(example)`# * `example_failed(example)`# * `example_pending(example)`# * `message(string)`# * `stop`# * `start_dump`# * `dump_pending`# * `dump_failures`# * `dump_summary(duration, example_count, failure_count, pending_count)`# * `seed(value)`# * `close`## You can either implement all of those methods or subclass# `RSpec::Core::Formatters::BaseTextFormatter` and override the methods you want# to enhance.## @see RSpec::Core::Formatters::BaseTextFormatter# @see RSpec::Core::ReportermoduleRSpec::Core::Formattersautoload:DocumentationFormatter,'rspec/core/formatters/documentation_formatter'autoload:HtmlFormatter,'rspec/core/formatters/html_formatter'autoload:ProgressFormatter,'rspec/core/formatters/progress_formatter'autoload:JsonFormatter,'rspec/core/formatters/json_formatter'autoload:TextMateFormatter,'rspec/core/formatters/text_mate_formatter'# @api private## `RSpec::Core::Formatters::Loader` is an internal class for# managing formatters used by a particular configuration. It is# not expected to be used directly, but only through the configuration# interface.classLoader# @api privatedefinitialize(reporter)@formatters=[]@reporter=reporter@setup=false@default_formatter='progress'end# @return [Array] the loaded formattersattr_reader:formatters# @return [Reporter] the reporterattr_reader:reporter# @privatedefsetup_default(output_stream,deprecation_stream)if@formatters.empty?add@default_formatter,output_streamendunless@formatters.any?{|formatter|DeprecationFormatter===formatter}addDeprecationFormatter,deprecation_stream,output_streamend@formatters.eachdo|formatter|@reporter.register_listenerformatter,*RSpec::Core::Reporter::NOTIFICATIONSend@setup=trueend# @privatedefadd(formatter_to_use,*paths)formatter_class=find_formatter(formatter_to_use)args=paths.map{|p|p.respond_to?(:puts)?p:file_at(p)}formatter=formatter_class.new(*args)if@setup@reporter.register_listenerformatter,*RSpec::Core::Reporter::NOTIFICATIONSend@formatters<<formatterunlessduplicate_formatter_exists?(formatter)formatterendprivatedeffind_formatter(formatter_to_use)built_in_formatter(formatter_to_use)||custom_formatter(formatter_to_use)||(raiseArgumentError,"Formatter '#{formatter_to_use}' unknown - maybe you meant 'documentation' or 'progress'?.")enddefduplicate_formatter_exists?(new_formatter)@formatters.any?do|formatter|formatter.class===new_formatter&&formatter.output==new_formatter.outputendenddefbuilt_in_formatter(key)casekey.to_swhen'd','doc','documentation'DocumentationFormatterwhen's','n','spec','nested'RSpec.deprecate"Using `#{key.to_s}` as a shortcut for the DocumentationFormatter",:replacement=>"`d`, `doc`, or `documentation`"DocumentationFormatterwhen'h','html'HtmlFormatterwhen'p','progress'ProgressFormatterwhen'j','json'JsonFormatterwhen't','textmate'ifdefined?(::RSpec::Mate::Formatters::TextMateFormatter)RSpec.deprecate"Using the text`#{key.to_s}` as a shortcut for the TextMateFormatter",:replacement=>"`::RSpec::Mate::Formatters::TextMateFormatter`"elseRSpec.deprecate"Using rspec-core's `::RSpec::Core::TextMateFormatter`",:replacement=>"the `rspec-tmbundle` gem and it's `::RSpec::Mate::Formatters::TextMateFormatter`"endTextMateFormatterendenddefcustom_formatter(formatter_ref)ifClass===formatter_refformatter_refelsifstring_const?(formatter_ref)beginformatter_ref.gsub(/^::/,'').split('::').inject(Object){|const,string|const.const_getstring}rescueNameErrorrequire(path_for(formatter_ref))?retry:raiseendendenddefstring_const?(str)str.is_a?(String)&&/\A[A-Z][a-zA-Z0-9_:]*\z/=~strenddefpath_for(const_ref)underscore_with_fix_for_non_standard_rspec_naming(const_ref)enddefunderscore_with_fix_for_non_standard_rspec_naming(string)underscore(string).sub(%r{(^|/)r_spec($|/)},'\\1rspec\\2')end# activesupport/lib/active_support/inflector/methods.rb, line 48defunderscore(camel_cased_word)word=camel_cased_word.to_s.dupword.gsub!(/::/,'/')word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')word.tr!("-","_")word.downcase!wordenddeffile_at(path)FileUtils.mkdir_p(File.dirname(path))File.new(path,'w')endendend