rspec-core 2.10.1 → 2.11.0
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/Changelog.md +35 -2
- data/README.md +14 -13
- data/features/command_line/example_name_option.feature +15 -0
- data/features/helper_methods/modules.feature +3 -3
- data/lib/rspec/core.rb +6 -2
- data/lib/rspec/core/configuration.rb +61 -26
- data/lib/rspec/core/configuration_options.rb +5 -1
- data/lib/rspec/core/deprecation.rb +0 -15
- data/lib/rspec/core/drb_command_line.rb +3 -0
- data/lib/rspec/core/drb_options.rb +3 -1
- data/lib/rspec/core/dsl.rb +4 -2
- data/lib/rspec/core/example.rb +85 -23
- data/lib/rspec/core/example_group.rb +103 -78
- data/lib/rspec/core/hooks.rb +68 -33
- data/lib/rspec/core/let.rb +0 -1
- data/lib/rspec/core/mocking/with_mocha.rb +10 -4
- data/lib/rspec/core/option_parser.rb +3 -2
- data/lib/rspec/core/project_initializer.rb +7 -1
- data/lib/rspec/core/runner.rb +2 -2
- data/lib/rspec/core/shared_context.rb +2 -2
- data/lib/rspec/core/shared_example_group.rb +38 -14
- data/lib/rspec/core/subject.rb +67 -52
- data/lib/rspec/core/version.rb +1 -1
- data/spec/rspec/core/command_line_spec.rb +68 -126
- data/spec/rspec/core/configuration_options_spec.rb +20 -4
- data/spec/rspec/core/configuration_spec.rb +61 -21
- data/spec/rspec/core/drb_command_line_spec.rb +1 -0
- data/spec/rspec/core/drb_options_spec.rb +1 -0
- data/spec/rspec/core/dsl_spec.rb +17 -0
- data/spec/rspec/core/example_group_spec.rb +19 -11
- data/spec/rspec/core/example_spec.rb +34 -0
- data/spec/rspec/core/option_parser_spec.rb +2 -1
- data/spec/rspec/core/shared_example_group_spec.rb +9 -9
- data/spec/rspec/core/subject_spec.rb +14 -0
- data/spec/rspec/core_spec.rb +18 -8
- data/spec/spec_helper.rb +1 -2
- metadata +7 -5
data/Changelog.md
CHANGED
@@ -1,3 +1,36 @@
|
|
1
|
+
### 2.11.0 / 2012-07-07
|
2
|
+
[full changelog](http://github.com/rspec/rspec-core/compare/v2.10.1...v2.11.0)
|
3
|
+
|
4
|
+
Enhancements
|
5
|
+
|
6
|
+
* Support multiple `--example` options. (Daniel Doubrovkine @dblock)
|
7
|
+
* Named subject e.g. `subject(:article) { Article.new }`
|
8
|
+
* see [http://blog.davidchelimsky.net/2012/05/13/spec-smell-explicit-use-of-subject/](http://blog.davidchelimsky.net/2012/05/13/spec-smell-explicit-use-of-subject/)
|
9
|
+
for background.
|
10
|
+
* thanks to Bradley Schaefer for suggesting it and Avdi Grimm for almost
|
11
|
+
suggesting it.
|
12
|
+
* `config.mock_with` and `config.expect_with` yield custom config object to a
|
13
|
+
block if given
|
14
|
+
* aids decoupling from rspec-core's configuation
|
15
|
+
* `include_context` and `include_examples` support a block, which gets eval'd
|
16
|
+
in the current context (vs the nested context generated by `it_behaves_like`).
|
17
|
+
* Add `config.order = 'random'` to the `spec_helper.rb` generated by `rspec
|
18
|
+
--init`.
|
19
|
+
* Delay the loading of DRb (Myron Marston).
|
20
|
+
* Limit monkey patching of `describe` onto just the objects that need it rather
|
21
|
+
than every object in the system (Myron Marston).
|
22
|
+
|
23
|
+
Bug fixes
|
24
|
+
|
25
|
+
* Support alternative path separators. For example, on Windows, you can now do
|
26
|
+
this: `rspec spec\subdir`. (Jarmo Pertman @jarmo)
|
27
|
+
* When an example raises an error and an after or around hook does as
|
28
|
+
well, print out the hook error. Previously, the error was silenced and
|
29
|
+
the user got no feedback about what happened. (Myron Marston)
|
30
|
+
* `--require` and `-I` are merged among different configuration sources (Andy
|
31
|
+
Lindeman)
|
32
|
+
* Delegate to mocha methods instead of aliasing them in mocha adapter.
|
33
|
+
|
1
34
|
### 2.10.1 / 2012-05-19
|
2
35
|
[full changelog](http://github.com/rspec/rspec-core/compare/v2.10.0...v2.10.1)
|
3
36
|
|
@@ -44,8 +77,8 @@ Bug fixes
|
|
44
77
|
over DRb (using spork).
|
45
78
|
* Ensure shared example groups are reset after a run (as example groups are).
|
46
79
|
* Remove `rescue false` from calls to filters represented as Procs
|
47
|
-
* Ensure described_class gets the closest constant (pyromaniac)
|
48
|
-
* In "autorun", don't run the specs in the at_exit hook if there was an
|
80
|
+
* Ensure `described_class` gets the closest constant (pyromaniac)
|
81
|
+
* In "autorun", don't run the specs in the `at_exit` hook if there was an
|
49
82
|
exception (most likely due to a SyntaxError). (sunaku)
|
50
83
|
* Don't extend groups with modules already used to extend ancestor groups.
|
51
84
|
* `its` correctly memoizes nil or false values (Yamada Masaki)
|
data/README.md
CHANGED
@@ -1,21 +1,22 @@
|
|
1
|
-
# rspec-core
|
1
|
+
# rspec-core [](http://travis-ci.org/rspec/rspec-core) [](https://codeclimate.com/github/rspec/rspec-core)
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
```
|
3
|
+
rspec-core provides the structure for writing executable examples of how your
|
4
|
+
code should behave, and an `rspec` command with tools to constrain which
|
5
|
+
examples get run and taylor the output.
|
7
6
|
|
8
|
-
|
7
|
+
## install
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
gem install rspec # for rspec-core, rspec-expectations, rspec-mocks
|
10
|
+
gem install rspec-core # for rspec-core only
|
11
|
+
rspec --help
|
12
|
+
|
13
|
+
## basic structure
|
14
|
+
|
15
|
+
RSpec uses the words "describe" and "it" so we can express concepts like a conversation:
|
13
16
|
|
14
17
|
"Describe an order."
|
15
18
|
"It sums the prices of its line items."
|
16
19
|
|
17
|
-
## basic structure
|
18
|
-
|
19
20
|
```ruby
|
20
21
|
describe Order do
|
21
22
|
it "sums the prices of its line items" do
|
@@ -95,8 +96,8 @@ hooks, `let` declarations, and nested groups/contexts.
|
|
95
96
|
|
96
97
|
You can also use the names `shared_context` and `include_context`. These are
|
97
98
|
pretty much the same as `shared_examples` and `include_examples`, providing
|
98
|
-
more accurate naming
|
99
|
-
|
99
|
+
more accurate naming when you share hooks, `let` declarations, helper methods,
|
100
|
+
etc, but no examples.
|
100
101
|
|
101
102
|
## metadata
|
102
103
|
|
@@ -8,6 +8,8 @@ Feature: --example option
|
|
8
8
|
|
9
9
|
This allows you to run a single uniquely named example, all examples with
|
10
10
|
similar names, all the examples in a uniquely named group, etc, etc.
|
11
|
+
|
12
|
+
You can also use the option more than once to specify multiple example matches.
|
11
13
|
|
12
14
|
Background:
|
13
15
|
Given a file named "first_spec.rb" with:
|
@@ -84,3 +86,16 @@ Feature: --example option
|
|
84
86
|
Scenario: Object#method
|
85
87
|
When I run `rspec . --example 'Array#length'`
|
86
88
|
Then the examples should all pass
|
89
|
+
|
90
|
+
Scenario: Multiple applications of example name option
|
91
|
+
When I run `rspec . --example 'first group' --example 'second group' --format d`
|
92
|
+
Then the examples should all pass
|
93
|
+
And the output should contain all of these:
|
94
|
+
|first example in first group|
|
95
|
+
|second example in first group|
|
96
|
+
|first example in second group|
|
97
|
+
|second example in second group|
|
98
|
+
And the output should not contain any of these:
|
99
|
+
|first example in third group|
|
100
|
+
|nested group first example in nested group|
|
101
|
+
|nested group second example in nested group|
|
@@ -33,7 +33,7 @@ Feature: Define helper methods in a module
|
|
33
33
|
end
|
34
34
|
|
35
35
|
describe "an example group" do
|
36
|
-
it "has access the helper methods defined in the module" do
|
36
|
+
it "has access to the helper methods defined in the module" do
|
37
37
|
help.should be(:available)
|
38
38
|
end
|
39
39
|
end
|
@@ -72,7 +72,7 @@ Feature: Define helper methods in a module
|
|
72
72
|
end
|
73
73
|
|
74
74
|
describe "an example group with matching metadata", :foo => :bar do
|
75
|
-
it "has access the helper methods defined in the module" do
|
75
|
+
it "has access to the helper methods defined in the module" do
|
76
76
|
help.should be(:available)
|
77
77
|
end
|
78
78
|
end
|
@@ -130,7 +130,7 @@ Feature: Define helper methods in a module
|
|
130
130
|
describe "an example group with matching include metadata", :include_helpers do
|
131
131
|
puts "In a group not matching the extend filter, help is #{help rescue 'not available'}"
|
132
132
|
|
133
|
-
it "has access the helper methods defined in the module" do
|
133
|
+
it "has access to the helper methods defined in the module" do
|
134
134
|
help.should be(:available)
|
135
135
|
end
|
136
136
|
end
|
data/lib/rspec/core.rb
CHANGED
@@ -11,6 +11,7 @@ else
|
|
11
11
|
end
|
12
12
|
|
13
13
|
require 'set'
|
14
|
+
require 'rbconfig'
|
14
15
|
require_rspec 'core/filter_manager'
|
15
16
|
require_rspec 'core/dsl'
|
16
17
|
require_rspec 'core/extensions'
|
@@ -30,10 +31,8 @@ require_rspec 'core/world'
|
|
30
31
|
require_rspec 'core/configuration'
|
31
32
|
require_rspec 'core/project_initializer'
|
32
33
|
require_rspec 'core/option_parser'
|
33
|
-
require_rspec 'core/drb_options'
|
34
34
|
require_rspec 'core/configuration_options'
|
35
35
|
require_rspec 'core/command_line'
|
36
|
-
require_rspec 'core/drb_command_line'
|
37
36
|
require_rspec 'core/runner'
|
38
37
|
require_rspec 'core/example'
|
39
38
|
require_rspec 'core/shared_example_group'
|
@@ -100,6 +99,11 @@ module RSpec
|
|
100
99
|
world.example_groups.clear
|
101
100
|
end
|
102
101
|
|
102
|
+
# @private
|
103
|
+
def self.windows_os?
|
104
|
+
/mswin|mingw/ === ::RbConfig::CONFIG['host_os']
|
105
|
+
end
|
106
|
+
|
103
107
|
module Core
|
104
108
|
end
|
105
109
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require "rbconfig"
|
2
1
|
require 'fileutils'
|
3
2
|
|
4
3
|
module RSpec
|
@@ -278,24 +277,31 @@ MESSAGE
|
|
278
277
|
#
|
279
278
|
# `framework` can be a Symbol or a Module.
|
280
279
|
#
|
281
|
-
# Given any of
|
282
|
-
# framework.
|
280
|
+
# Given any of `:rspec`, `:mocha`, `:flexmock`, or `:rr`, configures the
|
281
|
+
# named framework.
|
283
282
|
#
|
284
|
-
# Given
|
285
|
-
# mocking framework to save a little bit of overhead.
|
283
|
+
# Given `:nothing`, configures no framework. Use this if you don't use
|
284
|
+
# any mocking framework to save a little bit of overhead.
|
286
285
|
#
|
287
286
|
# Given a Module, includes that module in every example group. The module
|
288
287
|
# should adhere to RSpec's mock framework adapter API:
|
289
288
|
#
|
290
|
-
#
|
291
|
-
#
|
289
|
+
# setup_mocks_for_rspec
|
290
|
+
# - called before each example
|
292
291
|
#
|
293
|
-
#
|
294
|
-
#
|
295
|
-
#
|
292
|
+
# verify_mocks_for_rspec
|
293
|
+
# - called after each example. Framework should raise an exception
|
294
|
+
# when expectations fail
|
296
295
|
#
|
297
|
-
#
|
298
|
-
#
|
296
|
+
# teardown_mocks_for_rspec
|
297
|
+
# - called after verify_mocks_for_rspec (even if there are errors)
|
298
|
+
#
|
299
|
+
# If the module responds to `configuration` and `mock_with` receives a block,
|
300
|
+
# it will yield the configuration object to the block e.g.
|
301
|
+
#
|
302
|
+
# config.mock_with OtherMockFrameworkAdapter do |mod_config|
|
303
|
+
# mod_config.custom_setting = true
|
304
|
+
# end
|
299
305
|
def mock_with(framework)
|
300
306
|
framework_module = case framework
|
301
307
|
when Module
|
@@ -324,6 +330,11 @@ MESSAGE
|
|
324
330
|
assert_no_example_groups_defined(:mock_framework)
|
325
331
|
end
|
326
332
|
|
333
|
+
if block_given?
|
334
|
+
raise "#{framework_module} must respond to `configuration` so that mock_with can yield it." unless framework_module.respond_to?(:configuration)
|
335
|
+
yield framework_module.configuration
|
336
|
+
end
|
337
|
+
|
327
338
|
@mock_framework = framework_module
|
328
339
|
end
|
329
340
|
|
@@ -338,16 +349,33 @@ MESSAGE
|
|
338
349
|
expect_with(framework)
|
339
350
|
end
|
340
351
|
|
341
|
-
# Sets the expectation framework module(s)
|
352
|
+
# Sets the expectation framework module(s) to be included in each example
|
353
|
+
# group.
|
354
|
+
#
|
355
|
+
# `frameworks` can be `:rspec`, `:stdlib`, a custom module, or any
|
356
|
+
# combination thereof:
|
357
|
+
#
|
358
|
+
# config.expect_with :rspec
|
359
|
+
# config.expect_with :stdlib
|
360
|
+
# config.expect_with :rspec, :stdlib
|
361
|
+
# config.expect_with OtherExpectationFramework
|
342
362
|
#
|
343
|
-
#
|
363
|
+
# RSpec will translate `:rspec` and `:stdlib` into the appropriate
|
364
|
+
# modules.
|
344
365
|
#
|
345
|
-
#
|
346
|
-
#
|
347
|
-
#
|
366
|
+
# ## Configuration
|
367
|
+
#
|
368
|
+
# If the module responds to `configuration`, `expect_with` will
|
369
|
+
# yield the `configuration` object if given a block:
|
370
|
+
#
|
371
|
+
# config.expect_with OtherExpectationFramework do |custom_config|
|
372
|
+
# custom_config.custom_setting = true
|
373
|
+
# end
|
348
374
|
def expect_with(*frameworks)
|
349
375
|
modules = frameworks.map do |framework|
|
350
376
|
case framework
|
377
|
+
when Module
|
378
|
+
framework
|
351
379
|
when :rspec
|
352
380
|
require 'rspec/expectations'
|
353
381
|
self.expecting_with_rspec = true
|
@@ -364,7 +392,12 @@ MESSAGE
|
|
364
392
|
assert_no_example_groups_defined(:expect_with)
|
365
393
|
end
|
366
394
|
|
367
|
-
|
395
|
+
if block_given?
|
396
|
+
raise "expect_with only accepts a block with a single argument. Call expect_with #{modules.length} times, once with each argument, instead." if modules.length > 1
|
397
|
+
raise "#{modules.first} must respond to `configuration` so that expect_with can yield it." unless modules.first.respond_to?(:configuration)
|
398
|
+
yield modules.first.configuration
|
399
|
+
end
|
400
|
+
|
368
401
|
@expectation_frameworks.push(*modules)
|
369
402
|
end
|
370
403
|
|
@@ -378,10 +411,9 @@ MESSAGE
|
|
378
411
|
end
|
379
412
|
|
380
413
|
def color=(bool)
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
unless ENV['ANSICON']
|
414
|
+
if bool
|
415
|
+
@color = true
|
416
|
+
if RSpec.windows_os? and not ENV['ANSICON']
|
385
417
|
warn "You must use ANSICON 1.31 or later (http://adoxa.110mb.com/ansicon/) to use colour on Windows"
|
386
418
|
@color = false
|
387
419
|
end
|
@@ -429,7 +461,7 @@ EOM
|
|
429
461
|
end
|
430
462
|
|
431
463
|
def full_description=(description)
|
432
|
-
filter_run :full_description =>
|
464
|
+
filter_run :full_description => Regexp.union(*Array(description).map {|d| Regexp.new(d) })
|
433
465
|
end
|
434
466
|
|
435
467
|
# @overload add_formatter(formatter)
|
@@ -504,7 +536,7 @@ EOM
|
|
504
536
|
#
|
505
537
|
# Example:
|
506
538
|
#
|
507
|
-
#
|
539
|
+
# alias_it_behaves_like_to(:it_has_behavior, 'has behavior:')
|
508
540
|
#
|
509
541
|
# allows the user to include a shared example group like:
|
510
542
|
#
|
@@ -519,10 +551,12 @@ EOM
|
|
519
551
|
# Entity
|
520
552
|
# has behavior: sortability
|
521
553
|
# # sortability examples here
|
522
|
-
def
|
523
|
-
RSpec::Core::ExampleGroup.
|
554
|
+
def alias_it_behaves_like_to(new_name, report_label = '')
|
555
|
+
RSpec::Core::ExampleGroup.alias_it_behaves_like_to(new_name, report_label)
|
524
556
|
end
|
525
557
|
|
558
|
+
alias_method :alias_it_should_behave_like_to, :alias_it_behaves_like_to
|
559
|
+
|
526
560
|
# Adds key/value pairs to the `inclusion_filter`. If the
|
527
561
|
# `treat_symbols_as_metadata_keys_with_true_values` config option is set
|
528
562
|
# to true and `args` includes any symbols that are not part of a hash,
|
@@ -770,6 +804,7 @@ EOM
|
|
770
804
|
def get_files_to_run(paths)
|
771
805
|
patterns = pattern.split(",")
|
772
806
|
paths.map do |path|
|
807
|
+
path = path.gsub(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR
|
773
808
|
File.directory?(path) ? gather_directories(path, patterns) : extract_location(path)
|
774
809
|
end.flatten
|
775
810
|
end
|
@@ -25,7 +25,9 @@ module RSpec
|
|
25
25
|
|
26
26
|
def parse_options
|
27
27
|
@options ||= extract_filters_from(*all_configs).inject do |merged, pending|
|
28
|
-
merged.merge(pending)
|
28
|
+
merged.merge(pending) { |key, oldval, newval|
|
29
|
+
MERGED_OPTIONS.include?(key) ? oldval + newval : newval
|
30
|
+
}
|
29
31
|
end
|
30
32
|
end
|
31
33
|
|
@@ -44,6 +46,8 @@ module RSpec
|
|
44
46
|
:line_numbers, :full_description, :full_backtrace, :tty
|
45
47
|
].to_set
|
46
48
|
|
49
|
+
MERGED_OPTIONS = [:requires, :libs].to_set
|
50
|
+
|
47
51
|
def force?(key)
|
48
52
|
!NON_FORCED_OPTIONS.include?(key)
|
49
53
|
end
|
@@ -33,19 +33,4 @@ ADDITIONAL
|
|
33
33
|
send :warn, message
|
34
34
|
end
|
35
35
|
end
|
36
|
-
|
37
|
-
# @private
|
38
|
-
class HashWithDeprecationNotice < Hash
|
39
|
-
|
40
|
-
def initialize(method, alternate_method=nil)
|
41
|
-
@method, @alternate_method = method, alternate_method
|
42
|
-
end
|
43
|
-
|
44
|
-
def []=(k,v)
|
45
|
-
RSpec.deprecate(@method, @alternate_method)
|
46
|
-
super(k,v)
|
47
|
-
end
|
48
|
-
|
49
|
-
end
|
50
|
-
|
51
36
|
end
|
@@ -42,7 +42,9 @@ module RSpec::Core
|
|
42
42
|
# into a regexp when received for the first time (see OptionParser).
|
43
43
|
# Hence, merely grabbing the source of this regexp will retain the
|
44
44
|
# backslashes, so we must remove them.
|
45
|
-
|
45
|
+
@submitted_options[:full_description].each do |description|
|
46
|
+
argv << "--example" << description.source.delete('\\')
|
47
|
+
end
|
46
48
|
end
|
47
49
|
end
|
48
50
|
|
data/lib/rspec/core/dsl.rb
CHANGED
@@ -2,7 +2,7 @@ module RSpec
|
|
2
2
|
module Core
|
3
3
|
# Adds the `describe` method to the top-level namespace.
|
4
4
|
module DSL
|
5
|
-
# Generates a subclass of
|
5
|
+
# Generates a subclass of {ExampleGroup}
|
6
6
|
#
|
7
7
|
# ## Examples:
|
8
8
|
#
|
@@ -21,4 +21,6 @@ module RSpec
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
|
24
|
+
extend RSpec::Core::DSL
|
25
|
+
Module.send(:include, RSpec::Core::DSL)
|
26
|
+
|
data/lib/rspec/core/example.rb
CHANGED
@@ -1,11 +1,37 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Core
|
3
|
-
# Wrapper for an instance of a subclass of
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
3
|
+
# Wrapper for an instance of a subclass of {ExampleGroup}. An instance of
|
4
|
+
# `Example` is returned by the {ExampleGroup#example example} method
|
5
|
+
# exposed to examples, {Hooks#before before} and {Hooks#after after} hooks,
|
6
|
+
# and yielded to {Hooks#around around} hooks.
|
7
|
+
#
|
8
|
+
# Useful for configuring logging and/or taking some action based
|
9
|
+
# on the state of an example's metadata.
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
#
|
13
|
+
# RSpec.configure do |config|
|
14
|
+
# config.before do
|
15
|
+
# log example.description
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# config.after do
|
19
|
+
# log example.description
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# config.around do |ex|
|
23
|
+
# log example.description
|
24
|
+
# ex.run
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# shared_examples "auditable" do
|
29
|
+
# it "does something" do
|
30
|
+
# log "#{example.full_description}: #{auditable.inspect}"
|
31
|
+
# auditable.should do_something
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
#
|
9
35
|
# @see ExampleGroup
|
10
36
|
class Example
|
11
37
|
# @private
|
@@ -70,9 +96,9 @@ module RSpec
|
|
70
96
|
alias_method :pending?, :pending
|
71
97
|
|
72
98
|
# @api private
|
99
|
+
# instance_evals the block passed to the constructor in the context of
|
100
|
+
# the instance of {ExampleGroup}.
|
73
101
|
# @param example_group_instance the instance of an ExampleGroup subclass
|
74
|
-
# instance_evals the block submitted to the constructor in the
|
75
|
-
# context of the instance of ExampleGroup
|
76
102
|
def run(example_group_instance, reporter)
|
77
103
|
@example_group_instance = example_group_instance
|
78
104
|
@example_group_instance.example = self
|
@@ -103,16 +129,16 @@ module RSpec
|
|
103
129
|
@example_group_instance = nil
|
104
130
|
|
105
131
|
begin
|
106
|
-
|
132
|
+
assign_generated_description
|
107
133
|
rescue Exception => e
|
108
|
-
set_exception(e)
|
134
|
+
set_exception(e, "while assigning the example description")
|
109
135
|
end
|
110
136
|
end
|
111
137
|
|
112
138
|
finish(reporter)
|
113
139
|
end
|
114
140
|
|
115
|
-
# @private
|
141
|
+
# @api private
|
116
142
|
#
|
117
143
|
# Wraps the example block in a Proc so it can invoked using `run` or
|
118
144
|
# `call` in [around](../Hooks#around-instance_method) hooks.
|
@@ -120,20 +146,39 @@ module RSpec
|
|
120
146
|
proc.extend(Procsy).with(metadata)
|
121
147
|
end
|
122
148
|
|
123
|
-
#
|
149
|
+
# Used to extend a `Proc` with behavior that makes it look something like
|
150
|
+
# an {Example} in an {Hooks#around around} hook.
|
151
|
+
#
|
152
|
+
# @note Procsy, itself, is not a public API, but we're documenting it
|
153
|
+
# here to document how to interact with the object yielded to an
|
154
|
+
# `around` hook.
|
155
|
+
#
|
156
|
+
# @example
|
157
|
+
#
|
158
|
+
# RSpec.configure do |c|
|
159
|
+
# c.around do |ex| # ex is a Proc extended with Procsy
|
160
|
+
# if ex.metadata[:key] == :some_value && some_global_condition
|
161
|
+
# raise "some message"
|
162
|
+
# end
|
163
|
+
# ex.run # run delegates to ex.call
|
164
|
+
# end
|
165
|
+
# end
|
124
166
|
module Procsy
|
167
|
+
# The `metadata` of the {Example} instance.
|
125
168
|
attr_reader :metadata
|
126
169
|
|
127
|
-
# @private
|
170
|
+
# @api private
|
128
171
|
# @param [Proc]
|
129
172
|
# Adds a `run` method to the extended Proc, allowing it to be invoked
|
130
173
|
# in an [around](../Hooks#around-instance_method) hook using either
|
131
174
|
# `run` or `call`.
|
132
|
-
def self.extended(
|
133
|
-
|
175
|
+
def self.extended(proc)
|
176
|
+
# @api public
|
177
|
+
# Foo bar
|
178
|
+
def proc.run; call; end
|
134
179
|
end
|
135
180
|
|
136
|
-
# @private
|
181
|
+
# @api private
|
137
182
|
def with(metadata)
|
138
183
|
@metadata = metadata
|
139
184
|
self
|
@@ -159,7 +204,20 @@ module RSpec
|
|
159
204
|
#
|
160
205
|
# Used internally to set an exception in an after hook, which
|
161
206
|
# captures the exception but doesn't raise it.
|
162
|
-
def set_exception(exception)
|
207
|
+
def set_exception(exception, context=nil)
|
208
|
+
if @exception
|
209
|
+
# An error has already been set; we don't want to override it,
|
210
|
+
# but we also don't want silence the error, so let's print it.
|
211
|
+
msg = <<-EOS
|
212
|
+
|
213
|
+
An error occurred #{context}
|
214
|
+
#{exception.class}: #{exception.message}
|
215
|
+
occurred at #{exception.backtrace.first}
|
216
|
+
|
217
|
+
EOS
|
218
|
+
RSpec.configuration.reporter.message(msg)
|
219
|
+
end
|
220
|
+
|
163
221
|
@exception ||= exception
|
164
222
|
end
|
165
223
|
|
@@ -179,8 +237,8 @@ module RSpec
|
|
179
237
|
end
|
180
238
|
|
181
239
|
# @private
|
182
|
-
def instance_eval_with_rescue(&block)
|
183
|
-
@example_group_instance.instance_eval_with_rescue(&block)
|
240
|
+
def instance_eval_with_rescue(context = nil, &block)
|
241
|
+
@example_group_instance.instance_eval_with_rescue(context, &block)
|
184
242
|
end
|
185
243
|
|
186
244
|
# @private
|
@@ -196,6 +254,8 @@ module RSpec
|
|
196
254
|
else
|
197
255
|
@example_group_class.run_around_each_hooks(self, Example.procsy(metadata, &block))
|
198
256
|
end
|
257
|
+
rescue Exception => e
|
258
|
+
set_exception(e, "in an around(:each) hook")
|
199
259
|
end
|
200
260
|
|
201
261
|
def start(reporter)
|
@@ -235,18 +295,20 @@ module RSpec
|
|
235
295
|
end
|
236
296
|
|
237
297
|
def run_before_each
|
238
|
-
@example_group_instance.setup_mocks_for_rspec
|
298
|
+
@example_group_instance.setup_mocks_for_rspec
|
239
299
|
@example_group_class.run_before_each_hooks(self)
|
240
300
|
end
|
241
301
|
|
242
302
|
def run_after_each
|
243
303
|
@example_group_class.run_after_each_hooks(self)
|
244
|
-
@example_group_instance.verify_mocks_for_rspec
|
304
|
+
@example_group_instance.verify_mocks_for_rspec
|
305
|
+
rescue Exception => e
|
306
|
+
set_exception(e, "in an after(:each) hook")
|
245
307
|
ensure
|
246
|
-
@example_group_instance.teardown_mocks_for_rspec
|
308
|
+
@example_group_instance.teardown_mocks_for_rspec
|
247
309
|
end
|
248
310
|
|
249
|
-
def
|
311
|
+
def assign_generated_description
|
250
312
|
return unless RSpec.configuration.expecting_with_rspec?
|
251
313
|
if metadata[:description].empty? and !pending?
|
252
314
|
metadata[:description] = RSpec::Matchers.generated_description
|