rspec-core 2.7.1 → 2.8.0.rc1

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.
Files changed (56) hide show
  1. data/README.md +1 -1
  2. data/features/command_line/order.feature +29 -0
  3. data/features/command_line/tag.feature +10 -9
  4. data/features/configuration/default_path.feature +2 -2
  5. data/features/filtering/exclusion_filters.feature +1 -1
  6. data/features/filtering/run_all_when_everything_filtered.feature +1 -1
  7. data/features/subject/attribute_of_subject.feature +1 -1
  8. data/lib/rspec/core.rb +148 -12
  9. data/lib/rspec/core/command_line.rb +2 -2
  10. data/lib/rspec/core/configuration.rb +300 -155
  11. data/lib/rspec/core/configuration_options.rb +34 -53
  12. data/lib/rspec/core/deprecation.rb +4 -0
  13. data/lib/rspec/core/drb_options.rb +72 -0
  14. data/lib/rspec/core/example.rb +58 -24
  15. data/lib/rspec/core/example_group.rb +10 -5
  16. data/lib/rspec/core/extensions.rb +1 -0
  17. data/lib/rspec/core/extensions/ordered.rb +16 -0
  18. data/lib/rspec/core/filter_manager.rb +170 -0
  19. data/lib/rspec/core/formatters/base_formatter.rb +3 -1
  20. data/lib/rspec/core/formatters/base_text_formatter.rb +6 -0
  21. data/lib/rspec/core/formatters/snippet_extractor.rb +1 -1
  22. data/lib/rspec/core/hooks.rb +197 -1
  23. data/lib/rspec/core/let.rb +3 -2
  24. data/lib/rspec/core/metadata.rb +25 -4
  25. data/lib/rspec/core/option_parser.rb +89 -54
  26. data/lib/rspec/core/pending.rb +41 -0
  27. data/lib/rspec/core/rake_task.rb +9 -25
  28. data/lib/rspec/core/reporter.rb +43 -19
  29. data/lib/rspec/core/shared_context.rb +35 -0
  30. data/lib/rspec/core/shared_example_group.rb +0 -1
  31. data/lib/rspec/core/subject.rb +4 -4
  32. data/lib/rspec/core/version.rb +1 -1
  33. data/lib/rspec/core/world.rb +34 -52
  34. data/spec/autotest/failed_results_re_spec.rb +2 -2
  35. data/spec/command_line/order_spec.rb +131 -0
  36. data/spec/rspec/core/command_line_spec.rb +2 -1
  37. data/spec/rspec/core/configuration_options_spec.rb +83 -163
  38. data/spec/rspec/core/configuration_spec.rb +311 -139
  39. data/spec/rspec/core/drb_options_spec.rb +131 -0
  40. data/spec/rspec/core/example_group_spec.rb +22 -11
  41. data/spec/rspec/core/example_spec.rb +1 -2
  42. data/spec/rspec/core/filter_manager_spec.rb +175 -0
  43. data/spec/rspec/core/formatters/helpers_spec.rb +1 -1
  44. data/spec/rspec/core/formatters/html_formatter_spec.rb +3 -2
  45. data/spec/rspec/core/formatters/text_mate_formatter_spec.rb +1 -1
  46. data/spec/rspec/core/metadata_spec.rb +21 -6
  47. data/spec/rspec/core/option_parser_spec.rb +74 -0
  48. data/spec/rspec/core/reporter_spec.rb +18 -1
  49. data/spec/rspec/core/shared_context_spec.rb +54 -17
  50. data/spec/rspec/core/subject_spec.rb +1 -1
  51. data/spec/rspec/core/world_spec.rb +7 -188
  52. data/spec/spec_helper.rb +47 -43
  53. data/spec/support/config_options_helper.rb +27 -0
  54. metadata +28 -12
  55. data/lib/rspec/core/expecting/with_rspec.rb +0 -9
  56. data/lib/rspec/core/expecting/with_stdlib.rb +0 -9
