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

Sign up to get free protection for your applications and to get access to all the features.
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