rspec-core 2.0.0.a1 → 2.0.0.a2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +34 -3
- data/Rakefile +32 -17
- data/bin/rspec +5 -7
- data/cucumber.yml +3 -2
- data/features-pending/example_groups/example_group_with_should_methods.feature +3 -1
- data/features/before_and_after_blocks/around.feature +34 -0
- data/features/example_groups/describe_aliases.feature +20 -0
- data/{features-pending → features}/example_groups/nested_groups.feature +6 -8
- data/features/expectations/customized_message.feature +6 -6
- data/{features-pending → features}/matchers/define_matcher.feature +9 -9
- data/features/mock_framework_integration/use_rspec.feature +1 -1
- data/features/mocks/block_local_expectations.feature +68 -0
- data/{features-pending → features}/mocks/mix_stubs_and_mocks.feature +5 -1
- data/features/support/env.rb +6 -18
- data/lib/rspec/core.rb +5 -5
- data/lib/rspec/core/advice.rb +49 -0
- data/lib/rspec/core/command_line_options.rb +4 -11
- data/lib/rspec/core/configuration.rb +20 -32
- data/lib/rspec/core/example.rb +48 -15
- data/lib/rspec/core/example_group.rb +68 -93
- data/lib/rspec/core/extensions/instance_exec.rb +31 -0
- data/lib/rspec/core/kernel_extensions.rb +3 -1
- data/lib/rspec/core/load_path.rb +4 -0
- data/lib/rspec/core/metadata.rb +78 -0
- data/lib/rspec/core/rake_task.rb +3 -4
- data/lib/rspec/core/ruby_project.rb +30 -0
- data/lib/rspec/core/runner.rb +6 -7
- data/lib/rspec/core/version.rb +2 -2
- data/lib/rspec/core/world.rb +6 -4
- data/rspec-core.gemspec +33 -14
- data/spec/rspec/core/command_line_options_spec.rb +10 -10
- data/spec/rspec/core/configuration_spec.rb +26 -21
- data/spec/rspec/core/example_group_spec.rb +243 -173
- data/spec/rspec/core/example_group_subject_spec.rb +1 -1
- data/spec/rspec/core/example_spec.rb +12 -22
- data/spec/rspec/core/formatters/base_formatter_spec.rb +1 -1
- data/spec/rspec/core/formatters/documentation_formatter_spec.rb +1 -1
- data/spec/rspec/core/formatters/progress_formatter_spec.rb +4 -3
- data/spec/rspec/core/kernel_extensions_spec.rb +1 -1
- data/spec/rspec/core/metadata_spec.rb +101 -0
- data/spec/rspec/core/mocha_spec.rb +2 -2
- data/spec/rspec/core/runner_spec.rb +5 -5
- data/spec/rspec/core/shared_behaviour_spec.rb +5 -5
- data/spec/rspec/core/world_spec.rb +8 -8
- data/spec/rspec/core_spec.rb +1 -1
- data/spec/spec_helper.rb +15 -8
- data/specs.watchr +57 -0
- metadata +53 -15
- data/VERSION +0 -1
- data/VERSION.yml +0 -5
data/features/support/env.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require 'pathname'
|
2
|
+
RSPEC_LIB = File.expand_path('../../../lib', __FILE__)
|
3
3
|
|
4
4
|
require 'forwardable'
|
5
5
|
require 'tempfile'
|
6
6
|
require 'spec/ruby_forker'
|
7
7
|
require 'features/support/matchers/smart_match'
|
8
8
|
|
9
|
-
|
10
9
|
class RspecWorld
|
11
10
|
include Rspec::Expectations
|
12
11
|
include Rspec::Matchers
|
@@ -16,16 +15,12 @@ class RspecWorld
|
|
16
15
|
def_delegators RspecWorld, :working_dir, :spec_command
|
17
16
|
|
18
17
|
def self.working_dir
|
19
|
-
@working_dir ||= File.expand_path(
|
18
|
+
@working_dir ||= File.expand_path('../../../tmp/cucumber-generated-files', __FILE__)
|
20
19
|
end
|
21
20
|
|
22
21
|
def self.spec_command
|
23
|
-
@spec_command ||= File.expand_path(
|
22
|
+
@spec_command ||= File.expand_path('../../../bin/rspec', __FILE__)
|
24
23
|
end
|
25
|
-
|
26
|
-
RSPEC_LIB = File.expand_path(File.join(working_dir, "/../../lib"))
|
27
|
-
RSPEC_EXPECTATIONS_LIB = File.expand_path(File.join(working_dir, "/../../../expectations/lib"))
|
28
|
-
RSPEC_MOCKS_LIB = File.expand_path(File.join(working_dir, "/../../../mocks/lib"))
|
29
24
|
|
30
25
|
def spec(args)
|
31
26
|
ruby("#{spec_command} #{args}")
|
@@ -49,14 +44,7 @@ class RspecWorld
|
|
49
44
|
end
|
50
45
|
|
51
46
|
def rspec_libs
|
52
|
-
|
53
|
-
if File.directory?(RSPEC_EXPECTATIONS_LIB)
|
54
|
-
result << " -I #{RSPEC_EXPECTATIONS_LIB}"
|
55
|
-
end
|
56
|
-
if File.directory?(RSPEC_MOCKS_LIB)
|
57
|
-
result << " -I #{RSPEC_MOCKS_LIB}"
|
58
|
-
end
|
59
|
-
result
|
47
|
+
"-I #{RSPEC_LIB} -I #{working_dir}"
|
60
48
|
end
|
61
49
|
|
62
50
|
# it seems like this, and the last_* methods, could be moved into RubyForker-- is that being used anywhere but the features?
|
@@ -64,7 +52,7 @@ class RspecWorld
|
|
64
52
|
stderr_file = Tempfile.new('rspec')
|
65
53
|
stderr_file.close
|
66
54
|
Dir.chdir(working_dir) do
|
67
|
-
@stdout = super("#{rspec_libs} #{args}", stderr_file.path)
|
55
|
+
@stdout = super("-rrubygems #{rspec_libs} #{args}", stderr_file.path)
|
68
56
|
end
|
69
57
|
@stderr = IO.read(stderr_file.path)
|
70
58
|
@exit_code = $?.to_i
|
data/lib/rspec/core.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'rspec/core/load_path'
|
1
2
|
require 'rspec/core/deprecation'
|
2
3
|
require 'rspec/core/mocking/with_absolutely_nothing'
|
3
4
|
require 'rspec/core/world'
|
@@ -5,6 +6,7 @@ require 'rspec/core/configuration'
|
|
5
6
|
require 'rspec/core/command_line_options'
|
6
7
|
require 'rspec/core/runner'
|
7
8
|
require 'rspec/core/example'
|
9
|
+
require 'rspec/core/metadata'
|
8
10
|
require 'rspec/core/kernel_extensions'
|
9
11
|
require 'rspec/core/shared_behaviour'
|
10
12
|
require 'rspec/core/example_group_subject'
|
@@ -15,11 +17,9 @@ require 'rspec/core/version'
|
|
15
17
|
|
16
18
|
module Rspec
|
17
19
|
module Core
|
18
|
-
|
20
|
+
|
19
21
|
def self.install_directory
|
20
22
|
@install_directory ||= File.expand_path(File.dirname(__FILE__))
|
21
|
-
puts "@install_directory => #{@install_directory}"
|
22
|
-
@install_directory
|
23
23
|
end
|
24
24
|
|
25
25
|
def self.configuration
|
@@ -29,10 +29,10 @@ module Rspec
|
|
29
29
|
def self.configure
|
30
30
|
yield configuration if block_given?
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
def self.world
|
34
34
|
@world ||= Rspec::Core::World.new
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
end
|
38
38
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Rspec
|
2
|
+
module Core
|
3
|
+
module Advice
|
4
|
+
def before_blocks
|
5
|
+
@before_blocks ||= { :all => [], :each => [] }
|
6
|
+
end
|
7
|
+
|
8
|
+
def after_blocks
|
9
|
+
@after_blocks ||= { :all => [], :each => [] }
|
10
|
+
end
|
11
|
+
|
12
|
+
def around_blocks
|
13
|
+
@around_blocks ||= { :each => [] }
|
14
|
+
end
|
15
|
+
|
16
|
+
def before_eachs
|
17
|
+
before_blocks[:each]
|
18
|
+
end
|
19
|
+
|
20
|
+
def before_alls
|
21
|
+
before_blocks[:all]
|
22
|
+
end
|
23
|
+
|
24
|
+
def before(type=:each, &block)
|
25
|
+
before_blocks[type] << block
|
26
|
+
end
|
27
|
+
|
28
|
+
def after_eachs
|
29
|
+
after_blocks[:each]
|
30
|
+
end
|
31
|
+
|
32
|
+
def after_alls
|
33
|
+
after_blocks[:all]
|
34
|
+
end
|
35
|
+
|
36
|
+
def after(type=:each, &block)
|
37
|
+
after_blocks[type] << block
|
38
|
+
end
|
39
|
+
|
40
|
+
def around_eachs
|
41
|
+
around_blocks[:each]
|
42
|
+
end
|
43
|
+
|
44
|
+
def around(type=:each, &block)
|
45
|
+
around_blocks[type] << block
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -9,9 +9,7 @@ module Rspec
|
|
9
9
|
attr_reader :args, :options
|
10
10
|
|
11
11
|
def self.parse(args)
|
12
|
-
|
13
|
-
cli_options.parse
|
14
|
-
cli_options
|
12
|
+
new(args).parse
|
15
13
|
end
|
16
14
|
|
17
15
|
def initialize(args)
|
@@ -19,12 +17,8 @@ module Rspec
|
|
19
17
|
@options = {}
|
20
18
|
end
|
21
19
|
|
22
|
-
def files_to_run
|
23
|
-
options[:files_to_run]
|
24
|
-
end
|
25
|
-
|
26
20
|
def parse
|
27
|
-
|
21
|
+
options[:files_or_directories_to_run] = OptionParser.new do |opts|
|
28
22
|
opts.banner = "Usage: rspec [options] [files or directories]"
|
29
23
|
|
30
24
|
opts.on('-c', '--[no-]color', '--[no-]colour', 'Enable color in the output') do |o|
|
@@ -44,10 +38,9 @@ module Rspec
|
|
44
38
|
end
|
45
39
|
end.parse!(@args)
|
46
40
|
|
47
|
-
|
48
|
-
options
|
41
|
+
self
|
49
42
|
end
|
50
|
-
|
43
|
+
|
51
44
|
def apply(config)
|
52
45
|
options.each do |key, value|
|
53
46
|
config.send("#{key}=", value)
|
@@ -3,9 +3,9 @@ module Rspec
|
|
3
3
|
class Configuration
|
4
4
|
# Regex patterns to scrub backtrace with
|
5
5
|
attr_reader :backtrace_clean_patterns
|
6
|
-
|
7
|
-
# All of the defined
|
8
|
-
attr_reader :
|
6
|
+
|
7
|
+
# All of the defined advice in the configuration (before/after/around)
|
8
|
+
attr_reader :advice
|
9
9
|
|
10
10
|
# Allows you to control what examples are ran by filtering
|
11
11
|
attr_reader :filter
|
@@ -19,14 +19,14 @@ module Rspec
|
|
19
19
|
# when using focused examples for instance. Defaults to true
|
20
20
|
attr_accessor :run_all_when_everything_filtered
|
21
21
|
|
22
|
-
# Enable verbose interal logging of the framework - defaults to false
|
23
|
-
attr_accessor :trace
|
24
|
-
|
25
22
|
attr_reader :options
|
26
23
|
|
27
24
|
def initialize
|
28
25
|
@run_all_when_everything_filtered = true
|
29
|
-
@
|
26
|
+
@advice = {
|
27
|
+
:before => { :each => [], :all => [], :suite => [] },
|
28
|
+
:after => { :each => [], :all => [], :suite => [] }
|
29
|
+
}
|
30
30
|
@include_or_extend_modules = []
|
31
31
|
@filter, @exclusion_filter = nil, nil
|
32
32
|
@options = default_options
|
@@ -46,9 +46,7 @@ module Rspec
|
|
46
46
|
/vendor\/rails/,
|
47
47
|
/bin\/rspec/,
|
48
48
|
/bin\/spec/,
|
49
|
-
/lib\/rspec\/core
|
50
|
-
/lib\/rspec\/expectations/,
|
51
|
-
/lib\/rspec\/mocks/]
|
49
|
+
/lib\/rspec\/(core|expectations|matchers|mocks)/]
|
52
50
|
}
|
53
51
|
end
|
54
52
|
|
@@ -106,7 +104,7 @@ module Rspec
|
|
106
104
|
options[:profile_examples]
|
107
105
|
end
|
108
106
|
|
109
|
-
def profile_examples=(
|
107
|
+
def profile_examples=(on_or_off)
|
110
108
|
options[:profile_examples] = on_or_off
|
111
109
|
end
|
112
110
|
|
@@ -116,7 +114,7 @@ module Rspec
|
|
116
114
|
|
117
115
|
def formatter=(formatter_to_use)
|
118
116
|
formatter_class = case formatter_to_use.to_s
|
119
|
-
when /doc/, 's'
|
117
|
+
when /doc/, 's', 'n'
|
120
118
|
Rspec::Core::Formatters::DocumentationFormatter
|
121
119
|
when 'progress'
|
122
120
|
Rspec::Core::Formatters::ProgressFormatter
|
@@ -134,23 +132,17 @@ module Rspec
|
|
134
132
|
options[:files_to_run]
|
135
133
|
end
|
136
134
|
|
137
|
-
def
|
138
|
-
files.flatten
|
139
|
-
|
140
|
-
result = []
|
141
|
-
files.each do |file|
|
135
|
+
def files_or_directories_to_run=(*files)
|
136
|
+
options[:files_to_run] = files.flatten.inject([]) do |result, file|
|
142
137
|
if File.directory?(file)
|
143
138
|
filename_pattern.split(",").each do |pattern|
|
144
139
|
result += Dir[File.expand_path("#{file}/#{pattern.strip}")]
|
145
140
|
end
|
146
|
-
elsif File.file?(file)
|
147
|
-
result << file
|
148
141
|
else
|
149
|
-
|
142
|
+
result << file
|
150
143
|
end
|
144
|
+
result
|
151
145
|
end
|
152
|
-
|
153
|
-
options[:files_to_run] = result
|
154
146
|
end
|
155
147
|
|
156
148
|
# E.g. alias_example_to :crazy_slow, :speed => 'crazy_slow' defines
|
@@ -194,25 +186,21 @@ module Rspec
|
|
194
186
|
|
195
187
|
def find_modules(group)
|
196
188
|
include_or_extend_modules.select do |include_or_extend, mod, options|
|
197
|
-
|
198
|
-
Rspec::Core.world.apply_condition(filter_on, filter, group.metadata)
|
199
|
-
end
|
189
|
+
Rspec::Core.world.all_apply?(group, options)
|
200
190
|
end
|
201
191
|
end
|
202
192
|
|
203
193
|
def before(each_or_all=:each, options={}, &block)
|
204
|
-
|
194
|
+
advice[:before][each_or_all] << [options, block]
|
205
195
|
end
|
206
196
|
|
207
197
|
def after(each_or_all=:each, options={}, &block)
|
208
|
-
|
198
|
+
advice[:after][each_or_all] << [options, block]
|
209
199
|
end
|
210
200
|
|
211
|
-
def
|
212
|
-
|
213
|
-
|
214
|
-
Rspec::Core.world.apply_condition(filter_on, filter, group.metadata)
|
215
|
-
end
|
201
|
+
def find_advice(desired_advice_type, desired_each_or_all, group)
|
202
|
+
advice[desired_advice_type][desired_each_or_all].select do |options, block|
|
203
|
+
Rspec::Core.world.all_apply?(group, options)
|
216
204
|
end.map { |options, block| block }
|
217
205
|
end
|
218
206
|
|
data/lib/rspec/core/example.rb
CHANGED
@@ -2,12 +2,12 @@ module Rspec
|
|
2
2
|
module Core
|
3
3
|
class Example
|
4
4
|
|
5
|
-
attr_reader :behaviour, :
|
5
|
+
attr_reader :behaviour, :metadata, :example_block
|
6
6
|
|
7
7
|
def initialize(behaviour, desc, options, example_block=nil)
|
8
|
-
@behaviour, @
|
8
|
+
@behaviour, @options, @example_block = behaviour, options, example_block
|
9
9
|
@metadata = @behaviour.metadata.dup
|
10
|
-
@metadata[:description] =
|
10
|
+
@metadata[:description] = desc.to_s
|
11
11
|
@metadata[:execution_result] = {}
|
12
12
|
@metadata[:caller] = options.delete(:caller)
|
13
13
|
if @metadata[:caller]
|
@@ -16,6 +16,10 @@ module Rspec
|
|
16
16
|
end
|
17
17
|
@metadata.update(options)
|
18
18
|
end
|
19
|
+
|
20
|
+
def description
|
21
|
+
@metadata[:description]
|
22
|
+
end
|
19
23
|
|
20
24
|
def record_results(results={})
|
21
25
|
@metadata[:execution_result].update(results)
|
@@ -53,20 +57,43 @@ module Rspec
|
|
53
57
|
end
|
54
58
|
|
55
59
|
def run_before_each
|
56
|
-
@
|
57
|
-
@behaviour.eval_before_eachs(@
|
60
|
+
@example_group_instance._setup_mocks if @example_group_instance.respond_to?(:_setup_mocks)
|
61
|
+
@behaviour.eval_before_eachs(@example_group_instance)
|
58
62
|
end
|
59
63
|
|
60
64
|
def run_after_each
|
61
|
-
@behaviour.eval_after_eachs(@
|
62
|
-
@
|
65
|
+
@behaviour.eval_after_eachs(@example_group_instance)
|
66
|
+
@example_group_instance._verify_mocks if @example_group_instance.respond_to?(:_verify_mocks)
|
63
67
|
ensure
|
64
|
-
@
|
68
|
+
@example_group_instance._teardown_mocks if @example_group_instance.respond_to?(:_teardown_mocks)
|
65
69
|
end
|
66
70
|
|
67
|
-
def
|
68
|
-
|
69
|
-
|
71
|
+
def assign_auto_description
|
72
|
+
if description.empty?
|
73
|
+
metadata[:description] = Rspec::Matchers.generated_description
|
74
|
+
Rspec::Matchers.clear_generated_description
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
class AroundProxy
|
79
|
+
def initialize(example_group_instance, &example_block)
|
80
|
+
@example_group_instance, @example_block = example_group_instance, example_block
|
81
|
+
end
|
82
|
+
|
83
|
+
def run
|
84
|
+
@example_group_instance.instance_eval(&@example_block)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def runnable?
|
89
|
+
![example_block.nil?,
|
90
|
+
metadata[:disabled] == true,
|
91
|
+
metadata[:pending] == true ].any?
|
92
|
+
end
|
93
|
+
|
94
|
+
def run(example_group_instance)
|
95
|
+
@example_group_instance = example_group_instance
|
96
|
+
@example_group_instance.running_example = self
|
70
97
|
|
71
98
|
run_started
|
72
99
|
|
@@ -75,25 +102,31 @@ module Rspec
|
|
75
102
|
|
76
103
|
begin
|
77
104
|
run_before_each
|
78
|
-
@
|
105
|
+
if @behaviour.around_eachs.empty?
|
106
|
+
@example_group_instance.instance_eval(&example_block) if runnable?
|
107
|
+
else
|
108
|
+
@behaviour.around_eachs.first.call(AroundProxy.new(self, &example_block))
|
109
|
+
end
|
79
110
|
rescue Exception => e
|
80
111
|
exception_encountered = e
|
81
112
|
all_systems_nominal = false
|
82
113
|
end
|
83
114
|
|
115
|
+
assign_auto_description
|
116
|
+
|
84
117
|
begin
|
85
118
|
run_after_each
|
86
119
|
rescue Exception => e
|
87
120
|
exception_encountered ||= e
|
88
121
|
all_systems_nominal = false
|
89
122
|
ensure
|
90
|
-
@
|
123
|
+
@example_group_instance.running_example = nil
|
91
124
|
end
|
92
125
|
|
93
126
|
if exception_encountered
|
94
127
|
run_failed(exception_encountered)
|
95
128
|
else
|
96
|
-
|
129
|
+
runnable? ? run_passed : run_pending
|
97
130
|
end
|
98
131
|
|
99
132
|
all_systems_nominal
|
@@ -110,4 +143,4 @@ module Rspec
|
|
110
143
|
end
|
111
144
|
|
112
145
|
end
|
113
|
-
end
|
146
|
+
end
|
@@ -1,63 +1,35 @@
|
|
1
|
+
require 'rspec/core/advice'
|
2
|
+
require 'rspec/core/example_group_subject'
|
3
|
+
require 'rspec/core/metadata'
|
4
|
+
|
1
5
|
module Rspec
|
2
6
|
module Core
|
3
7
|
class ExampleGroup
|
8
|
+
extend Advice
|
4
9
|
include ExampleGroupSubject
|
5
|
-
|
10
|
+
|
6
11
|
attr_accessor :running_example, :reporter
|
7
|
-
|
12
|
+
|
8
13
|
def self.inherited(klass)
|
9
14
|
super
|
10
15
|
Rspec::Core.configuration.autorun!
|
11
16
|
Rspec::Core.world.behaviours << klass
|
12
17
|
end
|
13
|
-
|
18
|
+
|
14
19
|
def self.extended_modules #:nodoc:
|
15
20
|
ancestors = class << self; ancestors end
|
16
21
|
ancestors.select { |mod| mod.class == Module } - [ Object, Kernel ]
|
17
22
|
end
|
18
23
|
|
19
|
-
def self.befores
|
20
|
-
@_befores ||= { :all => [], :each => [] }
|
21
|
-
end
|
22
|
-
|
23
|
-
def self.before_eachs
|
24
|
-
befores[:each]
|
25
|
-
end
|
26
|
-
|
27
|
-
def self.before_alls
|
28
|
-
befores[:all]
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.before(type=:each, &block)
|
32
|
-
befores[type] << block
|
33
|
-
end
|
34
|
-
|
35
|
-
def self.afters
|
36
|
-
@_afters ||= { :all => [], :each => [] }
|
37
|
-
end
|
38
|
-
|
39
|
-
def self.after_eachs
|
40
|
-
afters[:each]
|
41
|
-
end
|
42
|
-
|
43
|
-
def self.after_alls
|
44
|
-
afters[:all]
|
45
|
-
end
|
46
|
-
|
47
|
-
def self.after(type=:each, &block)
|
48
|
-
afters[type] << block
|
49
|
-
end
|
50
|
-
|
51
24
|
def self.example(desc=nil, options={}, &block)
|
52
25
|
examples << Rspec::Core::Example.new(self, desc, options.update(:caller => caller[0]), block)
|
53
26
|
end
|
54
|
-
|
27
|
+
|
55
28
|
def self.alias_example_to(new_alias, extra_options={})
|
56
29
|
new_alias = <<-END_RUBY
|
57
30
|
def self.#{new_alias}(desc=nil, options={}, &block)
|
58
31
|
updated_options = options.update(:caller => caller[0])
|
59
32
|
updated_options.update(#{extra_options.inspect})
|
60
|
-
block = nil if updated_options[:pending] == true || updated_options[:disabled] == true
|
61
33
|
examples << Rspec::Core::Example.new(self, desc, updated_options, block)
|
62
34
|
end
|
63
35
|
END_RUBY
|
@@ -75,44 +47,21 @@ module Rspec
|
|
75
47
|
module_eval(&block) if names.include?(name)
|
76
48
|
end
|
77
49
|
end
|
78
|
-
|
50
|
+
|
79
51
|
def self.examples
|
80
52
|
@_examples ||= []
|
81
53
|
end
|
82
|
-
|
54
|
+
|
83
55
|
def self.examples_to_run
|
84
56
|
@_examples_to_run ||= []
|
85
57
|
end
|
86
58
|
|
87
|
-
def self.generate_name(options, metadata)
|
88
|
-
if superclass.metadata[:behaviour][:name]
|
89
|
-
metadata[:behaviour][:name] = "#{self.superclass.metadata[:behaviour][:name]} #{description} "
|
90
|
-
else
|
91
|
-
metadata[:behaviour][:name] = "#{describes} #{description} "
|
92
|
-
end
|
93
|
-
metadata[:behaviour][:name].strip!
|
94
|
-
end
|
95
|
-
|
96
59
|
def self.set_it_up(*args)
|
97
|
-
@metadata =
|
98
|
-
|
99
|
-
|
100
|
-
@metadata.update(self.superclass.metadata)
|
101
|
-
@metadata[:behaviour] = {}
|
102
|
-
@metadata[:behaviour][:describes] = args.shift unless args.first.is_a?(String)
|
103
|
-
@metadata[:behaviour][:describes] ||= self.superclass.metadata && self.superclass.metadata[:behaviour][:describes]
|
104
|
-
@metadata[:behaviour][:description] = args.shift || ''
|
105
|
-
@metadata[:behaviour][:name] = generate_name(args, metadata)
|
106
|
-
@metadata[:behaviour][:block] = extra_metadata.delete(:behaviour_block)
|
107
|
-
@metadata[:behaviour][:caller] = extra_metadata.delete(:caller) || caller(1)
|
108
|
-
@metadata[:behaviour][:file_path] = extra_metadata.delete(:file_path) || @metadata[:behaviour][:caller][4].split(":")[0].strip
|
109
|
-
@metadata[:behaviour][:line_number] = extra_metadata.delete(:line_number) || @metadata[:behaviour][:caller][4].split(":")[1].to_i
|
110
|
-
|
111
|
-
@metadata.update(extra_metadata)
|
112
|
-
|
113
|
-
Rspec::Core.configuration.find_modules(self).each do |include_or_extend, mod, opts|
|
60
|
+
@metadata = Rspec::Core::Metadata.process(self.superclass.metadata, *args)
|
61
|
+
|
62
|
+
Rspec::Core.configuration.find_modules(self).each do |include_or_extend, mod, opts|
|
114
63
|
if include_or_extend == :extend
|
115
|
-
send(:extend, mod) unless extended_modules.include?(mod)
|
64
|
+
send(:extend, mod) unless extended_modules.include?(mod)
|
116
65
|
else
|
117
66
|
send(:include, mod) unless included_modules.include?(mod)
|
118
67
|
end
|
@@ -120,7 +69,7 @@ module Rspec
|
|
120
69
|
end
|
121
70
|
|
122
71
|
def self.metadata
|
123
|
-
@metadata
|
72
|
+
@metadata
|
124
73
|
end
|
125
74
|
|
126
75
|
def self.name(friendly=true)
|
@@ -130,7 +79,7 @@ module Rspec
|
|
130
79
|
def self.describes
|
131
80
|
metadata[:behaviour][:describes]
|
132
81
|
end
|
133
|
-
|
82
|
+
|
134
83
|
def self.described_class
|
135
84
|
describes || description
|
136
85
|
end
|
@@ -138,25 +87,29 @@ module Rspec
|
|
138
87
|
def self.description
|
139
88
|
metadata[:behaviour][:description]
|
140
89
|
end
|
141
|
-
|
90
|
+
|
142
91
|
def self.file_path
|
143
92
|
metadata[:behaviour][:file_path]
|
144
93
|
end
|
145
|
-
|
94
|
+
|
146
95
|
def self.describe(*args, &behaviour_block)
|
147
96
|
raise(ArgumentError, "No arguments given. You must a least supply a type or description") if args.empty?
|
148
97
|
raise(ArgumentError, "You must supply a block when calling describe") if behaviour_block.nil?
|
149
|
-
|
98
|
+
|
150
99
|
# TODO: Pull out the below into a metadata object, that we can defer the subclassing if necessary
|
151
100
|
# describe 'foo', :shared => true will need this to be completed first
|
152
101
|
subclass('NestedLevel') do
|
153
102
|
args << {} unless args.last.is_a?(Hash)
|
154
|
-
args.last.update(:behaviour_block => behaviour_block)
|
103
|
+
args.last.update(:behaviour_block => behaviour_block, :caller => caller(2))
|
155
104
|
set_it_up(*args)
|
156
105
|
module_eval(&behaviour_block)
|
157
106
|
end
|
158
107
|
end
|
159
108
|
|
109
|
+
class << self
|
110
|
+
alias_method :context, :describe
|
111
|
+
end
|
112
|
+
|
160
113
|
def self.ancestors(superclass_last=false)
|
161
114
|
classes = []
|
162
115
|
current_class = self
|
@@ -165,14 +118,14 @@ module Rspec
|
|
165
118
|
superclass_last ? classes << current_class : classes.unshift(current_class)
|
166
119
|
current_class = current_class.superclass
|
167
120
|
end
|
168
|
-
|
121
|
+
|
169
122
|
classes
|
170
123
|
end
|
171
|
-
|
124
|
+
|
172
125
|
def self.before_ancestors
|
173
126
|
@_before_ancestors ||= ancestors
|
174
127
|
end
|
175
|
-
|
128
|
+
|
176
129
|
def self.after_ancestors
|
177
130
|
@_after_ancestors ||= ancestors(true)
|
178
131
|
end
|
@@ -183,48 +136,54 @@ module Rspec
|
|
183
136
|
|
184
137
|
def self.eval_before_alls(running_behaviour)
|
185
138
|
superclass.before_all_ivars.each { |ivar, val| running_behaviour.instance_variable_set(ivar, val) }
|
186
|
-
Rspec::Core.configuration.
|
187
|
-
|
139
|
+
Rspec::Core.configuration.find_advice(:before, :all, self).each { |blk| running_behaviour.instance_eval(&blk) }
|
140
|
+
|
188
141
|
before_alls.each { |blk| running_behaviour.instance_eval(&blk) }
|
189
142
|
running_behaviour.instance_variables.each { |ivar| before_all_ivars[ivar] = running_behaviour.instance_variable_get(ivar) }
|
190
143
|
end
|
191
|
-
|
144
|
+
|
192
145
|
def self.eval_before_eachs(running_behaviour)
|
193
|
-
Rspec::Core.configuration.
|
146
|
+
Rspec::Core.configuration.find_advice(:before, :each, self).each { |blk| running_behaviour.instance_eval(&blk) }
|
194
147
|
before_ancestors.each { |ancestor| ancestor.before_eachs.each { |blk| running_behaviour.instance_eval(&blk) } }
|
195
148
|
end
|
196
149
|
|
197
150
|
def self.eval_after_alls(running_behaviour)
|
198
151
|
after_alls.each { |blk| running_behaviour.instance_eval(&blk) }
|
199
|
-
Rspec::Core.configuration.
|
152
|
+
Rspec::Core.configuration.find_advice(:after, :all, self).each { |blk| running_behaviour.instance_eval(&blk) }
|
200
153
|
before_all_ivars.keys.each { |ivar| before_all_ivars[ivar] = running_behaviour.instance_variable_get(ivar) }
|
201
154
|
end
|
202
155
|
|
203
156
|
def self.eval_after_eachs(running_behaviour)
|
204
157
|
after_ancestors.each { |ancestor| ancestor.after_eachs.each { |blk| running_behaviour.instance_eval(&blk) } }
|
205
|
-
Rspec::Core.configuration.
|
158
|
+
Rspec::Core.configuration.find_advice(:after, :each, self).each { |blk| running_behaviour.instance_eval(&blk) }
|
206
159
|
end
|
207
160
|
|
208
161
|
def self.run(reporter)
|
209
|
-
|
162
|
+
example_world = new
|
210
163
|
reporter.add_behaviour(self)
|
211
|
-
eval_before_alls(
|
212
|
-
success = run_examples(
|
213
|
-
eval_after_alls(
|
214
|
-
|
164
|
+
eval_before_alls(example_world)
|
165
|
+
success = run_examples(example_world, reporter)
|
166
|
+
eval_after_alls(example_world)
|
167
|
+
|
215
168
|
success
|
216
169
|
end
|
217
|
-
|
170
|
+
|
218
171
|
# Runs all examples, returning true only if all of them pass
|
219
|
-
def self.run_examples(
|
220
|
-
examples_to_run.map
|
172
|
+
def self.run_examples(example_world, reporter)
|
173
|
+
examples_to_run.map do |ex|
|
174
|
+
result = ex.run(example_world)
|
175
|
+
example_world.__reset__
|
176
|
+
before_all_ivars.each { |k, v| example_world.instance_variable_set(k, v) }
|
177
|
+
result
|
178
|
+
end.all?
|
221
179
|
end
|
222
180
|
|
181
|
+
|
223
182
|
def self.subclass(base_name, &body) # :nodoc:
|
224
|
-
@
|
225
|
-
@
|
183
|
+
@_subclass_count ||= 0
|
184
|
+
@_subclass_count += 1
|
226
185
|
klass = Class.new(self)
|
227
|
-
class_name = "#{base_name}_#{@
|
186
|
+
class_name = "#{base_name}_#{@_subclass_count}"
|
228
187
|
const_set(class_name, klass)
|
229
188
|
klass.instance_eval(&body)
|
230
189
|
klass
|
@@ -233,7 +192,23 @@ module Rspec
|
|
233
192
|
def self.to_s
|
234
193
|
self == Rspec::Core::ExampleGroup ? 'Rspec::Core::ExampleGroup' : name
|
235
194
|
end
|
236
|
-
|
195
|
+
|
196
|
+
def self.let(name, &block)
|
197
|
+
# Should we block defining method names already defined?
|
198
|
+
define_method(name) do
|
199
|
+
assignments[name] ||= instance_eval(&block)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def assignments
|
204
|
+
@assignments ||= {}
|
205
|
+
end
|
206
|
+
|
207
|
+
def __reset__
|
208
|
+
instance_variables.each { |ivar| remove_instance_variable(ivar) }
|
209
|
+
assignments.clear
|
210
|
+
end
|
211
|
+
|
237
212
|
end
|
238
213
|
end
|
239
214
|
end
|