@@ -95,6 +95,9 @@ module RSpec
95
95
  def dump_pending
96
96
  end
97
97
 
98
+ def seed(number)
99
+ end
100
+
98
101
  # This method is invoked at the very end. Allows the formatter to clean up, like closing open streams.
99
102
  def close
100
103
  restore_sync_output
@@ -142,7 +145,6 @@ module RSpec
142
145
  match = line.match(/(.+?):(\d+)(|:\d+)/)
143
146
  match && match[1].downcase == path.downcase
144
147
  }
145
-
146
148
  end
147
149
 
148
150
  def start_sync_output
@@ -86,6 +86,12 @@ module RSpec
86
86
  end
87
87
  end
88
88
 
89
+ def seed(number)
90
+ output.puts
91
+ output.puts "Randomized with seed #{number}"
92
+ output.puts
93
+ end
94
+
89
95
  def close
90
96
  output.close if IO === output && output != $stdout
91
97
  end
@@ -8,7 +8,7 @@ module RSpec
8
8
  begin
9
9
  require 'syntax/convertors/html'
10
10
  @@converter = Syntax::Convertors::HTML.for_syntax "ruby"
11
- rescue LoadError => e
11
+ rescue LoadError
12
12
  @@converter = NullConverter.new
13
13
  end
14
14
 
@@ -77,7 +77,7 @@ module RSpec
77
77
 
78
78
  class AfterHooks < HookCollection
79
79
  def run_all(example_group_instance)
80
- reverse.each {|h| h.run_in(example_group_instance) }
80
+ reverse.each {|h| h.run_in(example_group_instance) }
81
81
  end
82
82
 
83
83
  def run_all!(example_group_instance)
@@ -87,6 +87,7 @@ module RSpec
87
87
 
88
88
  class AroundHooks < HookCollection; end
89
89
 
90
+ # @api private
90
91
  def hooks
91
92
  @hooks ||= {
92
93
  :around => { :each => AroundHooks.new },
@@ -95,37 +96,232 @@ module RSpec
95
96
  }
96
97
  end
97
98
 
