rspec-core 2.0.0.beta.18 → 2.0.0.beta.19

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/Gemfile CHANGED
@@ -15,8 +15,9 @@ gem "syntax"
15
15
  gem "rspec-core", :path => "."
16
16
  gem "rspec-expectations", :path => "../rspec-expectations"
17
17
  gem "rspec-mocks", :path => "../rspec-mocks"
18
- if RUBY_VERSION.to_s =~ /1.9/
18
+ case RUBY_VERSION
19
+ when /^1.9.1/
19
20
  gem "ruby-debug19"
20
- else
21
+ when /^1.8/
21
22
  gem "ruby-debug"
22
23
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.0.beta.18
1
+ 2.0.0.beta.19
@@ -0,0 +1,44 @@
1
+ Feature: attribute of subject
2
+
3
+ Scenario: simple attribute
4
+ Given a file named "example_spec.rb" with:
5
+ """
6
+ describe Array do
7
+ its(:size) { should == 0 }
8
+ end
9
+ """
10
+ When I run "rspec example_spec.rb --format documentation"
11
+ Then the output should contain:
12
+ """
13
+ Array
14
+ size
15
+ should == 0
16
+ """
17
+
18
+ Scenario: nested attribute
19
+ Given a file named "example_spec.rb" with:
20
+ """
21
+ class Person
22
+ attr_reader :phone_numbers
23
+ def initialize
24
+ @phone_numbers = []
25
+ end
26
+ end
27
+
28
+ describe Person do
29
+ subject do
30
+ person = Person.new
31
+ person.phone_numbers << "555-1212"
32
+ person
33
+ end
34
+
35
+ its("phone_numbers.first") { should == "555-1212" }
36
+ end
37
+ """
38
+ When I run "rspec example_spec.rb --format documentation"
39
+ Then the output should contain:
40
+ """
41
+ Person
42
+ phone_numbers.first
43
+ should == "555-1212"
44
+ """
@@ -3,7 +3,7 @@ Feature: implicit subject
3
3
  The first argument to the outermost example group block is
4
4
  made available to each example as an implicit subject of
5
5
  that example.
6
-
6
+
7
7
  Scenario: subject in top level group
8
8
  Given a file named "top_level_subject_spec.rb" with:
