rspec-core 2.0.0.a1 → 2.0.0.a2

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 (50) hide show
  1. data/README.markdown +34 -3
  2. data/Rakefile +32 -17
  3. data/bin/rspec +5 -7
  4. data/cucumber.yml +3 -2
  5. data/features-pending/example_groups/example_group_with_should_methods.feature +3 -1
  6. data/features/before_and_after_blocks/around.feature +34 -0
  7. data/features/example_groups/describe_aliases.feature +20 -0
  8. data/{features-pending → features}/example_groups/nested_groups.feature +6 -8
  9. data/features/expectations/customized_message.feature +6 -6
  10. data/{features-pending → features}/matchers/define_matcher.feature +9 -9
  11. data/features/mock_framework_integration/use_rspec.feature +1 -1
  12. data/features/mocks/block_local_expectations.feature +68 -0
  13. data/{features-pending → features}/mocks/mix_stubs_and_mocks.feature +5 -1
  14. data/features/support/env.rb +6 -18
  15. data/lib/rspec/core.rb +5 -5
  16. data/lib/rspec/core/advice.rb +49 -0
  17. data/lib/rspec/core/command_line_options.rb +4 -11
  18. data/lib/rspec/core/configuration.rb +20 -32
  19. data/lib/rspec/core/example.rb +48 -15
  20. data/lib/rspec/core/example_group.rb +68 -93
  21. data/lib/rspec/core/extensions/instance_exec.rb +31 -0
  22. data/lib/rspec/core/kernel_extensions.rb +3 -1
  23. data/lib/rspec/core/load_path.rb +4 -0
  24. data/lib/rspec/core/metadata.rb +78 -0
  25. data/lib/rspec/core/rake_task.rb +3 -4
  26. data/lib/rspec/core/ruby_project.rb +30 -0
  27. data/lib/rspec/core/runner.rb +6 -7
  28. data/lib/rspec/core/version.rb +2 -2
  29. data/lib/rspec/core/world.rb +6 -4
  30. data/rspec-core.gemspec +33 -14
  31. data/spec/rspec/core/command_line_options_spec.rb +10 -10
  32. data/spec/rspec/core/configuration_spec.rb +26 -21
  33. data/spec/rspec/core/example_group_spec.rb +243 -173
  34. data/spec/rspec/core/example_group_subject_spec.rb +1 -1
  35. data/spec/rspec/core/example_spec.rb +12 -22
  36. data/spec/rspec/core/formatters/base_formatter_spec.rb +1 -1
  37. data/spec/rspec/core/formatters/documentation_formatter_spec.rb +1 -1
  38. data/spec/rspec/core/formatters/progress_formatter_spec.rb +4 -3
  39. data/spec/rspec/core/kernel_extensions_spec.rb +1 -1
  40. data/spec/rspec/core/metadata_spec.rb +101 -0
  41. data/spec/rspec/core/mocha_spec.rb +2 -2
  42. data/spec/rspec/core/runner_spec.rb +5 -5
  43. data/spec/rspec/core/shared_behaviour_spec.rb +5 -5
  44. data/spec/rspec/core/world_spec.rb +8 -8
  45. data/spec/rspec/core_spec.rb +1 -1
  46. data/spec/spec_helper.rb +15 -8
  47. data/specs.watchr +57 -0
  48. metadata +53 -15
  49. data/VERSION +0 -1
  50. data/VERSION.yml +0 -5