99
+ # @api public
100
+ # @overload before(&block)
101
+ # @overload before(scope, &block)
102
+ # @overload before(scope, tags, &block)
103
+ # @overload before(tags, &block)
104
+ # @param [Symbol] scope `:each`, `:all`, or `:suite` (defaults to `:each`)
105
+ # @param [Hash] tags
106
+ # @see #after
107
+ # @see #around
108
+ # @see ExampleGroup
109
+ # @see SharedContext
110
+ # @see SharedExampleGroup
111
+ # @see Configuration
112
+ #
113
+ # Declare a block of code to be run before each example (using `:each`)
114
+ # or once before any example (using `:all`). These are usually declared
115
+ # directly in the [ExampleGroup](ExampleGroup) to which they apply, but
116
+ # they can also be shared across multiple groups.
117
+ #
118
+ # You can also use `before(:suite)` to run a block of code before any
119
+ # example groups are run. This should be declared in
120
+ # [RSpec.configure](../../RSpec#configure-class_method)
121
+ #
122
+ # Instance variables declared in `before(:each)` or `before(:all)` are
123
+ # accessible within each example.
124
+ #
125
+ # ### Exceptions
126
+ #
127
+ # When an exception is raised in a `before` block, RSpec skips any
128
+ # subsequent `before` blocks and the example, but runs all of the
129
+ # `after(:each)` and `after(:all)` hooks.
130
+ #
131
+ # ### Order
132
+ #
133
+ # `before` hooks are stored in three scopes, which are run in order:
134
+ # `:suite`, `:all`, and `:each`. They can also be declared in several
135
+ # different places: `RSpec.configure`, a parent group, the current group.
136
+ # They are run in the following order:
137
+ #
138
+ # before(:all) declared in RSpec.configure
139
+ # before(:all) declared in a parent group
140
+ # before(:all) declared in the current group
141
+ # before(:each) declared in RSpec.configure
142
+ # before(:each) declared in a parent group
143
+ # before(:each) declared in the current group
144
+ #
145
+ # If more than one `before` is declared within any one scope, they are run
146
+ # in the order in which they are declared.
147
+ #
148
+ # ### Warning: implicit before blocks
149
+ #
150
+ # `before` hooks can also be declared in shared contexts which get
151
+ # included implicitly either by you or by extension libraries. Since
152
+ # RSpec runs these in the order in which they are declared within each
153
+ # scope, load order matters, and can lead to confusing results when one
154
+ # before block depends on state that is prepared in another before block
155
+ # that gets run later.
156
+ #
157
+ # ### Warning: `before(:all)`
158
+ #
159
+ # It is very tempting to use `before(:all)` to speed things up, but we
160
+ # recommend that you avoid this as there are a number of gotchas, as well
161
+ # as things that simply don't work.
162
+ #
163
+ # #### context
164
+ #
165
+ # `before(:all)` is run in an example that is generated to provide group
166
+ # context for the block.
167
+ #
168
+ # #### instance variables
169
+ #
170
+ # Instance variables declared in `before(:all)` are shared across all the
171
+ # examples in the group. This means that each example can change the
172
+ # state of a shared object, resulting in an ordering dependency that can
173
+ # make it difficult to reason about failures.
174
+ #
175
+ # ### other frameworks
176
+ #
177
+ # Mock object frameworks and database transaction managers (like
178
+ # ActiveRecord) are typically designed around the idea of setting up
179
+ # before an example, running that one example, and then tearing down.
180
+ # This means that mocks and stubs can (sometimes) be declared in
181
+ # `before(:all)`, but get torn down before the first real example is ever
182
+ # run.
183
+ #
184
+ # You _can_ create database-backed model objects in a `before(:all)` in
185
+ # rspec-rails, but it will not be wrapped in a transaction for you, so
186
+ # you are on your own to clean up in an `after(:all)` block.
187
+ #
188
+ # @example before(:each) declared in an [ExampleGroup](ExampleGroup)
189
+ #
190
+ # describe Thing do
191
+ # before(:each) do
192
+ # @thing = Thing.new
193
+ # end
194
+ #
195
+ # it "does something" do
196
+ # # here you can access @thing
197
+ # end
198
+ # end
199
+ #
200
+ # @example before(:all) declared in an [ExampleGroup](ExampleGroup)
201
+ #
202
+ # describe Parser do
203
+ # before(:all) do
204
+ # File.open(file_to_parse, 'w') do |f|
205
+ # f.write <<-CONTENT
206
+ # Stuff in the file
207
+ # end
208
+ # end
209
+ # end
210
+ #
211
+ # it "parses the file" do
212
+ # Parser.parse(file_to_parse)
213
+ # end
214
+ #
215
+ # after(:all) do
216
+ # File.delete(file_to_parse)
217
+ # end
218
+ # end
98
219
  def before(*args, &block)
99
220
  scope, options = scope_and_options_from(*args)
100
221
  hooks[:before][scope] << BeforeHook.new(options, &block)
101
222
  end
102
223
 