9
9
  """
@@ -54,7 +54,6 @@ module RSpec
54
54
  end
55
55
 
56
56
  alias_example_to :it
57
- alias_example_to :its, :attribute_of_subject => true
58
57
  alias_example_to :specify
59
58
  alias_example_to :focused, :focused => true
60
59
  alias_example_to :pending, :pending => true
@@ -156,23 +155,22 @@ module RSpec
156
155
  @before_all_ivars ||= {}
157
156
  end
158
157
 
159
- def self.eval_before_alls(example)
160
- return if descendant_filtered_examples.empty?
161
- superclass.before_all_ivars.each { |ivar, val| example.instance_variable_set(ivar, val) }
162
- world.run_hook_filtered(:before, :all, self, example) if top_level?
163
-
164
- run_hook!(:before, :all, example)
165
- example.instance_variables.each { |ivar| before_all_ivars[ivar] = example.instance_variable_get(ivar) }
158
+ def self.store_before_all_ivars(example_group_instance)
159
+ example_group_instance.instance_variables.each { |ivar|
160
+ before_all_ivars[ivar] = example_group_instance.instance_variable_get(ivar)
161
+ }
166
162
  end
167
163
 
168
- def self.eval_before_eachs(example)
169
- world.run_hook_filtered(:before, :each, self, example)
170
- ancestors.reverse.each { |ancestor| ancestor.run_hook(:before, :each, example) }
164
+ def self.assign_before_all_ivars(ivars, example_group_instance)
165
+ ivars.each { |ivar, val| example_group_instance.instance_variable_set(ivar, val) }
171
166
  end
172
167
 
173
- def self.eval_after_eachs(example)
174
- ancestors.each { |ancestor| ancestor.run_hook(:after, :each, example) }
175
- world.run_hook_filtered(:after, :each, self, example)
168
+ def self.eval_before_alls(example_group_instance)
169
+ return if descendant_filtered_examples.empty?
170
+ assign_before_all_ivars(superclass.before_all_ivars, example_group_instance)
171
+ world.run_hook_filtered(:before, :all, self, example_group_instance) if top_level?
172
+ run_hook!(:before, :all, example_group_instance)
173
+ store_before_all_ivars(example_group_instance)
176
174
  end
177
175
 
178
176
  def self.eval_around_eachs(example_group_instance, wrapped_example)
@@ -182,15 +180,25 @@ module RSpec
182
180
  end
183
181
  end
184
182
 
185
- def self.around_hooks
186
- (world.find_hook(:around, :each, self) + ancestors.reverse.map{|a| a.find_hook(:around, :each, self)}).flatten
183
+ def self.eval_before_eachs(example_group_instance)
184
+ world.run_hook_filtered(:before, :each, self, example_group_instance)
185
+ ancestors.reverse.each { |ancestor| ancestor.run_hook(:before, :each, example_group_instance) }
186
+ end
187
+
188
+ def self.eval_after_eachs(example_group_instance)
189
+ ancestors.each { |ancestor| ancestor.run_hook(:after, :each, example_group_instance) }
190
+ world.run_hook_filtered(:after, :each, self, example_group_instance)
187
191
  end
188
192
 
189
- def self.eval_after_alls(example)
193
+ def self.eval_after_alls(example_group_instance)
190
194
  return if descendant_filtered_examples.empty?
191
- before_all_ivars.each { |ivar, val| example.instance_variable_set(ivar, val) }
192
- run_hook!(:after, :all, example)
193
- world.run_hook_filtered(:after, :all, self, example) if top_level?
195
+ assign_before_all_ivars(before_all_ivars, example_group_instance)
196
+ run_hook!(:after, :all, example_group_instance)
197
+ world.run_hook_filtered(:after, :all, self, example_group_instance) if top_level?
198
+ end
199
+
200
+ def self.around_hooks
201
+ (world.find_hook(:around, :each, self) + ancestors.reverse.map{|a| a.find_hook(:around, :each, self)}).flatten
194
202
  end
195
203
 
196
204
  def self.run(reporter)
@@ -253,6 +261,14 @@ module RSpec
253
261
  self.class.describes
254
262
  end
255
263
 
264
+ def instance_eval_with_rescue(&hook)
265
+ begin
266
+ instance_eval(&hook)
267
+ rescue Exception => e
268
+ example.set_exception(e)
269
+ end
270
+ end
271
+
256
272
  private
257
273
 
258
274
  def self.extended_modules #:nodoc:
@@ -138,11 +138,11 @@ module RSpec
138
138
 
139
139
  def read_failed_line(exception, example)
140
140
  original_file = example.file_path.to_s.downcase
141
- matching_line = exception.backtrace.detect { |line| line.split(':').first.downcase == original_file.downcase }
141
+ matching_line = exception.backtrace.detect { |line| line.match(/(.+?):(\d+)(|:\d+)/)[1].downcase == original_file.downcase }
142
142
 
143
143
  return "Unable to find matching line from backtrace" if matching_line.nil?
144
144
 
145
- file_path, line_number = matching_line.split(':')
145
+ file_path, line_number = matching_line.match(/(.+?):(\d+)(|:\d+)/)[1..2]
146
146
  if File.exist?(file_path)
147
147
  open(file_path, 'r') { |f| f.readlines[line_number.to_i - 1] }
148
148
  else
@@ -24,21 +24,19 @@ module RSpec
24
24
  end
25
25
 
26
26
  class BeforeHook < Hook
27
- def run_in(example)
28
- example ? example.instance_eval(&self) : call
27
+ def run_in(example_group_instance)
28
+ if example_group_instance
29
+ example_group_instance.instance_eval(&self)
30
+ else
31
+ call
32
+ end
29
33
  end
30
34
  end
31
35
 
32
36
  class AfterHook < Hook
33
- def run_in(example)
34
- if example
35
- begin
36
- example.instance_eval(&self)
37
- rescue Exception => e
38
- if example.respond_to?(:example)
39
- example.example.set_exception(e)
40
- end
41
- end
37
+ def run_in(example_group_instance)
38
+ if example_group_instance
39
+ example_group_instance.instance_eval_with_rescue(&self)
42
40
  else
43
41
  call
44
42
  end
@@ -58,22 +56,22 @@ module RSpec
58
56
  end
59
57
 
60
58
  class BeforeHooks < HookCollection
61
- def run_all(example)
62
- each {|h| h.run_in(example) }
59
+ def run_all(example_group_instance)
60
+ each {|h| h.run_in(example_group_instance) }
63
61
  end
64
62
 
65
- def run_all!(example)
66
- shift.run_in(example) until empty?
63
+ def run_all!(example_group_instance)
64
+ shift.run_in(example_group_instance) until empty?
67
65
  end
68
66
  end
69
67
 
70
68
  class AfterHooks < HookCollection
71
- def run_all(example)
72
- reverse.each {|h| h.run_in(example) }
69
+ def run_all(example_group_instance)
70
+ reverse.each {|h| h.run_in(example_group_instance) }
73
71
  end
74
72
 
75
- def run_all!(example)
76
- pop.run_in(example) until empty?
73
+ def run_all!(example_group_instance)
74
+ pop.run_in(example_group_instance) until empty?
77
75
  end
78
76
  end
79
77
 
@@ -101,22 +99,22 @@ module RSpec
101
99
 
102
100
  # Runs all of the blocks stored with the hook in the context of the
103
101
  # example. If no example is provided, just calls the hook directly.
104
- def run_hook(hook, scope, example=nil)
105
- hooks[hook][scope].run_all(example)
102
+ def run_hook(hook, scope, example_group_instance=nil)
103
+ hooks[hook][scope].run_all(example_group_instance)
106
104
  end
107
105
 
108
106
  # Just like run_hook, except it removes the blocks as it evalutes them,
109
107
  # ensuring that they will only be run once.
110
- def run_hook!(hook, scope, example)
111
- hooks[hook][scope].run_all!(example)
108
+ def run_hook!(hook, scope, example_group_instance)
109
+ hooks[hook][scope].run_all!(example_group_instance)
112
110
  end
113
111
 
114
- def run_hook_filtered(hook, scope, group, example)
115
- find_hook(hook, scope, group).run_all(example)
112
+ def run_hook_filtered(hook, scope, group, example_group_instance)
113
+ find_hook(hook, scope, group).run_all(example_group_instance)
116
114
  end
117
115
 
118
- def find_hook(hook, scope, group)
119
- hooks[hook][scope].find_hooks_for(group)
116
+ def find_hook(hook, scope, example_group_class)
117
+ hooks[hook][scope].find_hooks_for(example_group_class)
120
118
  end
121
119
  end
122
120
  end
@@ -164,7 +164,7 @@ EOM
164
164
 
165
165
  def file_and_line_number(metadata)
166
166
  entry = candidate_entries_from_caller(metadata).first
167
- entry && entry.split(":")
167
+ entry && entry.match(/(.+?):(\d+)(|:\d+)/)[1..2]
168
168
  end
169
169
 
170
170
  def candidate_entries_from_caller(metadata)
@@ -10,8 +10,32 @@ module RSpec
10
10
  end
11
11
  end
12
12
 
13
+ # Returns the subject defined by the example group. The subject block is
14
+ # only executed once per example, the result of which is cached and
15
+ # returned by any subsequent calls to +subject+.
16
+ #
17
+ # If a class is passed to +describe+ and no subject is explicitly
18
+ # declared in the example group, then +subject+ will return a new
19
+ # instance of that class.
20
+ #
21
+ # == Examples
22
+ #
23
+ # # explicit subject defined by the subject method
24
+ # describe Person do
25
+ # subject { Person.new(:birthdate => 19.years.ago) }
26
+ # it "should be eligible to vote" do
27
+ # subject.should be_eligible_to_vote
28
+ # end
29
+ # end
30
+ #
31
+ # # implicit subject => { Person.new }
32
+ # describe Person do
33
+ # it "should be eligible to vote" do
34
+ # subject.should be_eligible_to_vote
35
+ # end
36
+ # end
13
37
  def subject
14
- using_attribute? ? attribute_of_subject : original_subject
38
+ @original_subject ||= instance_eval(&self.class.subject)
15
39
  end
16
40
 
17
41
  # When +should+ is called with no explicit receiver, the call is
@@ -41,6 +65,50 @@ module RSpec
41
65
  end
42
66
 
43
67
  module ClassMethods
68
+ # Creates a nested example group named by the submitted +attribute+,
69
+ # and then generates an example using the submitted block.
70
+ #
71
+ # # This ...
72
+ # describe Array do
73
+ # its(:size) { should == 0 }
74
+ # end
75
+ #
76
+ # # ... generates the same runtime structure as this:
77
+ # describe Array do
78
+ # describe "size" do
79
+ # it "should == 0" do
80
+ # subject.size.should == 0
81
+ # end
82
+ # end
83
+ # end
84
+ #
85
+ # The attribute can be a +Symbol+ or a +String+. Given a +String+
86
+ # with dots, the result is as though you concatenated that +String+
87
+ # onto the subject in an expression.
88
+ #
89
+ # describe Person
90
+ # let(:person) do
91
+ # person = Person.new
92
+ # person.phone_numbers << "555-1212"
93
+ # end
94
+ #
95
+ # its("phone_numbers.first") { should == "555-1212" }
96
+ # end
97
+ def its(attribute, &block)
98
+ describe(attribute) do
99
+ example do
100
+ self.class.class_eval do
101
+ define_method(:subject) do
102
+ attribute.to_s.split('.').inject(super) do |target, method|
103
+ target.send(method)
104
+ end
105
+ end
106
+ end
107
+ instance_eval(&block)
108
+ end
109
+ end
110
+ end
111
+
44
112
  # Defines an explicit subject for an example group which can then be the
45
113
  # implicit receiver (through delegation) of calls to +should+.
46
114
  #
@@ -75,25 +143,6 @@ module RSpec
75
143
  end
76
144
  end
77
145
 
78
- private
79
-
80
- def original_subject
81
- @original_subject ||= instance_eval(&self.class.subject)
82
- end
83
-
84
- def attribute_of_subject
85
- if using_attribute?
86
- example.description.split('.').inject(original_subject) do |target, method|
87
- target.send(method)
88
- end
89
- end
90
- end
91
-
92
- def using_attribute?
93
- example.in_block? &&
94
- example.metadata[:attribute_of_subject]
95
- end
96
-
97
146
  end
98
147
  end
99
148
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rspec-core}
8
- s.version = "2.0.0.beta.18"
8
+ s.version = "2.0.0.beta.19"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Chad Humphries", "David Chelimsky"]
12
- s.date = %q{2010-07-21}
12
+ s.date = %q{2010-07-25}
13
13
  s.default_executable = %q{rspec}
14
14
  s.description = %q{RSpec runner and example groups}
15
15
  s.email = %q{dchelimsky@gmail.com;chad.humphries@gmail.com}
@@ -53,6 +53,7 @@ Gem::Specification.new do |s|
53
53
  "features/mock_framework_integration/use_rr.feature",
54
54
  "features/mock_framework_integration/use_rspec.feature",
55
55
  "features/pending/pending_examples.feature",
56
+ "features/subject/attribute_of_subject.feature",
56
57
  "features/subject/explicit_subject.feature",
57
58
  "features/subject/implicit_subject.feature",
58
59
  "features/support/env.rb",
@@ -153,7 +154,7 @@ Gem::Specification.new do |s|
153
154
  s.homepage = %q{http://github.com/rspec/rspec-core}
154
155
  s.post_install_message = %q{**************************************************
155
156
 
156
- Thank you for installing rspec-core-2.0.0.beta.18
157
+ Thank you for installing rspec-core-2.0.0.beta.19
157
158
 
158
159
  Please be sure to look at Upgrade.markdown to see what might have changed
159
160
  since the last release.
@@ -164,7 +165,7 @@ Gem::Specification.new do |s|
164
165
  s.require_paths = ["lib"]
165
166
  s.rubyforge_project = %q{rspec}
166
167
  s.rubygems_version = %q{1.3.7}
167
- s.summary = %q{rspec-core-2.0.0.beta.18}
168
+ s.summary = %q{rspec-core-2.0.0.beta.19}
168
169
  s.test_files = [
169
170
  "spec/autotest/failed_results_re_spec.rb",
170
171
  "spec/autotest/rspec_spec.rb",
@@ -212,19 +213,19 @@ Gem::Specification.new do |s|
212
213
  s.specification_version = 3
213
214
 
214
215
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
215
- s.add_development_dependency(%q<rspec-expectations>, [">= 2.0.0.beta.18"])
216
- s.add_development_dependency(%q<rspec-mocks>, [">= 2.0.0.beta.18"])
216
+ s.add_development_dependency(%q<rspec-expectations>, [">= 2.0.0.beta.19"])
217
+ s.add_development_dependency(%q<rspec-mocks>, [">= 2.0.0.beta.19"])
217
218
  s.add_development_dependency(%q<cucumber>, [">= 0.5.3"])
218
219
  s.add_development_dependency(%q<autotest>, [">= 4.2.9"])
219
220
  else
220
- s.add_dependency(%q<rspec-expectations>, [">= 2.0.0.beta.18"])
221
- s.add_dependency(%q<rspec-mocks>, [">= 2.0.0.beta.18"])
221
+ s.add_dependency(%q<rspec-expectations>, [">= 2.0.0.beta.19"])
222
+ s.add_dependency(%q<rspec-mocks>, [">= 2.0.0.beta.19"])
222
223
  s.add_dependency(%q<cucumber>, [">= 0.5.3"])
223
224
  s.add_dependency(%q<autotest>, [">= 4.2.9"])
224
225
  end
225
226
  else
226
- s.add_dependency(%q<rspec-expectations>, [">= 2.0.0.beta.18"])
227
- s.add_dependency(%q<rspec-mocks>, [">= 2.0.0.beta.18"])
227
+ s.add_dependency(%q<rspec-expectations>, [">= 2.0.0.beta.19"])
228
+ s.add_dependency(%q<rspec-mocks>, [">= 2.0.0.beta.19"])
228
229
  s.add_dependency(%q<cucumber>, [">= 0.5.3"])
229
230
  s.add_dependency(%q<autotest>, [">= 4.2.9"])
230
231
  end
@@ -374,12 +374,6 @@ module RSpec::Core
374
374
  group.examples.size.should == 1
375
375
  end
376
376
 
377
- it "allows adding an example using 'its'" do
378
- group = ExampleGroup.describe
379
- group.its(:some_method) { }
380
- group.examples.size.should == 1
381
- end
382
-
383
377
  it "exposes all examples at examples" do
384
378
  group = ExampleGroup.describe
385
379
  group.it("should do something 1") { }
@@ -547,6 +541,24 @@ module RSpec::Core
547
541
  its("name.size") { should == 4 }
548
542
  its("name.size.class") { should == Fixnum }
549
543
  end
544
+
545
+ context "calling and overriding super" do
546
+ it "calls to the subject defined in the parent group" do
547
+ group = ExampleGroup.describe(Array) do
548
+ subject { [1, 'a'] }
549
+
550
+ its(:last) { should == 'a' }
551
+
552
+ describe '.first' do
553
+ def subject; super.first; end
554
+
555
+ its(:next) { should == 2 }
556
+ end
557
+ end
558
+
559
+ group.run_all.should be_true
560
+ end
561
+ end
550
562
  end
551
563
 
552
564
  describe "#top_level_description" do
@@ -131,6 +131,18 @@ module RSpec
131
131
  ])
132
132
  m[:example_group][:file_path].should == __FILE__
133
133
  end
134
+
135
+ it "finds the first spec file in the caller array with drive letter" do
136
+ m = Metadata.new
137
+ m.process(:caller => [
138
+ "foo",
139
+ "C:/path/file_spec.rb:#{__LINE__}",
140
+ "bar_spec.rb:23",
141
+ "baz"
142
+ ])
143
+ m[:example_group][:file_path].should == "C:/path/file_spec.rb"
144
+ end
145
+
134
146
  it "is nil if there are no spec files found", :full_backtrace => true do
135
147
  m = Metadata.new
136
148
  m.process(:caller => [
@@ -153,6 +165,16 @@ module RSpec
153
165
  ])
154
166
  m[:example_group][:line_number].should == __LINE__ - 4
155
167
  end
168
+ it "finds the line number with the first spec file with drive letter" do
169
+ m = Metadata.new
170
+ m.process(:caller => [
171
+ "foo",
172
+ "C:/path/to/file_spec.rb:#{__LINE__}",
173
+ "bar_spec.rb:23",
174
+ "baz"
175
+ ])
176
+ m[:example_group][:line_number].should == __LINE__ - 4
177
+ end
156
178
  it "uses the number after the first : for ruby 1.9" do
157
179
  m = Metadata.new
158
180
  m.process(:caller => [
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-core
3
3
  version: !ruby/object:Gem::Version
4
- hash: 62196423
4
+ hash: 62196421
5
5
  prerelease: true
6
6
  segments:
7
7
  - 2
8
8
  - 0
9
9
  - 0
10
10
  - beta
11
- - 18
12
- version: 2.0.0.beta.18
11
+ - 19
12
+ version: 2.0.0.beta.19
13
13
  platform: ruby
14
14
  authors:
15
15
  - Chad Humphries
@@ -18,7 +18,7 @@ autorequire:
18
18
  bindir: bin
19
19
  cert_chain: []
20
20
 
21
- date: 2010-07-21 00:00:00 -05:00
21
+ date: 2010-07-25 00:00:00 -05:00
22
22
  default_executable: rspec
23
23
  dependencies:
24
24
  - !ruby/object:Gem::Dependency
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- hash: 62196423
33
+ hash: 62196421
34
34
  segments:
35
35
  - 2
36
36
  - 0
37
37
  - 0
38
38
  - beta
39
- - 18
40
- version: 2.0.0.beta.18
39
+ - 19
40
+ version: 2.0.0.beta.19
41
41
  requirement: *id001
42
42
  - !ruby/object:Gem::Dependency
43
43
  type: :development
@@ -48,14 +48,14 @@ dependencies:
48
48
  requirements:
49
49
  - - ">="
50
50
  - !ruby/object:Gem::Version
51
- hash: 62196423
51
+ hash: 62196421
52
52
  segments:
53
53
  - 2
54
54
  - 0
55
55
  - 0
56
56
  - beta
57
- - 18
58
- version: 2.0.0.beta.18
57
+ - 19
58
+ version: 2.0.0.beta.19
59
59
  requirement: *id002
60
60
  - !ruby/object:Gem::Dependency
61
61
  type: :development
@@ -133,6 +133,7 @@ files:
133
133
  - features/mock_framework_integration/use_rr.feature
134
134
  - features/mock_framework_integration/use_rspec.feature
135
135
  - features/pending/pending_examples.feature
136
+ - features/subject/attribute_of_subject.feature
136
137
  - features/subject/explicit_subject.feature
137
138
  - features/subject/implicit_subject.feature
138
139
  - features/support/env.rb
@@ -236,7 +237,7 @@ licenses: []
236
237
  post_install_message: |
237
238
  **************************************************
238
239
 
239
- Thank you for installing rspec-core-2.0.0.beta.18
240
+ Thank you for installing rspec-core-2.0.0.beta.19
240
241
 
241
242
  Please be sure to look at Upgrade.markdown to see what might have changed
242
243
  since the last release.
@@ -273,7 +274,7 @@ rubyforge_project: rspec
273
274
  rubygems_version: 1.3.7
274
275
  signing_key:
275
276
  specification_version: 3
276
- summary: rspec-core-2.0.0.beta.18
277
+ summary: rspec-core-2.0.0.beta.19
277
278
  test_files:
278
279
  - spec/autotest/failed_results_re_spec.rb
279
280
  - spec/autotest/rspec_spec.rb