@@ -1,12 +1,11 @@
1
- $:.unshift File.join(File.dirname(__FILE__), "/../../lib")
2
- $:.unshift File.join(File.dirname(__FILE__), "/../../../expectations/lib")
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(File.join(File.dirname(__FILE__), "/../../tmp/cucumber-generated-files"))
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(File.join(File.dirname(__FILE__), "/../../bin/rspec"))
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
- result = "-I #{RSPEC_LIB}"
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
@@ -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
- cli_options = new(args)
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
- possible_files = OptionParser.new do |opts|
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
- options[:files_to_run] = possible_files
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 before/after blocks setup in the configuration
8
- attr_reader :before_and_afters
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
- @before_and_afters = { :before => { :each => [], :all => [], :suite => [] }, :after => { :each => [], :all => [], :suite => [] } }
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=(profile)
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 files_to_run=(*files)
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
- raise "File or directory not found: #{file}"
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
- options.all? do |filter_on, filter|
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
- before_and_afters[:before][each_or_all] << [options, block]
194
+ advice[:before][each_or_all] << [options, block]
205
195
  end
206
196
 
207
197
  def after(each_or_all=:each, options={}, &block)
208
- before_and_afters[:after][each_or_all] << [options, block]
198
+ advice[:after][each_or_all] << [options, block]
209
199
  end
210
200
 
211
- def find_before_or_after(desired_before_or_after, desired_each_or_all, group)
212
- before_and_afters[desired_before_or_after][desired_each_or_all].select do |options, block|
213
- options.all? do |filter_on, filter|
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
 
@@ -2,12 +2,12 @@ module Rspec
2
2
  module Core
3
3
  class Example
4
4
 
5
- attr_reader :behaviour, :description, :metadata, :example_block
5
+ attr_reader :behaviour, :metadata, :example_block
6
6
 
7
7
  def initialize(behaviour, desc, options, example_block=nil)
8
- @behaviour, @description, @options, @example_block = behaviour, desc, options, example_block
8
+ @behaviour, @options, @example_block = behaviour, options, example_block
9
9
  @metadata = @behaviour.metadata.dup
10
- @metadata[:description] = 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
- @behaviour_instance._setup_mocks if @behaviour_instance.respond_to?(:_setup_mocks)
57
- @behaviour.eval_before_eachs(@behaviour_instance)
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(@behaviour_instance)
62
- @behaviour_instance._verify_mocks if @behaviour_instance.respond_to?(:_verify_mocks)
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
- @behaviour_instance._teardown_mocks if @behaviour_instance.respond_to?(:_teardown_mocks)
68
+ @example_group_instance._teardown_mocks if @example_group_instance.respond_to?(:_teardown_mocks)
65
69
  end
66
70
 
67
- def run(behaviour_instance)
68
- @behaviour_instance = behaviour_instance
69
- @behaviour_instance.running_example = self
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
- @behaviour_instance.instance_eval(&example_block) if example_block
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
- @behaviour_instance.running_example = nil
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
- example_block ? run_passed : run_pending
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
- extra_metadata = args.last.is_a?(Hash) ? args.pop : {}
99
- extra_metadata.delete(:behaviour) # Remove it when present to prevent it clobbering the one we setup
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 ||= { :behaviour => {} }
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.find_before_or_after(:before, :all, self).each { |blk| running_behaviour.instance_eval(&blk) }
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.find_before_or_after(:before, :each, self).each { |blk| running_behaviour.instance_eval(&blk) }
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.find_before_or_after(:after, :all, self).each { |blk| running_behaviour.instance_eval(&blk) }
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.find_before_or_after(:after, :each, self).each { |blk| running_behaviour.instance_eval(&blk) }
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
- behaviour_instance = new
162
+ example_world = new
210
163
  reporter.add_behaviour(self)
211
- eval_before_alls(behaviour_instance)
212
- success = run_examples(behaviour_instance, reporter)
213
- eval_after_alls(behaviour_instance)
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(behaviour_instance, reporter)
220
- examples_to_run.map { |ex| ex.run(behaviour_instance) }.all?
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
- @_sub_class_count ||= 0
225
- @_sub_class_count += 1
183
+ @_subclass_count ||= 0
184
+ @_subclass_count += 1
226
185
  klass = Class.new(self)
227
- class_name = "#{base_name}_#{@_sub_class_count}"
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