rspec 0.9.1 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGES CHANGED
@@ -1,5 +1,14 @@
1
1
  = RSpec Changelog
2
2
 
3
+ == Version 0.9.2
4
+ This is a quick maintenance release.
5
+
6
+ * Added some website love
7
+ * Fixed [#10542] reverse predicate matcher syntax
8
+ * Added a spec:translate Rake task to make 0.9 translation easier with Spec:Rails
9
+ * Better translation of should_redirect_to
10
+ * Fixed --colour support for Windows. This is a regression that was introduced in 0.9.1
11
+
3
12
  == Version 0.9.1
4
13
 
5
14
  This release introduces #describe and #it (aliased as #context and #specify for
data/EXAMPLES.rd CHANGED
@@ -99,6 +99,6 @@
99
99
  # * RSpec should be able to access TestCase methods
100
100
  # * RSpec should be able to accept included modules
101
101
 
102
- Finished in 0.046798 seconds
102
+ Finished in 0.045762 seconds
103
103
 
104
104
  74 examples, 0 failures
data/README CHANGED
@@ -34,7 +34,7 @@ do the following:
34
34
  rake gem
35
35
  gem install pkg/rspec-0.x.x.gem (you may have to sudo)
36
36
 
37
- == Running the specs ==
37
+ == Running RSpec's specs
38
38
  In order to run RSpec's full suite of specs (rake pre_commit) you must install the following gems:
39
39
 
40
40
  * rake # Runs the build script
data/bin/spec_translator CHANGED
@@ -1,3 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ raise "\n\nUsage: spec_translator from_dir to_dir\n\n" if ARGV.size != 2
1
3
  $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
2
4
  require 'spec/translator'
3
5
  t = ::Spec::Translator.new
@@ -21,14 +21,19 @@ describe "State created in before(:all)" do
21
21
 
22
22
  it "should not have sideffects" do
23
23
  @sideeffect.should == 1
24
- $global.should == 1
24
+ $global.should == 2
25
25
  @isolated.should == 1
26
26
 
27
27
  @sideeffect += 1
28
28
  @isolated += 1
29
29
  end
30
+
31
+ after :each do
32
+ $global += 1
33
+ end
30
34
 
31
35
  after :all do
36
+ $global.should == 3
32
37
  $global = 0
33
38
  end
34
39
  end
@@ -50,13 +50,13 @@ module Spec
50
50
  # end
51
51
  #
52
52
  # describe Fish do
53
- # predicate_matchers[:can_swim?] = :swim
53
+ # predicate_matchers[:swim] = :can_swim?
54
54
  # it "should swim" do
55
55
  # Fish.new.should swim
56
56
  # end
57
57
  # end
58
58
  def predicate_matchers
59
- @predicate_matchers ||= {:exist? => :exist}
59
+ @predicate_matchers ||= {:exist => :exist?}
60
60
  end
61
61
 
62
62
  def define_predicate_matchers(hash=nil) # :nodoc:
@@ -64,7 +64,7 @@ module Spec
64
64
  define_predicate_matchers(predicate_matchers)
65
65
  define_predicate_matchers(Spec::Runner.configuration.predicate_matchers)
66
66
  else
67
- hash.each_pair do |method_on_object, matcher_method|
67
+ hash.each_pair do |matcher_method, method_on_object|
68
68
  define_method matcher_method do |*args|
69
69
  eval("be_#{method_on_object.to_s.gsub('?','')}(*args)")
70
70
  end
@@ -14,6 +14,8 @@ module Spec
14
14
  super(where)
15
15
  if where.is_a?(String)
16
16
  @output = File.open(where, 'w')
17
+ elsif where == STDOUT
18
+ @output = Kernel
17
19
  else
18
20
  @output = where
19
21
  end
@@ -38,7 +40,6 @@ module Spec
38
40
  @output.puts magenta(failure.exception.message)
39
41
  end
40
42
  @output.puts format_backtrace(failure.exception.backtrace)
41
- @output.flush
42
43
  end
43
44
 
44
45
  def dump_summary(duration, example_count, failure_count)
@@ -9,7 +9,6 @@ module Spec
9
9
  def example_failed(name, counter, failure)
10
10
  unless @behaviour_name.nil?
11
11
  @output.puts @behaviour_name
12
- @output.flush
13
12
  @behaviour_name = nil
14
13
  end
15
14
  end
@@ -8,7 +8,6 @@ module Spec
8
8
 
9
9
  def example_failed(name, counter, failure)
10
10
  @output.puts "#{@behaviour_name} #{name}"
11
- @output.flush
12
11
  end
13
12
 
14
13
  def dump_failure(counter, failure)
@@ -7,6 +7,7 @@ module Spec
7
7
  super
8
8
  @current_behaviour_number = 0
9
9
  @current_example_number = 0
10
+ @html_header = true
10
11
  end
11
12
 
12
13
  # The number of the currently running behaviour
@@ -22,10 +23,10 @@ module Spec
22
23
  def start(example_count)
23
24
  @example_count = example_count
24
25
 
25
- @output.puts HEADER_1
26
- @output.puts extra_header_content unless extra_header_content.nil?
27
- @output.puts HEADER_2
28
- @output.flush
26
+ if(@html_header)
27
+ @output.puts HTML_HEADER
28
+ end
29
+ @output.puts REPORT_HEADER
29
30
  end
30
31
 
31
32
  def add_behaviour(name)
@@ -34,31 +35,28 @@ module Spec
34
35
  @output.puts " </dl>"
35
36
  @output.puts "</div>"
36
37
  end
37
- @output.puts "<div class=\"context\">"
38
+ @output.puts "<div class=\"behaviour\">"
38
39
  @output.puts " <dl>"
39
- @output.puts " <dt id=\"context_#{current_behaviour_number}\">#{escape(name)}</dt>"
40
- @output.flush
40
+ @output.puts " <dt id=\"behaviour_#{current_behaviour_number}\">#{escape(name)}</dt>"
41
41
  end
42
42
 
43
43
  def start_dump
44
44
  @output.puts " </dl>"
45
45
  @output.puts "</div>"
46
- @output.flush
47
46
  end
48
47
 
49
48
  def example_passed(name)
50
49
  @current_example_number += 1
51
50
  move_progress
52
51
  @output.puts " <dd class=\"spec passed\"><span class=\"passed_spec_name\">#{escape(name)}</span></dd>"
53
- @output.flush
54
52
  end
55
53
 
56
54
  def example_failed(name, counter, failure)
57
55
  extra = extra_failure_content(failure)
58
56
 
59
57
  @current_example_number += 1
60
- @output.puts " <script type=\"text/javascript\">makeRed('header');</script>"
61
- @output.puts " <script type=\"text/javascript\">makeRed('context_#{current_behaviour_number}');</script>"
58
+ @output.puts " <script type=\"text/javascript\">makeRed('rspec-header');</script>"
59
+ @output.puts " <script type=\"text/javascript\">makeRed('behaviour_#{current_behaviour_number}');</script>"
62
60
  move_progress
63
61
  @output.puts " <dd class=\"spec failed\">"
64
62
  @output.puts " <span class=\"failed_spec_name\">#{escape(name)}</span>"
@@ -68,12 +66,6 @@ module Spec
68
66
  @output.puts extra unless extra == ""
69
67
  @output.puts " </div>"
70
68
  @output.puts " </dd>"
71
- @output.flush
72
- end
73
-
74
- # Override this method if you wish to output extra HTML in the header
75
- #
76
- def extra_header_content
77
69
  end
78
70
 
79
71
  # Override this method if you wish to output extra HTML for a failed spec. For example, you
@@ -104,12 +96,14 @@ module Spec
104
96
  @output.puts "<script type=\"text/javascript\">document.getElementById('duration').innerHTML = \"Finished in <strong>#{duration} seconds</strong>\";</script>"
105
97
  @output.puts "<script type=\"text/javascript\">document.getElementById('totals').innerHTML = \"#{totals}\";</script>"
106
98
  @output.puts "</div>"
107
- @output.puts "</body>"
108
- @output.puts "</html>"
109
- @output.flush
99
+ @output.puts "</div>"
100
+ if(@html_header)
101
+ @output.puts "</body>"
102
+ @output.puts "</html>"
103
+ end
110
104
  end
111
105
 
112
- HEADER_1 = <<-EOF
106
+ HTML_HEADER = <<-EOF
113
107
  <?xml version="1.0" encoding="iso-8859-1"?>
114
108
  <!DOCTYPE html
115
109
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
@@ -121,28 +115,32 @@ module Spec
121
115
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
122
116
  <meta http-equiv="Expires" content="-1" />
123
117
  <meta http-equiv="Pragma" content="no-cache" />
118
+ <style type="text/css">
119
+ body {
120
+ margin: 0; padding: 0;
121
+ background: #fff;
122
+ }
123
+ </style>
124
+ </head>
125
+ <body>
124
126
  EOF
125
127
 
126
- HEADER_2 = <<-EOF
128
+ REPORT_HEADER = <<-EOF
129
+ <div class="rspec-report">
127
130
  <script type="text/javascript">
128
131
  function moveProgressBar(percentDone) {
129
- document.getElementById("header").style.width = percentDone +"%";
132
+ document.getElementById("rspec-header").style.width = percentDone +"%";
130
133
  }
131
134
  function makeRed(element_id) {
132
135
  document.getElementById(element_id).style.background = '#C40D0D';
133
136
  }
134
137
  </script>
135
138
  <style type="text/css">
136
- body {
137
- margin: 0; padding: 0;
138
- background: #fff;
139
- }
140
-
141
- #header {
139
+ #rspec-header {
142
140
  background: #65C400; color: #fff;
143
141
  }
