Geminstaller C0 Coverage Information - RCov

/Users/woolley/.rvm/gems/ruby-1.8.7-p174@geminstaller/gems/rspec-1.3.0/lib/spec/runner/options.rb

Name Total Lines Lines of Code Total Coverage Code Coverage
/Users/woolley/.rvm/gems/ruby-1.8.7-p174@geminstaller/gems/rspec-1.3.0/lib/spec/runner/options.rb 405 345
74.81%
70.43%

Key

Code reported as executed by Ruby looks like this...and this: this line is also marked as covered.Lines considered as run by rcov, but not reported by Ruby, look like this,and this: these lines were inferred by rcov (using simple heuristics).Finally, here's a line marked as not executed.

Coverage Details

1 require 'ostruct'
2 
3 module Spec
4   module Runner
5     class Options
6       FILE_SORTERS = {
7         'mtime' => lambda {|file_a, file_b| File.mtime(file_b) <=> File.mtime(file_a)}
8       }
9 
10       EXAMPLE_FORMATTERS = { # Load these lazily for better speed
11                 'silent' => ['spec/runner/formatter/silent_formatter',                 'Formatter::SilentFormatter'],
12                      'l' => ['spec/runner/formatter/silent_formatter',                 'Formatter::SilentFormatter'],
13                'specdoc' => ['spec/runner/formatter/specdoc_formatter',                'Formatter::SpecdocFormatter'],
14                      's' => ['spec/runner/formatter/specdoc_formatter',                'Formatter::SpecdocFormatter'],
15                 'nested' => ['spec/runner/formatter/nested_text_formatter',            'Formatter::NestedTextFormatter'],
16                      'n' => ['spec/runner/formatter/nested_text_formatter',            'Formatter::NestedTextFormatter'],
17                   'html' => ['spec/runner/formatter/html_formatter',                   'Formatter::HtmlFormatter'],
18                      'h' => ['spec/runner/formatter/html_formatter',                   'Formatter::HtmlFormatter'],
19               'progress' => ['spec/runner/formatter/progress_bar_formatter',           'Formatter::ProgressBarFormatter'],
20                      'p' => ['spec/runner/formatter/progress_bar_formatter',           'Formatter::ProgressBarFormatter'],
21       'failing_examples' => ['spec/runner/formatter/failing_examples_formatter',       'Formatter::FailingExamplesFormatter'],
22                      'e' => ['spec/runner/formatter/failing_examples_formatter',       'Formatter::FailingExamplesFormatter'],
23 'failing_example_groups' => ['spec/runner/formatter/failing_example_groups_formatter', 'Formatter::FailingExampleGroupsFormatter'],
24                      'g' => ['spec/runner/formatter/failing_example_groups_formatter', 'Formatter::FailingExampleGroupsFormatter'],
25                'profile' => ['spec/runner/formatter/profile_formatter',                'Formatter::ProfileFormatter'],
26                      'o' => ['spec/runner/formatter/profile_formatter',                'Formatter::ProfileFormatter'],
27               'textmate' => ['spec/runner/formatter/text_mate_formatter',              'Formatter::TextMateFormatter']
28       }
29 
30       attr_accessor(
31         :autospec, # hack to tell
32         :filename_pattern,
33         :backtrace_tweaker,
34         :context_lines,
35         :diff_format,
36         :dry_run,
37         :profile,
38         :heckle_runner,
39         :debug,
40         :line_number,
41         :loadby,
42         :reporter,
43         :reverse,
44         :timeout,
45         :verbose,
46         :user_input_for_runner,
47         :error_stream,
48         :output_stream,
49         # TODO: BT - Figure out a better name
50         :argv
51       )
52       attr_reader :colour, :differ_class, :files, :examples, :example_groups
53       attr_writer :drb_port
54       
55       def initialize(error_stream, output_stream)
56         @error_stream = error_stream
57         @output_stream = output_stream
58         @filename_pattern = "**/*_spec.rb"
59         @backtrace_tweaker = QuietBacktraceTweaker.new
60         @examples = []
61         @colour = false
62         @profile = false
63         @dry_run = false
64         @debug = false
65         @reporter = Reporter.new(self)
66         @context_lines = 3
67         @diff_format  = :unified
68         @files = []
69         @example_groups = []
70         @result = nil
71         @examples_run = false
72         @examples_should_be_run = nil
73         @user_input_for_runner = nil
74         @after_suite_parts = []
75         @files_loaded = false
76         @out_used = nil
77       end
78 
79       def add_example_group(example_group)
80         @example_groups << example_group
81       end
82 
83       def line_number_requested?
84         !!line_number
85       end
86 
87       def example_line
88         Spec::Runner::LineNumberQuery.new(self).example_line_for(files.first, line_number)
89       end
90 
91       def remove_example_group(example_group)
92         @example_groups.delete(example_group)
93       end
94 
95       def require_ruby_debug
96         require 'rubygems' unless ENV['NO_RUBYGEMS']
97         require 'ruby-debug'
98       end
99 
100       def project_root # :nodoc:
101         require 'pathname'
102         @project_root ||= determine_project_root
103       end
104 
105       def determine_project_root # :nodoc:
106         # This is borrowed (slightly modified) from Scott Taylors
107         # project_path project:
108         #   http://github.com/smtlaissezfaire/project_path
109         Pathname(File.expand_path('.')).ascend do |path|
110           if File.exists?(File.join(path, "spec"))
111             return path
112           end
113         end
114       end
115 
116       def add_dir_from_project_root_to_load_path(dir, load_path=$LOAD_PATH) # :nodoc:
117         return if project_root.nil?
118         full_dir = File.join(project_root, dir)
119         load_path.unshift full_dir unless load_path.include?(full_dir)
120       end
121 
122       def run_examples
123         require_ruby_debug if debug
124         return true unless examples_should_be_run?
125         success = true
126         begin
127           runner = custom_runner || ExampleGroupRunner.new(self)
128 
129           unless @files_loaded
130             ['spec','lib'].each do |dir|
131               add_dir_from_project_root_to_load_path(dir)
132             end
133             runner.load_files(files_to_load)
134             @files_loaded = true
135           end
136 
137           define_predicate_matchers
138           plugin_mock_framework
139           ignore_backtrace_patterns
140 
141           # TODO - this has to happen after the files get loaded,
142           # otherwise the before_suite_parts are not populated
143           # from the configuration. There is no spec for this
144           # directly, but features/before_and_after_blocks/before_and_after_blocks.story
145           # will fail if this happens before the files are loaded.
146           before_suite_parts.each { |part| part.call }
147 
148           if example_groups.empty?
149             true
150           else
151             set_spec_from_line_number if line_number
152             success = runner.run
153             @examples_run = true
154             heckle if heckle_runner
155             success
156           end
157         ensure
158           after_suite_parts.each do |part|
159             part.arity < 1 ? part.call : part.call(success)
160           end
161         end
162       end
163 
164       def before_suite_parts
165         Spec::Example::BeforeAndAfterHooks.before_suite_parts
166       end
167 
168       def after_suite_parts
169         Spec::Example::BeforeAndAfterHooks.after_suite_parts
170       end
171 
172       def examples_run?
173         @examples_run
174       end
175 
176       def examples_should_not_be_run
177         @examples_should_be_run = false
178       end
179 
180       def mock_framework
181         # TODO - don't like this dependency - perhaps store this in here instead?
182         Spec::Runner.configuration.mock_framework
183       end
184 
185       def colour=(colour)
186         @colour = colour
187         if @colour && RUBY_PLATFORM =~ /mswin|mingw/ ;\
188           begin ;\
189             replace_output = @output_stream.equal?($stdout) ;\
190             require 'rubygems' unless ENV['NO_RUBYGEMS'] ;\
191             require 'Win32/Console/ANSI' ;\
192             @output_stream = $stdout if replace_output ;\
193           rescue LoadError ;\
194             warn "You must 'gem install win32console' to use colour on Windows" ;\
195             @colour = false ;\
196           end
197         end
198       end
199 
200       def parse_diff(format)
201         case format
202         when :context, 'context', 'c'
203           @diff_format  = :context
204           default_differ
205         when :unified, 'unified', 'u', '', nil
206           @diff_format  = :unified
207           default_differ
208         else
209           @diff_format  = :custom
210           self.differ_class = load_class(format, 'differ', '--diff')
211         end
212       end
213 
214       def parse_example(example)
215         if(File.file?(example))
216           @examples = [File.open(example).read.split("\n")].flatten
217         else
218           @examples = [example]
219         end
220       end
221 
222       def parse_format(format_arg)
223         format, where = ClassAndArgumentsParser.parse(format_arg)
224         unless where
225           raise "When using several --format options only one of them can be without a file" if @out_used
226           where = @output_stream
227           @out_used = true
228         end
229         @format_options ||= []
230         @format_options << [format, where]
231       end
232 
233       def formatters
234         @format_options ||= [['progress', @output_stream]]
235         @formatters ||= load_formatters(@format_options, EXAMPLE_FORMATTERS)
236       end
237 
238       def load_formatters(format_options, formatters)
239         format_options.map do |format, where|
240           formatter_type = if formatters[format]
241             require formatters[format][0]
242             eval(formatters[format][1], binding, __FILE__, __LINE__)
243           else
244             load_class(format, 'formatter', '--format')
245           end
246           formatter_type.new(formatter_options, where)
247         end
248       end
249 
250       def formatter_options
251         @formatter_options ||= OpenStruct.new(
252           :colour   => colour,
253           :autospec => autospec,
254           :dry_run  => dry_run
255         )
256       end
257 
258       def which_heckle_runner
259         ([/mswin/, /java/].detect{|p| p =~ RUBY_PLATFORM} || Spec::Ruby.version.to_f == 1.9) ? "spec/runner/heckle_runner_unsupported" : "spec/runner/heckle_runner"
260       end
261 
262       def load_heckle_runner(heckle)
263         @format_options ||= [['silent', @output_stream]]
264         require which_heckle_runner
265         @heckle_runner = ::Spec::Runner::HeckleRunner.new(heckle)
266       end
267 
268       def number_of_examples
269         return examples.size unless examples.empty?
270         @example_groups.inject(0) {|sum, group| sum + group.number_of_examples}
271       end
272 
273       def files_to_load
274         result = []
275         sorted_files.each do |file|
276           if File.directory?(file)
277             filename_pattern.split(",").each do |pattern|
278               result += Dir[File.expand_path("#{file}/#{pattern.strip}")]
279             end
280           elsif File.file?(file)
281             result << file
282           else
283             raise "File or directory not found: #{file}"
284           end
285         end
286         result
287       end
288 
289       def dry_run?
290         @dry_run == true
291       end
292 
293       def drb_port
294         @drb_port.to_i if defined?(@drb_port)
295       end
296       
297     protected
298 
299       def define_predicate_matchers
300         Spec::Runner.configuration.predicate_matchers.each_pair do |matcher_method, method_on_object|
301           Spec::Example::ExampleMethods::__send__ :define_method, matcher_method do |*args|
302             eval("be_#{method_on_object.to_s.gsub('?','')}(*args)")
303           end
304         end
305       end
306 
307       def plugin_mock_framework
308         case mock_framework
309         when Module
310           Spec::Example::ExampleMethods.__send__ :include, mock_framework
311         else
312           require mock_framework
313           Spec::Example::ExampleMethods.__send__ :include, Spec::Adapters::MockFramework
314         end
315       end
316 
317       def ignore_backtrace_patterns
318         @backtrace_tweaker.ignore_patterns Spec::Runner.configuration.ignored_backtrace_patterns
319       end
320 
321       def examples_should_be_run?
322         return @examples_should_be_run unless @examples_should_be_run.nil?
323         @examples_should_be_run = true
324       end
325 
326       def differ_class=(klass)
327         return unless klass
328         @differ_class = klass
329         Spec::Expectations.differ = self.differ_class.new(self)
330       end
331 
332       def load_class(name, kind, option)
333         if name =~ /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/
334           arg = $2 == "" ? nil : $2
335           [$1, arg]
336         else
337           m = "#{name.inspect} is not a valid class name"
338           @error_stream.puts m
339           raise m
340         end
341         begin
342           eval(name, binding, __FILE__, __LINE__)
343         rescue NameError => e
344           @error_stream.puts "Couldn't find #{kind} class #{name}"
345           @error_stream.puts "Make sure the --require option is specified *before* #{option}"
346           if $_spec_spec ; raise e ; else exit(1) ; end
347         end
348       end
349 
350       def custom_runner
351         return nil unless custom_runner?
352         klass_name, arg = ClassAndArgumentsParser.parse(user_input_for_runner)
353         runner_type = load_class(klass_name, 'example group runner', '--runner')
354         return runner_type.new(self, arg)
355       end
356 
357       def custom_runner?
358         return user_input_for_runner ? true : false
359       end
360 
361       def heckle
362         heckle_runner = self.heckle_runner
363         self.heckle_runner = nil
364         heckle_runner.heckle_with
365       end
366 
367       def sorted_files
368         return sorter ? files.sort(&sorter) : files
369       end
370 
371       def sorter
372         FILE_SORTERS[loadby]
373       end
374 
375       def default_differ
376         require 'spec/runner/differs/default'
377         self.differ_class = ::Spec::Expectations::Differs::Default
378       end
379 
380       def set_spec_from_line_number
381         if examples.empty?
382           if files.length == 1
383             if File.directory?(files[0])
384               error_stream.puts "You must specify one file, not a directory when providing a line number"
385               exit(1) if stderr?
386             else
387               example = LineNumberQuery.new(self).spec_name_for(files[0], line_number)
388               @examples = [example]
389             end
390           else
391             error_stream.puts "Only one file can be specified when providing a line number: #{files.inspect}"
392             exit(3) if stderr?
393           end
394         else
395           error_stream.puts "You cannot use --example and specify a line number"
396           exit(4) if stderr?
397         end
398       end
399 
400       def stderr?
401         @error_stream == $stderr
402       end
403     end
404   end
405 end

Generated on Mon May 10 23:40:28 -0700 2010 with rcov 0.9.8