224
+ # @api public
225
+ # @overload after(&block)
226
+ # @overload after(scope, &block)
227
+ # @overload after(scope, tags, &block)
228
+ # @overload after(tags, &block)
229
+ # @param [Symbol] scope `:each`, `:all`, or `:suite` (defaults to `:each`)
230
+ # @param [Hash] tags
231
+ # @see #before
232
+ # @see #around
233
+ # @see ExampleGroup
234
+ # @see SharedContext
235
+ # @see SharedExampleGroup
236
+ # @see Configuration
237
+ #
238
+ # Declare a block of code to be run after each example (using `:each`) or
239
+ # once after all examples (using `:all`). See
240
+ # [#before](Hooks#before-instance_method) for more information about
241
+ # ordering.
242
+ #
243
+ # ### Exceptions
244
+ #
245
+ # `after` hooks are guaranteed to run even when there are exceptions in
246
+ # `before` hooks or examples. When an exception is raised in an after
247
+ # block, the exception is captured for later reporting, and subsequent
248
+ # `after` blocks are run.
249
+ #
250
+ # ### Order
251
+ #
252
+ # `after` hooks are stored in three scopes, which are run in order:
253
+ # `:each`, `:all`, and `:suite`. They can also be declared in several
254
+ # different places: `RSpec.configure`, a parent group, the current group.
255
+ # They are run in the following order:
256
+ #
257
+ # after(:each) declared in the current group
258
+ # after(:each) declared in a parent group
259
+ # after(:each) declared in RSpec.configure
260
+ # after(:all) declared in the current group
261
+ # after(:all) declared in a parent group
262
+ # after(:all) declared in RSpec.configure
263
+ #
264
+ # This is the reverse of the order in which `before` hooks are run.
265
+ # Similarly, if more than one `after` is declared within any one scope,
266
+ # they are run in reverse order of that in which they are declared.
103
267
  def after(*args, &block)
104
268
  scope, options = scope_and_options_from(*args)
105
269
  hooks[:after][scope] << AfterHook.new(options, &block)
106
270
  end
107
271
 
272
+ # @api public
273
+ # @overload around(&block)
274
+ # @overload around(scope, &block)
275
+ # @overload around(scope, tags, &block)
276
+ # @overload around(tags, &block)
277
+ # @param [Symbol] scope `:each` (defaults to `:each`)
278
+ # @param [Hash] tags
279
+ # @yield [Example] the example to run
280
+ #
281
+ # @note `:each` is the only supported scope.
282
+ #
283
+ # Declare a block of code, parts of which will be run before and parts
284
+ # after the example. It is your responsibility to run the example:
285
+ #
286
+ # around(:each) do |ex|
287
+ # # do some stuff before
288
+ # ex.run
289
+ # # do some stuff after
290
+ # end
291
+ #
292
+ # The yielded example aliases `run` with `call`, which lets you treat it
293
+ # like a `Proc`. This is especially handy when working with libaries
294
+ # that manage their own setup and teardown using a block or proc syntax,
295
+ # e.g.
296
+ #
297
+ # around(:each) {|ex| Database.transaction(&ex)}
298
+ # around(:each) {|ex| FakeFS(&ex)}
299
+ #
108
300
  def around(*args, &block)
109
301
  scope, options = scope_and_options_from(*args)
110
302
  hooks[:around][scope] << AroundHook.new(options, &block)
111
303
  end
112
304
 
305
+ # @api private
113
306
  # Runs all of the blocks stored with the hook in the context of the
114
307
  # example. If no example is provided, just calls the hook directly.
115
308
  def run_hook(hook, scope, example_group_instance=nil)
116
309
  hooks[hook][scope].run_all(example_group_instance)
117
310
  end
118
311
 
312
+ # @api private
119
313
  # Just like run_hook, except it removes the blocks as it evalutes them,
120
314
  # ensuring that they will only be run once.
121
315
  def run_hook!(hook, scope, example_group_instance)
122
316
  hooks[hook][scope].run_all!(example_group_instance)
123
317
  end
124
318
 
319
+ # @api private
125
320
  def run_hook_filtered(hook, scope, group, example_group_instance, example = nil)
126
321
  find_hook(hook, scope, group, example).run_all(example_group_instance)
127
322
  end
128
323
 
324
+ # @api private
129
325
  def find_hook(hook, scope, example_group_class, example = nil)
130
326
  found_hooks = hooks[hook][scope].find_hooks_for(example || example_group_class)
131
327
 
@@ -6,7 +6,7 @@ module RSpec
6
6
  # Generates a method whose return value is memoized
7
7
  # after the first call.
8
8
  #
9
- # == Examples
9
+ # @example
10
10
  #
11
11
  # describe Thing do
12
12
  # let(:thing) { Thing.new }
@@ -30,7 +30,7 @@ module RSpec
30
30
  # purpose of setting up state and providing a memoized
31
31
  # reference to that state.
32
32
  #