144
142
 
145
- h1 {
143
+ div.rspec-report h1 {
146
144
  margin: 0 0 10px;
147
145
  padding: 10px;
148
146
  font: bold 18px "Lucida Grande", Helvetica, sans-serif;
@@ -165,7 +163,7 @@ EOF
165
163
  font-size: 14px;
166
164
  }
167
165
 
168
- .context {
166
+ .behaviour {
169
167
  margin: 0 10px 5px;
170
168
  background: #fff;
171
169
  }
@@ -217,37 +215,35 @@ EOF
217
215
  padding: 0.1em 0 0.2em 0;
218
216
  }
219
217
 
220
- .keyword { color: #FF6600; }
221
- .constant { color: #339999; }
222
- .attribute { color: white; }
223
- .global { color: white; }
224
- .module { color: white; }
225
- .class { color: white; }
226
- .string { color: #66FF00; }
227
- .ident { color: white; }
228
- .method { color: #FFCC00; }
229
- .number { color: white; }
230
- .char { color: white; }
231
- .comment { color: #9933CC; }
232
- .symbol { color: white; }
233
- .regex { color: #44B4CC; }
234
- .punct { color: white; }
235
- .escape { color: white; }
236
- .interp { color: white; }
237
- .expr { color: white; }
218
+ pre.ruby .keyword { color: #FF6600; }
219
+ pre.ruby .constant { color: #339999; }
220
+ pre.ruby .attribute { color: white; }
221
+ pre.ruby .global { color: white; }
222
+ pre.ruby .module { color: white; }
223
+ pre.ruby .class { color: white; }
224
+ pre.ruby .string { color: #66FF00; }
225
+ pre.ruby .ident { color: white; }
226
+ pre.ruby .method { color: #FFCC00; }
227
+ pre.ruby .number { color: white; }
228
+ pre.ruby .char { color: white; }
229
+ pre.ruby .comment { color: #9933CC; }
230
+ pre.ruby .symbol { color: white; }
231
+ pre.ruby .regex { color: #44B4CC; }
232
+ pre.ruby .punct { color: white; }
233
+ pre.ruby .escape { color: white; }
234
+ pre.ruby .interp { color: white; }
235
+ pre.ruby .expr { color: white; }
238
236
 
239
- .offending { background-color: gray; }
240
- .linenum {
237
+ pre.ruby .offending { background-color: gray; }
238
+ pre.ruby .linenum {
241
239
  width: 75px;
242
240
  padding: 0.1em 1em 0.2em 0;
243
241
  color: #000000;
244
242
  background-color: #FFFBD3;
245
243
  }
246
244
  </style>
247
- </head>
248
- <body>
249
245
 
250
- <div id="header">
246
+ <div id="rspec-header">
251
247
  <h1>RSpec Results</h1>
252
248
 
253
249
  <div id="summary">
@@ -256,7 +252,7 @@ EOF
256
252
  </div>
257
253
  </div>
258
254
 
259
- <div id="results">
255
+ <div class="results">
260
256
  EOF
261
257
  end
262
258
  end
@@ -7,17 +7,14 @@ module Spec
7
7
 
8
8
  def example_failed(name, counter, failure)
9
9
  @output.print failure.expectation_not_met? ? red('F') : magenta('F')
10
- @output.flush
11
10
  end
12
11
 
13
12
  def example_passed(name)
14
13
  @output.print green('.')
15
- @output.flush
16
14
  end
17
15
 
18
16
  def start_dump
19
17
  @output.puts
20
- @output.flush
21
18
  end
22
19
  end
23
20
  end
@@ -4,17 +4,14 @@ module Spec
4
4
  class RdocFormatter < BaseTextFormatter
5
5
  def add_behaviour(name)
6
6
  @output.print "# #{name}\n"
7
- @output.flush
8
7
  end
9
8
 
10
9
  def example_passed(name)
11
10
  @output.print "# * #{name}\n"
12
- @output.flush
13
11
  end
14
12
 
15
13
  def example_failed(name, counter, failure)
16
14
  @output.print "# * #{name} [#{counter} - FAILED]\n"
17
- @output.flush
18
15
  end
19
16
  end
20
17
  end
@@ -5,17 +5,14 @@ module Spec
5
5
  def add_behaviour(name)
6
6
  @output.puts
7
7
  @output.puts name
8
- @output.flush
9
8
  end
10
9
 
11
10
  def example_failed(name, counter, failure)
12
11
  @output.puts failure.expectation_not_met? ? red("- #{name} (FAILED - #{counter})") : magenta("- #{name} (ERROR - #{counter})")
13
- @output.flush
14
12
  end
15
13
 
16
14
  def example_passed(name)
17
15
  @output.print green("- #{name}\n")
18
- @output.flush
19
16
  end
20
17
  end
21
18
  end
@@ -19,6 +19,66 @@ module Spec
19
19
  'b' => Formatter::FailingBehavioursFormatter
20
20
  }
21
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
+
22
82
  def initialize
23
83
  @spec_parser = SpecParser.new
24
84
  @file_factory = File
@@ -29,234 +89,67 @@ module Spec
29
89
  # Some exit points in parse (--generate-options, --drb) don't return the options,
30
90
  # but hand over control. In that case we don't want to continue.
31
91
  return nil unless options.is_a?(Options)
32
-
33
- options.formatters.each do |formatter|
34
- formatter.colour = options.colour if formatter.respond_to?(:colour=)
35
- formatter.dry_run = options.dry_run if formatter.respond_to?(:dry_run=)
36
- end
37
- options.reporter = Reporter.new(options.formatters, options.backtrace_tweaker)
38
-
39
- # this doesn't really belong here.
40
- # it should, but the way things are coupled, it doesn't
41
- if options.differ_class
42
- Spec::Expectations.differ = options.differ_class.new(options.diff_format, options.context_lines, options.colour)
43
- end
44
-
45
- unless options.generate
46
- if options.runner_type
47
- options.runner_type.new(options)
48
- else
49
- BehaviourRunner.new(options)
50
- end
51
- end
92
+ options.create_behaviour_runner
52
93
  end
53
94
 
54
95
  def parse(args, err, out, warn_if_no_files)
55
96
  options_file = nil
56
97
  args_copy = args.dup
57
98
  options = Options.new
58
- options.formatters = []
59
- options.backtrace_tweaker = QuietBacktraceTweaker.new
60
- options.examples = []
61
99
 
62
100
  opts = ::OptionParser.new do |opts|
63
101
  opts.banner = "Usage: spec (FILE|DIRECTORY|GLOB)+ [options]"
64
102
  opts.separator ""
65
103
 
66
- opts.on("-D", "--diff [FORMAT]", "Show diff of objects that are expected to be equal when they are not",
67
- "Builtin formats: unified|u|context|c",
68
- "You can also specify a custom differ class",
69
- "(in which case you should also specify --require)") do |format|
104
+ def opts.rspec_on(name, &block)
105
+ on(*COMMAND_LINE[name], &block)
106
+ end
70
107
 
71
- # TODO make context_lines settable
72
- options.context_lines = 3
108
+ opts.rspec_on(:diff) {|diff| options.parse_diff(diff, out, err)}
73
109
 
74
- case format
75
- when 'context', 'c'
76
- options.diff_format = :context
77
- when 'unified', 'u', '', nil
78
- options.diff_format = :unified
79
- end
110
+ opts.rspec_on(:colour) {options.colour = true}
80
111
 
81
- if [:context,:unified].include? options.diff_format
82
- require 'spec/expectations/differs/default'
83
- options.differ_class = Spec::Expectations::Differs::Default
84
- else
85
- begin
86
- options.diff_format = :custom
87
- options.differ_class = eval(format)
88
- rescue NameError
89
- err.puts "Couldn't find differ class #{format}"
90
- err.puts "Make sure the --require option is specified *before* --diff"
91
- exit if out == $stdout
92
- end
93
- end
112
+ opts.rspec_on(:example) {|example| options.parse_example(example)}
94
113
 
95
- end
96
-
97
- opts.on("-c", "--colour", "--color", "Show coloured (red/green) output") do
98
- options.colour = true
99
- end
100
-
101
- opts.on("-e", "--example [NAME|FILE_NAME]", "Execute example(s) with matching name(s). If the argument is",
102
- "the path to an existing file (typically generated by a previous",
103
- "run using --format failing_examples:file.txt), then the examples",
104
- "on each line of that file will be executed. If the file is empty,",
105
- "all examples will be run (as if --example was not specified).",
106
- " ",
107
- "If the argument is not an existing file, then it is treated as",
108
- "an example name directly, causing RSpec to run just the example",
109
- "matching that name") do |example|
110
- if(File.file?(example))
111
- options.examples = File.open(example).read.split("\n")
112
- else
113
- options.examples = [example]
114
- end
115
- end
114
+ opts.rspec_on(:specification) {|example| options.parse_example(example)}
116
115
 
117
- opts.on("-s", "--spec [NAME]", "DEPRECATED - use -e instead", "(This will be removed when autotest works with -e)") do |example|
118
- if(File.file?(example))
119
- options.examples = File.open(example).read.split("\n")
120
- else
121
- options.examples = [example]
122
- end
123
- end
116
+ opts.rspec_on(:line) {|line_number| options.line_number = line_number.to_i}
124
117
 
125
- opts.on("-l", "--line LINE_NUMBER", Integer, "Execute behaviour or example at given line.",
126
- "(does not work for dynamically generated specs)") do |line_number|
127
- options.line_number = line_number.to_i
128
- end
118
+ opts.rspec_on(:format) {|format| options.parse_format(format, out, err)}
129
119
 
130
- opts.on("-f", "--format FORMAT[:WHERE]", "Specifies what format to use for output. Specify WHERE to tell",
131
- "the formatter where to write the output. All built-in formats",
132
- "expect WHERE to be a file name, and will write to STDOUT if it's",
133
- "not specified. The --format option may be specified several times",
134
- "if you want several outputs",
135
- " ",
136
- "Builtin formats: ",
137
- "progress|p : Text progress",
138
- "specdoc|s : Behaviour doc as text",
139
- "rdoc|r : Behaviour doc as RDoc",
140
- "html|h : A nice HTML report",
141
- "failing_examples|e : Write all failing examples - input for --example",
142
- "failing_behaviours|b : Write all failing behaviours - input for --example",
143
- " ",
144
- "FORMAT can also be the name of a custom formatter class",
145
- "(in which case you should also specify --require to load it)") do |format|
146
-
147
- where = out
148
- # This funky regexp checks whether we have a FILE_NAME or not
149
- if (format =~ /([a-zA-Z_]+(?:::[a-zA-Z_]+)*):?(.*)/) && ($2 != '')
150
- format = $1
151
- where = $2
152
- else
153
- raise "When using several --format options only one of them can be without a file" if @out_used
154
- @out_used = true
155
- end
120
+ opts.rspec_on(:require) {|req| options.parse_require(req)}
156
121
 
157
- begin
158
- formatter_type = BUILT_IN_FORMATTERS[format] || eval(format)
159
- options.formatters << formatter_type.new(where)
160
- rescue NameError
161
- err.puts "Couldn't find formatter class #{format}"
162
- err.puts "Make sure the --require option is specified *before* --format"
163
- exit if out == $stdout
164
- end
165
- end
122
+ opts.rspec_on(:backtrace) {options.backtrace_tweaker = NoisyBacktraceTweaker.new}
166
123
 
167
- opts.on("-r", "--require FILE", "Require FILE before running specs",
168
- "Useful for loading custom formatters or other extensions.",
169
- "If this option is used it must come before the others") do |req|
170
- req.split(",").each{|file| require file}
171
- end
172
-
173
- opts.on("-b", "--backtrace", "Output full backtrace") do
174
- options.backtrace_tweaker = NoisyBacktraceTweaker.new
175
- end
176
-
177
- opts.on("-L", "--loadby STRATEGY", "Specify the strategy by which spec files should be loaded.",
178
- "STRATEGY can currently only be 'mtime' (File modification time)",
179
- "By default, spec files are loaded in alphabetical order if --loadby",
180
- "is not specified.") do |loadby|
181
- options.loadby = loadby
182
- end
124
+ opts.rspec_on(:loadby) {|loadby| options.loadby = loadby}
183
125
 
184
- opts.on("-R", "--reverse", "Run examples in reverse order") do
185
- options.reverse = true
186
- end
187
-
188
- opts.on("-t", "--timeout FLOAT", "Interrupt and fail each example that doesn't complete in the",
189
- "specified time") do |timeout|
190
- options.timeout = timeout.to_f
191
- end
126
+ opts.rspec_on(:reverse) {options.reverse = true}
192
127
 
193
- opts.on("-H", "--heckle CODE", "If all examples pass, this will mutate the classes and methods",
194
- "identified by CODE little by little and run all the examples again",
195
- "for each mutation. The intent is that for each mutation, at least",
196
- "one example *should* fail, and RSpec will tell you if this is not the",
197
- "case. CODE should be either Some::Module, Some::Class or",
198
- "Some::Fabulous#method") do |heckle|
199
- heckle_runner = PLATFORM == 'i386-mswin32' ? 'spec/runner/heckle_runner_win' : 'spec/runner/heckle_runner'
200
- require heckle_runner
201
- options.heckle_runner = HeckleRunner.new(heckle)
202
- end
203
-
204
- opts.on("-d", "--dry-run", "Invokes formatters without executing the examples.") do
205
- options.dry_run = true
206
- end
207
-
208
- opts.on("-O", "--options PATH", "Read options from a file") do |options_file|
209
- # Remove the --options option and the argument before writing to file
210
- index = args_copy.index("-O") || args_copy.index("--options")
211
- args_copy.delete_at(index)
212
- args_copy.delete_at(index)
213
-
214
- new_args = args_copy + IO.readlines(options_file).map {|l| l.chomp.split " "}.flatten
215
- return CommandLine.run(new_args, err, out, true, warn_if_no_files)
216
- end
128
+ opts.rspec_on(:timeout) {|timeout| options.timeout = timeout.to_f}
217
129
 
218
- opts.on("-G", "--generate-options PATH", "Generate an options file for --options") do |options_file|
219
- # Remove the --generate-options option and the argument before writing to file
220
- index = args_copy.index("-G") || args_copy.index("--generate-options")
221
- args_copy.delete_at(index)
222
- args_copy.delete_at(index)
130
+ opts.rspec_on(:heckle) {|heckle| options.parse_heckle(heckle)}
131
+
132
+ opts.rspec_on(:dry_run) {options.dry_run = true}
223
133
 
224
- File.open(options_file, 'w') do |io|
225
- io.puts args_copy.join("\n")
226
- end
227
- out.puts "\nOptions written to #{options_file}. You can now use these options with:"
228
- out.puts "spec --options #{options_file}"
229
- options.generate = true
134
+ opts.rspec_on(:options_file) do |options_file|
135
+ return parse_options_file(options_file, out, err, args_copy, warn_if_no_files)
230
136
  end
231
137
 
232
- opts.on("-U", "--runner RUNNER", "Use a custom BehaviourRunner.") do |runner|
233
- begin
234
- options.runner_type = eval(runner)
235
- rescue NameError
236
- err.puts "Couldn't find behaviour runner class #{runner}"
237
- err.puts "Make sure the --require option is specified."
238
- exit if out == $stdout
239
- end
240
- end
241
-
242
- opts.on("-X", "--drb", "Run examples via DRb. (For example against script/spec_server)") do |options_file|
243
- # Remove the --drb option
244
- index = args_copy.index("-X") || args_copy.index("--drb")
245
- args_copy.delete_at(index)
246
-
247
- return DrbCommandLine.run(args_copy, err, out, true, warn_if_no_files)
138
+ opts.rspec_on(:generate_options) do |options_file|
139
+ options.parse_generate_options(options_file, args_copy, out)
248
140
  end
249
141
 
250
- opts.on("-v", "--version", "Show version") do
251
- out.puts ::Spec::VERSION::DESCRIPTION
252
- exit if out == $stdout
142
+ opts.rspec_on(:runner) do |runner|
143
+ options.parse_runner(runner, out, err)
253
144
  end
254
145
 
255
- opts.on_tail("-h", "--help", "You're looking at it") do
256
- out.puts opts
257
- exit if out == $stdout
146
+ opts.rspec_on(:drb) do
147
+ parse_drb args_copy, out, err, warn_if_no_files
258
148
  end
259
-
149
+
150
+ opts.rspec_on(:version) {parse_version(out)}
151
+
152
+ opts.on_tail(*COMMAND_LINE[:help]) {parse_help(opts, out)}
260
153
  end
261
154
  opts.parse!(args)
262
155
 
@@ -269,21 +162,49 @@ module Spec
269
162
  if options.line_number
270
163
  set_spec_from_line_number(options, args, err)
271
164
  end
272
-
165
+
273
166
  if options.formatters.empty?
274
167
  options.formatters << Formatter::ProgressBarFormatter.new(out)
275
168
  end
276
169
 
277
170
  options
278
171
  end
279
-
172
+
173
+ def parse_options_file(options_file, out_stream, error_stream, args_copy, warn_if_no_files)
174
+ # Remove the --options option and the argument before writing to file
175
+ index = args_copy.index("-O") || args_copy.index("--options")
176
+ args_copy.delete_at(index)
177
+ args_copy.delete_at(index)
178
+
179
+ new_args = args_copy + IO.readlines(options_file).map {|l| l.chomp.split " "}.flatten
180
+ return CommandLine.run(new_args, error_stream, out_stream, true, warn_if_no_files)
181
+ end
182
+
183
+ def parse_drb(args_copy, out_stream, error_stream, warn_if_no_files)
184
+ # Remove the --drb option
185
+ index = args_copy.index("-X") || args_copy.index("--drb")
186
+ args_copy.delete_at(index)
187
+
188
+ return DrbCommandLine.run(args_copy, error_stream, out_stream, true, warn_if_no_files)
189
+ end
190
+
191
+ def parse_version(out_stream)
192
+ out_stream.puts ::Spec::VERSION::DESCRIPTION
193
+ exit if out_stream == $stdout
194
+ end
195
+
196
+ def parse_help(opts, out_stream)
197
+ out_stream.puts opts
198
+ exit if out_stream == $stdout
199
+ end
200
+
280
201
  def set_spec_from_line_number(options, args, err)
281
202
  if options.examples.empty?
282
203
  if args.length == 1
283
204
  if @file_factory.file?(args[0])
284
205
  source = @file_factory.open(args[0])
285
206
  example = @spec_parser.spec_name_for(source, options.line_number)
286
- options.examples = [example]
207
+ options.parse_example(example)
287
208
  elsif @file_factory.directory?(args[0])
288
209
  err.puts "You must specify one file, not a directory when using the --line option"
289
210
  exit(1) if err == $stderr
@@ -1,6 +1,21 @@
1
1
  module Spec
2
2
  module Runner
3
3
  class Options
4
+ BUILT_IN_FORMATTERS = {
5
+ 'specdoc' => Formatter::SpecdocFormatter,
6
+ 's' => Formatter::SpecdocFormatter,
7
+ 'html' => Formatter::HtmlFormatter,
8
+ 'h' => Formatter::HtmlFormatter,
9
+ 'rdoc' => Formatter::RdocFormatter,
10
+ 'r' => Formatter::RdocFormatter,
11
+ 'progress' => Formatter::ProgressBarFormatter,
12
+ 'p' => Formatter::ProgressBarFormatter,
13
+ 'failing_examples' => Formatter::FailingExamplesFormatter,
14
+ 'e' => Formatter::FailingExamplesFormatter,
15
+ 'failing_behaviours' => Formatter::FailingBehavioursFormatter,
16
+ 'b' => Formatter::FailingBehavioursFormatter
17
+ }
18
+
4
19
  attr_accessor(
5
20
  :backtrace_tweaker,
6
21
  :colour,
@@ -21,6 +36,127 @@ module Spec
21
36
  :timeout,
22
37
  :verbose
23
38
  )
39
+
40
+ def initialize
41
+ @backtrace_tweaker = QuietBacktraceTweaker.new
42
+ @examples = []
43
+ @formatters = []
44
+ @colour = false
45
+ @dry_run = false
46
+ end
47
+
48
+ def create_behaviour_runner
49
+ @formatters.each do |formatter|
50
+ formatter.colour = @colour if formatter.respond_to?(:colour=)
51
+ formatter.dry_run = @dry_run if formatter.respond_to?(:dry_run=)
52
+ end
53
+ @reporter = Reporter.new(@formatters, @backtrace_tweaker)
54
+
55
+ # this doesn't really belong here.
56
+ # it should, but the way things are coupled, it doesn't
57
+ if @differ_class
58
+ Spec::Expectations.differ = @differ_class.new(@diff_format, @context_lines, @colour)
59
+ end
60
+
61
+ return nil if @generate
62
+
63
+ if @runner_type
64
+ @runner_type.new(self)
65
+ else
66
+ BehaviourRunner.new(self)
67
+ end
68
+ end
69
+
70
+ def parse_diff(format, out_stream, error_stream)
71
+ @context_lines = 3
72
+ case format
73
+ when :context, 'context', 'c'
74
+ @diff_format = :context
75
+ when :unified, 'unified', 'u', '', nil
76
+ @diff_format = :unified
77
+ end
78
+
79
+ if [:context,:unified].include? @diff_format
80
+ require 'spec/expectations/differs/default'
81
+ @differ_class = Spec::Expectations::Differs::Default
82
+ else
83
+ begin
84
+ @diff_format = :custom
85
+ @differ_class = eval(format)
86
+ rescue NameError
87
+ error_stream.puts "Couldn't find differ class #{format}"
88
+ error_stream.puts "Make sure the --require option is specified *before* --diff"
89
+ exit if out_stream == $stdout
90
+ end
91
+ end
92
+ end
93
+
94
+ def parse_example(example)
95
+ if(File.file?(example))
96
+ @examples = File.open(example).read.split("\n")
97
+ else
98
+ @examples = [example]
99
+ end
100
+ end
101
+
102
+ def parse_line(line_number)
103
+ @line_number = line_number.to_i
104
+ end
105
+
106
+ def parse_format(format, out_stream, error_stream)
107
+ where = out_stream
108
+ # This funky regexp checks whether we have a FILE_NAME or not
109
+ if (format =~ /([a-zA-Z_]+(?:::[a-zA-Z_]+)*):?(.*)/) && ($2 != '')
110
+ format = $1
111
+ where = $2
112
+ else
113
+ raise "When using several --format options only one of them can be without a file" if @out_used
114
+ @out_used = true
115
+ end
116
+
117
+ begin
118
+ formatter_type = BUILT_IN_FORMATTERS[format] || eval(format)
119
+ @formatters << formatter_type.new(where)
120
+ rescue NameError
121
+ error_stream.puts "Couldn't find formatter class #{format}"
122
+ error_stream.puts "Make sure the --require option is specified *before* --format"
123
+ exit if out_stream == $stdout
124
+ end
125
+ end
126
+
127
+ def parse_require(req)
128
+ req.split(",").each{|file| require file}
129
+ end
130
+
131
+ def parse_heckle(heckle)
132
+ heckle_require = PLATFORM == 'i386-mswin32' ? 'spec/runner/heckle_runner_win' : 'spec/runner/heckle_runner'
133
+ require heckle_require
134
+ @heckle_runner = HeckleRunner.new(heckle)
135
+ end
136
+
137
+ def parse_generate_options(options_file, args_copy, out_stream)
138
+ # Remove the --generate-options option and the argument before writing to file
139
+ index = args_copy.index("-G") || args_copy.index("--generate-options")
140
+ args_copy.delete_at(index)
141
+ args_copy.delete_at(index)
142
+
143
+ File.open(options_file, 'w') do |io|
144
+ io.puts args_copy.join("\n")
145
+ end
146
+ out_stream.puts "\nOptions written to #{options_file}. You can now use these options with:"
147
+ out_stream.puts "spec --options #{options_file}"
148
+ @generate = true
149
+ end
150
+
151
+ def parse_runner(runner, out_stream, error_stream)
152
+ begin
153
+ @runner_type = eval(runner)
154
+ rescue NameError
155
+ error_stream.puts "Couldn't find behaviour runner class #{runner}"
156
+ error_stream.puts "Make sure the --require option is specified."
157
+ exit if out_stream == $stdout
158
+ end
159
+ end
24
160
  end
25
161
  end
26
162
  end
@@ -65,6 +65,7 @@ module Spec
65
65
  @formatters.each{|f| f.dump_failure(index, failure)}
66
66
  index + 1
67
67
  end
68
+ STDOUT.flush
68
69
  end
69
70
 
70
71
  def duration
@@ -74,12 +75,12 @@ module Spec
74
75
 
75
76
  def example_passed(name)
76
77
  @formatters.each{|f| f.example_passed(name)}
78
+ STDOUT.flush
77
79
  end
78
80
 
79
81
  def example_failed(name, error, failure_location)
80
82
  @backtrace_tweaker.tweak_backtrace(error, failure_location)
81
83
  example_name = "#{@behaviour_names.last} #{name}"
82
- @failure_io.puts(example_name) unless @failure_io.nil?
83
84
  failure = Failure.new(example_name, error)
84
85
  @failures << failure
85
86
  @formatters.each{|f| f.example_failed(name, @failures.length, failure)}
@@ -66,6 +66,7 @@ module Spec
66
66
 
67
67
  # Add parenthesis
68
68
  post.gsub!(/^(\w+)\s+([\w|\.|\,|\(.*\)|\'|\"|\:|@| ]+)(\})/, '\1(\2)\3') # inside a block
69
+ post.gsub!(/^(redirect_to)\s+(.*)/, '\1(\2)') # redirect_to, which often has http:
69
70
  post.gsub!(/^(\w+)\s+([\w|\.|\,|\(.*\)|\{.*\}|\'|\"|\:|@| ]+)/, '\1(\2)')
70
71
  post.gsub!(/(\s+\))/, ')')
71
72
  post.gsub!(/\)\}/, ') }')
@@ -89,6 +90,7 @@ module Spec
89
90
  /^match/,
90
91
  /^raise_error/,
91
92
  /^respond_to/,
93
+ /^redirect_to/,
92
94
  /^satisfy/,
93
95
  /^throw_symbol/,
94
96
  # Extra ones that we use in spec_helper
data/lib/spec/version.rb CHANGED
@@ -3,11 +3,11 @@ module Spec
3
3
  unless defined? MAJOR
4
4
  MAJOR = 0
5
5
  MINOR = 9
6
- TINY = 1
6
+ TINY = 2
7
7
  RELEASE_CANDIDATE = nil
8
8
 
9
- # RANDOM_TOKEN: 0.434722315440065
10
- REV = "$LastChangedRevision: 1880 $".match(/LastChangedRevision: (\d+)/)[1]
9
+ # RANDOM_TOKEN: 0.495595173542949
10
+ REV = "$LastChangedRevision: 1899 $".match(/LastChangedRevision: (\d+)/)[1]
11
11
 
12
12
  STRING = [MAJOR, MINOR, TINY].join('.')
13
13
  TAG = "REL_#{[MAJOR, MINOR, TINY, RELEASE_CANDIDATE].compact.join('_')}".upcase.gsub(/\.|-/, '_')
@@ -460,7 +460,7 @@ module Spec
460
460
 
461
461
  it "should include any predicate_matchers included using configuration" do
462
462
  $included_predicate_matcher_found = false
463
- Spec::Runner.configuration.predicate_matchers[:does_something?] = :do_something
463
+ Spec::Runner.configuration.predicate_matchers[:do_something] = :does_something?
464
464
  Behaviour.new('example') do
465
465
  it "should respond to do_something" do
466
466
  $included_predicate_matcher_found = respond_to?(:do_something)
@@ -9,7 +9,7 @@ module Spec
9
9
  end
10
10
 
11
11
  describe "predicate_matcher[method_on_object] = matcher_method" do
12
- predicate_matchers[:can_swim?] = :swim
12
+ predicate_matchers[:swim] = :can_swim?
13
13
  it "should match matcher_method if method_on_object returns true" do
14
14
  swim(100).matches?(Fish.new).should be_true
15
15
  end
@@ -45,7 +45,7 @@ describe "OptionParser" do
45
45
 
46
46
  it "should not use colour by default" do
47
47
  options = parse([])
48
- options.colour.should be_nil
48
+ options.colour.should == false
49
49
  end
50
50
 
51
51
  it "should print help to stdout" do
@@ -0,0 +1,142 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper.rb'
2
+
3
+ module Spec
4
+ module Runner
5
+ describe "Options" do
6
+ before do
7
+ @error_stream = StringIO.new('')
8
+ @out_stream = StringIO.new('')
9
+ @options = Options.new
10
+ end
11
+
12
+ it "instantiates empty arrays" do
13
+ @options.examples.should == []
14
+ @options.formatters.should == []
15
+ end
16
+
17
+ it "defaults to QuietBacktraceTweaker" do
18
+ @options.backtrace_tweaker.class.should == QuietBacktraceTweaker
19
+ end
20
+
21
+ it "defaults to no dry_run" do
22
+ @options.dry_run.should == false
23
+ end
24
+
25
+ it "parse_diff sets context_lines" do
26
+ @options.parse_diff nil, @out_stream, @error_stream
27
+ @options.context_lines.should == 3
28
+ end
29
+
30
+ it "defaults diff to unified" do
31
+ @options.parse_diff nil, @out_stream, @error_stream
32
+ @options.diff_format.should == :unified
33
+ end
34
+
35
+ it "should use unified diff format option when format is unified" do
36
+ @options.parse_diff 'unified', @out_stream, @error_stream
37
+ @options.diff_format.should == :unified
38
+ @options.differ_class.should equal(Spec::Expectations::Differs::Default)
39
+ end
40
+
41
+ it "should use context diff format option when format is context" do
42
+ @options.parse_diff 'context', @out_stream, @error_stream
43
+ @options.diff_format.should == :context
44
+ @options.differ_class.should == Spec::Expectations::Differs::Default
45
+ end
46
+
47
+ it "should use custom diff format option when format is a custom format" do
48
+ @options.parse_diff "Custom::Formatter", @out_stream, @error_stream
49
+ @options.diff_format.should == :custom
50
+ @options.differ_class.should == Custom::Formatter
51
+ end
52
+
53
+ it "should print instructions about how to fix bad differ" do
54
+ @options.parse_diff "Custom::BadFormatter", @out_stream, @error_stream
55
+ @error_stream.string.should match(/Couldn't find differ class Custom::BadFormatter/n)
56
+ end
57
+
58
+ it "parse_example sets single example when argument not a file" do
59
+ example = "something or other"
60
+ File.file?(example).should == false
61
+ @options.parse_example example
62
+ @options.examples.should eql(["something or other"])
63
+ end
64
+
65
+ it "parse_example sets examples to contents of file" do
66
+ example = "#{File.dirname(__FILE__)}/examples.txt"
67
+ File.should_receive(:file?).with(example).and_return(true)
68
+ file = StringIO.new("Sir, if you were my husband, I would poison your drink.\nMadam, if you were my wife, I would drink it.")
69
+ File.should_receive(:open).with(example).and_return(file)
70
+
71
+ @options.parse_example example
72
+ @options.examples.should eql([
73
+ "Sir, if you were my husband, I would poison your drink.",
74
+ "Madam, if you were my wife, I would drink it."
75
+ ])
76
+ end
77
+ end
78
+
79
+ describe "Options", "receiving create_behaviour_runner" do
80
+ before do
81
+ @options = Options.new
82
+ end
83
+
84
+ it "returns nil when generate is true" do
85
+ @options.generate = true
86
+ @options.create_behaviour_runner.should == nil
87
+ end
88
+
89
+ it "returns a BehaviourRunner by default" do
90
+ runner = @options.create_behaviour_runner
91
+ runner.class.should == BehaviourRunner
92
+ end
93
+
94
+ it "returns a custom runner when runner_type is set" do
95
+ runner_type = Class.new do
96
+ attr_reader :options
97
+ def initialize(options)
98
+ @options = options
99
+ end
100
+ end
101
+ @options.runner_type = runner_type
102
+
103
+ runner = @options.create_behaviour_runner
104
+ runner.class.should == runner_type
105
+ runner.options.should === @options
106
+ end
107
+
108
+ it "does not set Expectations differ when differ_class is not set" do
109
+ @options.differ_class = nil
110
+ Spec::Expectations.should_not_receive(:differ=)
111
+ @options.create_behaviour_runner
112
+ end
113
+
114
+ it "sets Expectations differ when differ_class is set" do
115
+ @options.differ_class = Spec::Expectations::Differs::Default
116
+ Spec::Expectations.should_receive(:differ=).with(:anything).and_return do |arg|
117
+ arg.class.should == Spec::Expectations::Differs::Default
118
+ end
119
+ @options.create_behaviour_runner
120
+ end
121
+
122
+ it "creates a Reporter" do
123
+ formatter = ::Spec::Runner::Formatter::BaseFormatter.new(:somewhere)
124
+ @options.formatters << formatter
125
+ reporter = Reporter.new(@formatters, @backtrace_tweaker)
126
+ Reporter.should_receive(:new).with(@options.formatters, @options.backtrace_tweaker).and_return(reporter)
127
+ @options.create_behaviour_runner
128
+ @options.reporter.should === reporter
129
+ end
130
+
131
+ it "sets colour and dry_run on the formatters" do
132
+ @options.colour = true
133
+ @options.dry_run = true
134
+ formatter = ::Spec::Runner::Formatter::BaseTextFormatter.new(:somewhere)
135
+ formatter.should_receive(:colour=).with(true)
136
+ formatter.should_receive(:dry_run=).with(true)
137
+ @options.formatters << formatter
138
+ @options.create_behaviour_runner
139
+ end
140
+ end
141
+ end
142
+ end
@@ -205,4 +205,12 @@ describe "Translator" do
205
205
  # "lambda { @instance.foo = foo }.should raise_error(NoMethodError) # no writer defined"
206
206
  # )
207
207
  # end
208
+
209
+ it "should translate redirects" do
210
+ @t.translate_line(
211
+ "controller.should_redirect_to 'http://not_existing_domain_for_novalis.test.host/404.html'"
212
+ ).should eql(
213
+ "controller.should redirect_to('http://not_existing_domain_for_novalis.test.host/404.html')"
214
+ )
215
+ end
208
216
  end
metadata CHANGED
@@ -3,9 +3,9 @@ rubygems_version: 0.9.1
3
3
  specification_version: 1
4
4
  name: rspec
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.9.1
7
- date: 2007-05-01 00:00:00 +02:00
8
- summary: RSpec-0.9.1 (r1880) - BDD for Ruby http://rspec.rubyforge.org/
6
+ version: 0.9.2
7
+ date: 2007-05-03 00:00:00 +02:00
8
+ summary: RSpec-0.9.2 (r1899) - BDD for Ruby http://rspec.rubyforge.org/
9
9
  require_paths:
10
10
  - lib
11
11
  email: rspec-devel@rubyforge.org
@@ -184,6 +184,7 @@ files:
184
184
  - spec/spec/runner/noisy_backtrace_tweaker_spec.rb
185
185
  - spec/spec/runner/object_ext_spec.rb
186
186
  - spec/spec/runner/option_parser_spec.rb
187
+ - spec/spec/runner/options_spec.rb
187
188
  - spec/spec/runner/quiet_backtrace_tweaker_spec.rb
188
189
  - spec/spec/runner/reporter_spec.rb
189
190
  - spec/spec/runner/spec_matcher_spec.rb