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.
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