33
- # == Examples
33
+ # @example
34
34
  #
35
35
  # class Thing
36
36
  # def self.count
@@ -86,6 +86,7 @@ module RSpec
86
86
  end
87
87
 
88
88
  module InstanceMethods
89
+ private
89
90
  def __memoized
90
91
  @__memoized ||= {}
91
92
  end
@@ -1,10 +1,16 @@
1
1
  module RSpec
2
2
  module Core
3
+ # Each ExampleGroup class and Example instance ...
4
+ #
5
+ # @see Example#metadata
6
+ # @see ExampleGroup.metadata
3
7
  class Metadata < Hash
4
8
 
5
- # Used to extend metadata Hashes to support lazy evaluation of locations
6
- # and descriptions.
7
9
  module MetadataHash
10
+
11
+ # Supports lazy evaluation of some values. Extended by
12
+ # ExampleMetadataHash and GroupMetadataHash, which get mixed in to
13
+ # Metadata for ExampleGroups and Examples (respectively).
8
14
  def [](key)
9
15
  return super if has_key?(key)
10
16
  case key
@@ -58,9 +64,19 @@ module RSpec
58
64
  end
59
65
  end
60
66
 
67
+ # Mixed in to Metadata for an Example (extends MetadataHash) to support
68
+ # lazy evaluation of some values.
69
+ module ExampleMetadataHash
70
+ include MetadataHash
71
+ end
72
+
73
+ # Mixed in to Metadata for an ExampleGroup (extends MetadataHash) to
74
+ # support lazy evaluation of some values.
61
75
  module GroupMetadataHash
62
76
  include MetadataHash
63
77
 
78
+ private
79
+
64
80
  def described_class_for(*)
65
81
  ancestors.each do |g|
66
82
  return g[:describes] if g.has_key?(:describes)
@@ -76,7 +92,7 @@ module RSpec
76
92
 
77
93
  def full_description_for(*)
78
94
  build_description_from(*ancestors.reverse.map do |a|
79
- a.has_key?(:full_description) ? a[:full_description] : a[:description_args]
95
+ a[:description_args]
80
96
  end.flatten)
81
97
  end
82
98
 
@@ -105,6 +121,7 @@ module RSpec
105
121
  yield self if block_given?
106
122
  end
107
123
 
124
+ # @api private
108
125
  def process(*args)
109
126
  user_metadata = args.last.is_a?(Hash) ? args.pop : {}
110
127
  ensure_valid_keys(user_metadata)
@@ -115,18 +132,22 @@ module RSpec
115
132
  update(user_metadata)
116
133
  end
117
134
 
135
+ # @api private
118
136
  def for_example(description, user_metadata)
119
- dup.extend(MetadataHash).configure_for_example(description, user_metadata)
137
+ dup.extend(ExampleMetadataHash).configure_for_example(description, user_metadata)
120
138
  end
121
139
 
140
+ # @api private
122
141
  def any_apply?(filters)
123
142
  filters.any? {|k,v| filter_applies?(k,v)}
124
143
  end
125
144
 
145
+ # @api private
126
146
  def all_apply?(filters)
127
147
  filters.all? {|k,v| filter_applies?(k,v)}
128
148
  end
129
149
 
150
+ # @api private
130
151
  def filter_applies?(key, value, metadata=self)
131
152
  case value
132
153
  when Hash
@@ -28,22 +28,62 @@ module RSpec::Core
28
28
  OptionParser.new do |parser|
29
29
  parser.banner = "Usage: rspec [options] [files or directories]\n\n"
30
30
 
31
- parser.on('-b', '--backtrace', 'Enable full backtrace') do |o|
32
- options[:full_backtrace] = true
31
+ parser.on('-I DIRECTORY', 'specify $LOAD_PATH directory (may be used more than once)') do |dir|
32
+ options[:libs] ||= []
33
+ options[:libs] << dir
33
34
  end
34
35
 
