rspec 0.9.1 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
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