C0 code coverage information
Generated on Mon Aug 13 01:18:55 -0400 2007 with rcov 0.8.0
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.
1 require 'optparse'
2 require 'stringio'
3
4 module Spec
5 module Runner
6 class OptionParser
7 BUILT_IN_FORMATTERS = {
8 'specdoc' => Formatter::SpecdocFormatter,
9 's' => Formatter::SpecdocFormatter,
10 'html' => Formatter::HtmlFormatter,
11 'h' => Formatter::HtmlFormatter,
12 'rdoc' => Formatter::RdocFormatter,
13 'r' => Formatter::RdocFormatter,
14 'progress' => Formatter::ProgressBarFormatter,
15 'p' => Formatter::ProgressBarFormatter,
16 'failing_examples' => Formatter::FailingExamplesFormatter,
17 'e' => Formatter::FailingExamplesFormatter,
18 'failing_behaviours' => Formatter::FailingBehavioursFormatter,
19 'b' => Formatter::FailingBehavioursFormatter
20 }
21
22 COMMAND_LINE = {
23 :diff => ["-D", "--diff [FORMAT]", "Show diff of objects that are expected to be equal when they are not",
24 "Builtin formats: unified|u|context|c",
25 "You can also specify a custom differ class",
26 "(in which case you should also specify --require)"],
27 :colour => ["-c", "--colour", "--color", "Show coloured (red/green) output"],
28 :example => ["-e", "--example [NAME|FILE_NAME]", "Execute example(s) with matching name(s). If the argument is",
29 "the path to an existing file (typically generated by a previous",
30 "run using --format failing_examples:file.txt), then the examples",
31 "on each line of thatfile will be executed. If the file is empty,",
32 "all examples will be run (as if --example was not specified).",
33 " ",
34 "If the argument is not an existing file, then it is treated as",
35 "an example name directly, causing RSpec to run just the example",
36 "matching that name"],
37 :specification => ["-s", "--specification [NAME]", "DEPRECATED - use -e instead", "(This will be removed when autotest works with -e)"],
38 :line => ["-l", "--line LINE_NUMBER", Integer, "Execute behaviout or specification at given line.",
39 "(does not work for dynamically generated specs)"],
40 :format => ["-f", "--format FORMAT[:WHERE]", "Specifies what format to use for output. Specify WHERE to tell",
41 "the formatter where to write the output. All built-in formats",
42 "expect WHERE to be a file name, and will write to STDOUT if it's",
43 "not specified. The --format option may be specified several times",
44 "if you want several outputs",
45 " ",
46 "Builtin formats: ",
47 "progress|p : Text progress",
48 "specdoc|s : Behaviour doc as text",
49 "rdoc|r : Behaviour doc as RDoc",
50 "html|h : A nice HTML report",
51 "failing_examples|e : Write all failing examples - input for --example",
52 "failing_behaviours|b : Write all failing behaviours - input for --example",
53 " ",
54 "FORMAT can also be the name of a custom formatter class",
55 "(in which case you should also specify --require to load it)"],
56 :require => ["-r", "--require FILE", "Require FILE before running specs",
57 "Useful for loading custom formatters or other extensions.",
58 "If this option is used it must come before the others"],
59 :backtrace => ["-b", "--backtrace", "Output full backtrace"],
60 :loadby => ["-L", "--loadby STRATEGY", "Specify the strategy by which spec files should be loaded.",
61 "STRATEGY can currently only be 'mtime' (File modification time)",
62 "By default, spec files are loaded in alphabetical order if --loadby",
63 "is not specified."],
64 :reverse => ["-R", "--reverse", "Run examples in reverse order"],
65 :timeout => ["-t", "--timeout FLOAT", "Interrupt and fail each example that doesn't complete in the",
66 "specified time"],
67 :heckle => ["-H", "--heckle CODE", "If all examples pass, this will mutate the classes and methods",
68 "identified by CODE little by little and run all the examples again",
69 "for each mutation. The intent is that for each mutation, at least",
70 "one example *should* fail, and RSpec will tell you if this is not the",
71 "case. CODE should be either Some::Module, Some::Class or",
72 "Some::Fabulous#method}"],
73 :dry_run => ["-d", "--dry-run", "Invokes formatters without executing the examples."],
74 :options_file => ["-O", "--options PATH", "Read options from a file"],
75 :generate_options => ["-G", "--generate-options PATH", "Generate an options file for --options"],
76 :runner => ["-U", "--runner RUNNER", "Use a custom BehaviourRunner."],
77 :drb => ["-X", "--drb", "Run examples via DRb. (For example against script/spec_server)"],
78 :version => ["-v", "--version", "Show version"],
79 :help => ["-h", "--help", "You're looking at it"]
80 }
81
82 def initialize
83 @spec_parser = SpecParser.new
84 @file_factory = File
85 end
86
87 def create_behaviour_runner(args, err, out, warn_if_no_files)
88 options = parse(args, err, out, warn_if_no_files)
89 # Some exit points in parse (--generate-options, --drb) don't return the options,
90 # but hand over control. In that case we don't want to continue.
91 return nil unless options.is_a?(Options)
92 options.configure
93 options.behaviour_runner
94 end
95
96 def parse(args, err, out, warn_if_no_files)
97 options_file = nil
98 args_copy = args.dup
99 options = Options.new(err, out)
100
101 opts = ::OptionParser.new do |opts|
102 opts.banner = "Usage: spec (FILE|DIRECTORY|GLOB)+ [options]"
103 opts.separator ""
104
105 def opts.rspec_on(name, &block)
106 on(*COMMAND_LINE[name], &block)
107 end
108
109 opts.rspec_on(:diff) {|diff| options.parse_diff(diff)}
110
111 opts.rspec_on(:colour) {options.colour = true}
112
113 opts.rspec_on(:example) {|example| options.parse_example(example)}
114
115 opts.rspec_on(:specification) {|example| options.parse_example(example)}
116
117 opts.rspec_on(:line) {|line_number| options.line_number = line_number.to_i}
118
119 opts.rspec_on(:format) {|format| options.parse_format(format)}
120
121 opts.rspec_on(:require) {|req| options.parse_require(req)}
122
123 opts.rspec_on(:backtrace) {options.backtrace_tweaker = NoisyBacktraceTweaker.new}
124
125 opts.rspec_on(:loadby) {|loadby| options.loadby = loadby}
126
127 opts.rspec_on(:reverse) {options.reverse = true}
128
129 opts.rspec_on(:timeout) {|timeout| options.timeout = timeout.to_f}
130
131 opts.rspec_on(:heckle) {|heckle| options.parse_heckle(heckle)}
132
133 opts.rspec_on(:dry_run) {options.dry_run = true}
134
135 opts.rspec_on(:options_file) do |options_file|
136 return parse_options_file(options_file, out, err, args_copy, warn_if_no_files)
137 end
138
139 opts.rspec_on(:generate_options) do |options_file|
140 options.parse_generate_options(options_file, args_copy, out)
141 end
142
143 opts.rspec_on(:runner) do |runner|
144 options.runner_arg = runner
145 end
146
147 opts.rspec_on(:drb) do
148 return parse_drb(args_copy, out, err, warn_if_no_files)
149 end
150
151 opts.rspec_on(:version) {parse_version(out)}
152
153 opts.on_tail(*COMMAND_LINE[:help]) {parse_help(opts, out)}
154 end
155 opts.parse!(args)
156
157 if args.empty? && warn_if_no_files
158 err.puts "No files specified."
159 err.puts opts
160 exit(6) if err == $stderr
161 end
162
163 if options.line_number
164 set_spec_from_line_number(options, args, err)
165 end
166
167 if options.formatters.empty?
168 options.formatters << Formatter::ProgressBarFormatter.new(out)
169 end
170
171 options
172 end
173
174 def parse_options_file(options_file, out_stream, error_stream, args_copy, warn_if_no_files)
175 # Remove the --options option and the argument before writing to file
176 index = args_copy.index("-O") || args_copy.index("--options")
177 args_copy.delete_at(index)
178 args_copy.delete_at(index)
179
180 new_args = args_copy + IO.readlines(options_file).map {|l| l.chomp.split " "}.flatten
181 return CommandLine.run(new_args, error_stream, out_stream, true, warn_if_no_files)
182 end
183
184 def parse_drb(args_copy, out_stream, error_stream, warn_if_no_files)
185 # Remove the --drb option
186 index = args_copy.index("-X") || args_copy.index("--drb")
187 args_copy.delete_at(index)
188
189 return DrbCommandLine.run(args_copy, error_stream, out_stream, true, warn_if_no_files)
190 end
191
192 def parse_version(out_stream)
193 out_stream.puts ::Spec::VERSION::DESCRIPTION
194 exit if out_stream == $stdout
195 end
196
197 def parse_help(opts, out_stream)
198 out_stream.puts opts
199 exit if out_stream == $stdout
200 end
201
202 def set_spec_from_line_number(options, args, err)
203 if options.examples.empty?
204 if args.length == 1
205 if @file_factory.file?(args[0])
206 source = @file_factory.open(args[0])
207 example = @spec_parser.spec_name_for(source, options.line_number)
208 options.parse_example(example)
209 elsif @file_factory.directory?(args[0])
210 err.puts "You must specify one file, not a directory when using the --line option"
211 exit(1) if err == $stderr
212 else
213 err.puts "#{args[0]} does not exist"
214 exit(2) if err == $stderr
215 end
216 else
217 err.puts "Only one file can be specified when using the --line option: #{args.inspect}"
218 exit(3) if err == $stderr
219 end
220 else
221 err.puts "You cannot use both --line and --example"
222 exit(4) if err == $stderr
223 end
224 end
225 end
226 end
227 end
Generated using the rcov code coverage analysis tool for Ruby version 0.8.0.