35
- parser.on('-c', '--[no-]color', '--[no-]colour', 'Enable color in the output') do |o|
36
- options[:color_enabled] = o
36
+ parser.on('-r', '--require PATH', 'Require a file') do |path|
37
+ options[:requires] ||= []
38
+ options[:requires] << path
39
+ end
40
+
41
+ parser.on('-O', '--options PATH', 'Specify the path to a custom options file') do |path|
42
+ options[:custom_options_file] = path
43
+ end
44
+
45
+ parser.on('--order TYPE', 'Run examples by the specified order type',
46
+ ' [rand] randomized',
47
+ ' [random] alias for rand',
48
+ ' [random:SEED] e.g. --order random:123') do |o|
49
+ options[:order] = o
50
+ end
51
+
52
+ parser.on('--seed SEED', "Equivalent of --order rand:SEED") do |seed|
53
+ options[:order] = "rand:#{seed}"
37
54
  end
38
55
 
39
56
  parser.on('-d', '--debugger', 'Enable debugging') do |o|
40
57
  options[:debug] = true
41
58
  end
42
59
 
43
- parser.on('-e', '--example STRING', "Run examples whose full nested names include STRING") do |o|
44
- options[:full_description] = Regexp.compile(Regexp.escape(o))
60
+ parser.on('--fail-fast', 'Abort the run on first failure') do |o|
61
+ options[:fail_fast] = true
62
+ end
63
+
64
+ parser.on('--failure-exit-code CODE', 'Override the exit code used when there are failing specs') do |o|
65
+ options[:failure_exit_code] = o.to_i
45
66
  end
46
67
 
68
+ parser.on('-X', '--[no-]drb', 'Run examples via DRb') do |o|
69
+ options[:drb] = o
70
+ end
71
+
72
+ parser.on('--drb-port [PORT]', 'Port to connect to on the DRb server') do |o|
73
+ options[:drb_port] = o.to_i
74
+ end
75
+
76
+ parser.on('--configure COMMAND', 'Generate configuration files') do |cmd|
77
+ CommandLineConfiguration.new(cmd).run
78
+ exit
79
+ end
80
+
81
+ parser.on("--tty", "Used internally by rspec when sending commands to other processes") do |o|
82
+ options[:tty] = true
83
+ end
84
+
85
+ parser.separator("\n **** Output formatting ****\n\n")
86
+
47
87
  parser.on('-f', '--format FORMATTER', 'Choose a formatter',
48
88
  ' [p]rogress (default - dots)',
49
89
  ' [d]ocumentation (group and example names)',
@@ -63,84 +103,79 @@ module RSpec::Core
63
103
  options[:formatters].last << o
64
104
  end
65
105
 
66
- parser.on_tail('-h', '--help', "You're looking at it.") do
67
- puts parser
68
- exit
69
- end
70
-
71
- parser.on('-I DIRECTORY', 'specify $LOAD_PATH directory (may be used more than once)') do |dir|
72
- options[:libs] ||= []
73
- options[:libs] << dir
74
- end
75
-
76
- parser.on('-l', '--line_number LINE', 'Specify the line number of an example to run. May be specified multiple times.') do |o|
77
- (options[:line_numbers] ||= []) << o
106
+ parser.on('-b', '--backtrace', 'Enable full backtrace') do |o|
107
+ options[:full_backtrace] = true
78
108
  end
79
109
 
80
- parser.on('-O', '--options PATH', 'Specify the path to an options file') do |path|
81
- options[:custom_options_file] = path
110
+ parser.on('-c', '--[no-]color', '--[no-]colour', 'Enable color in the output') do |o|
111
+ options[:color] = o
82
112
  end
83
113
 
84
114
  parser.on('-p', '--profile', 'Enable profiling of examples with output of the top 10 slowest examples') do |o|
85
115
  options[:profile_examples] = o
86
116
  end
87
117
 
88
- parser.on('-P', '--pattern PATTERN', 'Load files matching this pattern. Default is "spec/**/*_spec.rb"') do |o|
89
- options[:pattern] = o
90
- end
118
+ parser.separator <<-FILTERING
91
119
 
92
- parser.on('-r', '--require PATH', 'Require a file') do |path|
93
- options[:requires] ||= []
94
- options[:requires] << path
95
- end
120
+ **** Filtering and tags ****
96
121
 
97
- parser.on('-v', '--version', 'Show version') do
98
- puts RSpec::Core::Version::STRING
99
- exit
100
- end
122
+ In addition to the following options for selecting specific files, groups,
123
+ or examples, you can select a single example by appending the line number to
124
+ the filename:
101
125
 
102
- parser.on('-X', '--[no-]drb', 'Run examples via DRb') do |o|
103
- options[:drb] = o
104
- end
126
+ rspec path/to/a_spec.rb:37
105
127
 
106
- parser.on('--configure COMMAND', 'Generate configuration files') do |cmd|
107
- CommandLineConfiguration.new(cmd).run
108
- exit
109
- end
128
+ FILTERING
110
129
 
111
- parser.on('--drb-port [PORT]', 'Port to connect to on the DRb server') do |o|
112
- options[:drb_port] = o.to_i
130
+ parser.on('-P', '--pattern PATTERN', 'Load files matching pattern (default: "spec/**/*_spec.rb")') do |o|
131
+ options[:pattern] = o
113
132
  end
114
133
 
115
- parser.on('--fail-fast', 'Abort the run on first failure.') do |o|
116
- options[:fail_fast] = true
134
+ parser.on('-e', '--example STRING', "Run examples whose full nested names include STRING") do |o|
135
+ options[:full_description] = Regexp.compile(Regexp.escape(o))
117
136
  end
118
137
 
119
- parser.on('--failure-exit-code CODE', 'Override the exit code used when there are failing specs.') do |o|
120
- options[:failure_exit_code] = o.to_i
138
+ parser.on('-l', '--line_number LINE', 'Specify line number of an example or group (may be specified multiple times)') do |o|
139
+ (options[:line_numbers] ||= []) << o
121
140
  end
122
141
 
123
- parser.on('-t', '--tag TAG[:VALUE]', 'Run examples with the specified tag',
124
- 'To exclude examples, add ~ before the tag (e.g. ~slow)',
125
- '(TAG is always converted to a symbol)') do |tag|
126
- filter_type = tag =~ /^~/ ? :exclusion_filter : :filter
142
+ parser.on('-t', '--tag TAG[:VALUE]',
143
+ 'Run examples with the specified tag, or exclude',
144
+ 'examples by ading ~ before the tag (e.g. ~slow)',
145
+ '(TAG is always converted to a symbol)') do |tag|
146
+ filter_type = tag =~ /^~/ ? :exclusion_filter : :inclusion_filter
127
147
 
128
148
  name,value = tag.gsub(/^(~@|~|@)/, '').split(':')
129
149
  name = name.to_sym
130
- value = true if value.nil?
131
150
 
132
151
  options[filter_type] ||= {}
133
- options[filter_type][name] = value
134
- end
135
-
136
- parser.on('--tty', 'Used internally by rspec when sending commands to other processes') do |o|
137
- options[:tty] = true
152
+ options[filter_type][name] = case value
153
+ when /^(true|false|nil)$/
154
+ eval(value)
155
+ when nil
156
+ true
157
+ else
158
+ value
159
+ end
138
160
  end
139
161
 
140
162
  parser.on('--default_path PATH', 'Set the default path where RSpec looks for examples.',
141
163
  'Can be a path to a file or a directory') do |path|
142
164
  options[:default_path] = path
143
165
  end
166
+
167
+ parser.separator("\n **** Utility ****\n\n")
168
+
169
+ parser.on('-v', '--version', 'Show version') do
170
+ puts RSpec::Core::Version::STRING
171
+ exit
172
+ end
173
+
174
+ parser.on_tail('-h', '--help', "You're looking at it.") do
175
+ puts parser
176
+ exit
177
+ end
178
+
144
179
  end
145
180
  end
146
181
  end