rspec-core 2.12.2 → 2.13.0
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/Changelog.md +31 -0
- data/README.md +11 -10
- data/features/command_line/example_name_option.feature +6 -10
- data/features/command_line/tag.feature +15 -8
- data/features/configuration/backtrace_clean_patterns.feature +102 -0
- data/features/configuration/failure_exit_code.feature +36 -0
- data/features/configuration/order_and_seed.feature +3 -0
- data/features/configuration/output_stream.feature +24 -0
- data/features/configuration/pattern.feature +30 -0
- data/features/configuration/profile.feature +163 -0
- data/features/configuration/run_all_when_everything_filtered.feature +60 -0
- data/features/configuration/show_failures_in_pending_blocks.feature +61 -0
- data/features/configuration/treat_symbols_as_metadata_keys_with_true_values.feature +52 -0
- data/features/filtering/exclusion_filters.feature +1 -2
- data/features/formatters/configurable_colors.feature +31 -0
- data/features/step_definitions/additional_cli_steps.rb +21 -0
- data/features/subject/explicit_subject.feature +19 -0
- data/lib/autotest/rspec2.rb +1 -1
- data/lib/rspec/core.rb +1 -2
- data/lib/rspec/core/configuration.rb +33 -3
- data/lib/rspec/core/configuration_options.rb +5 -5
- data/lib/rspec/core/deprecation.rb +1 -1
- data/lib/rspec/core/example.rb +2 -2
- data/lib/rspec/core/example_group.rb +1 -3
- data/lib/rspec/core/formatters/base_text_formatter.rb +93 -27
- data/lib/rspec/core/formatters/documentation_formatter.rb +3 -3
- data/lib/rspec/core/formatters/progress_formatter.rb +3 -3
- data/lib/rspec/core/memoized_helpers.rb +425 -0
- data/lib/rspec/core/metadata.rb +6 -2
- data/lib/rspec/core/option_parser.rb +8 -2
- data/lib/rspec/core/pending.rb +7 -0
- data/lib/rspec/core/shared_context.rb +1 -1
- data/lib/rspec/core/version.rb +1 -1
- data/spec/autotest/failed_results_re_spec.rb +4 -4
- data/spec/autotest/rspec_spec.rb +25 -20
- data/spec/command_line/order_spec.rb +21 -21
- data/spec/rspec/core/command_line_spec.rb +6 -6
- data/spec/rspec/core/configuration_options_spec.rb +86 -72
- data/spec/rspec/core/configuration_spec.rb +161 -156
- data/spec/rspec/core/deprecations_spec.rb +4 -4
- data/spec/rspec/core/drb_command_line_spec.rb +9 -9
- data/spec/rspec/core/drb_options_spec.rb +46 -33
- data/spec/rspec/core/dsl_spec.rb +3 -3
- data/spec/rspec/core/example_group_spec.rb +156 -124
- data/spec/rspec/core/example_spec.rb +68 -52
- data/spec/rspec/core/filter_manager_spec.rb +36 -36
- data/spec/rspec/core/formatters/base_formatter_spec.rb +9 -9
- data/spec/rspec/core/formatters/base_text_formatter_spec.rb +104 -42
- data/spec/rspec/core/formatters/documentation_formatter_spec.rb +4 -4
- data/spec/rspec/core/formatters/helpers_spec.rb +13 -13
- data/spec/rspec/core/formatters/html_formatted-1.8.7-jruby.html +5 -17
- data/spec/rspec/core/formatters/html_formatted-1.8.7-rbx.html +159 -44
- data/spec/rspec/core/formatters/html_formatted-1.8.7.html +14 -14
- data/spec/rspec/core/formatters/html_formatted-1.9.2.html +20 -20
- data/spec/rspec/core/formatters/html_formatted-1.9.3-jruby.html +5 -5
- data/spec/rspec/core/formatters/html_formatted-1.9.3-rbx.html +159 -44
- data/spec/rspec/core/formatters/html_formatted-1.9.3.html +20 -20
- data/spec/rspec/core/formatters/{html_formatted-1.9.2-jruby.html → html_formatted-2.0.0.html} +24 -18
- data/spec/rspec/core/formatters/html_formatter_spec.rb +9 -5
- data/spec/rspec/core/formatters/json_formatter_spec.rb +9 -9
- data/spec/rspec/core/formatters/progress_formatter_spec.rb +4 -4
- data/spec/rspec/core/formatters/snippet_extractor_spec.rb +3 -3
- data/spec/rspec/core/formatters/text_mate_formatted-1.8.7-jruby.html +5 -17
- data/spec/rspec/core/formatters/text_mate_formatted-1.8.7-rbx.html +159 -44
- data/spec/rspec/core/formatters/text_mate_formatted-1.8.7.html +16 -16
- data/spec/rspec/core/formatters/text_mate_formatted-1.9.2.html +23 -23
- data/spec/rspec/core/formatters/text_mate_formatted-1.9.3-jruby.html +5 -17
- data/spec/rspec/core/formatters/text_mate_formatted-1.9.3-rbx.html +159 -44
- data/spec/rspec/core/formatters/text_mate_formatted-1.9.3.html +23 -23
- data/spec/rspec/core/formatters/{text_mate_formatted-1.9.2-jruby.html → text_mate_formatted-2.0.0.html} +25 -19
- data/spec/rspec/core/formatters/text_mate_formatter_spec.rb +8 -4
- data/spec/rspec/core/hooks_filtering_spec.rb +16 -16
- data/spec/rspec/core/hooks_spec.rb +11 -11
- data/spec/rspec/core/kernel_extensions_spec.rb +1 -1
- data/spec/rspec/core/memoized_helpers_spec.rb +458 -0
- data/spec/rspec/core/metadata_spec.rb +74 -74
- data/spec/rspec/core/option_parser_spec.rb +27 -27
- data/spec/rspec/core/pending_example_spec.rb +32 -32
- data/spec/rspec/core/project_initializer_spec.rb +8 -8
- data/spec/rspec/core/rake_task_spec.rb +16 -16
- data/spec/rspec/core/reporter_spec.rb +3 -3
- data/spec/rspec/core/resources/formatter_specs.rb +4 -4
- data/spec/rspec/core/ruby_project_spec.rb +4 -2
- data/spec/rspec/core/shared_context_spec.rb +34 -7
- data/spec/rspec/core/shared_example_group_spec.rb +14 -14
- data/spec/rspec/core/world_spec.rb +9 -9
- data/spec/rspec/core_spec.rb +5 -5
- data/spec/spec_helper.rb +4 -0
- data/spec/support/shared_example_groups.rb +4 -4
- data/spec/support/spec_files.rb +2 -2
- metadata +158 -150
- data/lib/rspec/core/let.rb +0 -110
- data/lib/rspec/core/subject.rb +0 -223
- data/spec/rspec/core/let_spec.rb +0 -55
- data/spec/rspec/core/subject_spec.rb +0 -255
data/lib/rspec/core/let.rb
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
module RSpec
|
|
2
|
-
module Core
|
|
3
|
-
module Let
|
|
4
|
-
|
|
5
|
-
module ExampleGroupMethods
|
|
6
|
-
# Generates a method whose return value is memoized after the first
|
|
7
|
-
# call. Useful for reducing duplication between examples that assign
|
|
8
|
-
# values to the same local variable.
|
|
9
|
-
#
|
|
10
|
-
# @note `let` _can_ enhance readability when used sparingly (1,2, or
|
|
11
|
-
# maybe 3 declarations) in any given example group, but that can
|
|
12
|
-
# quickly degrade with overuse. YMMV.
|
|
13
|
-
#
|
|
14
|
-
# @note `let` uses an `||=` conditional that has the potential to
|
|
15
|
-
# behave in surprising ways in examples that spawn separate threads,
|
|
16
|
-
# though we have yet to see this in practice. You've been warned.
|
|
17
|
-
#
|
|
18
|
-
# @example
|
|
19
|
-
#
|
|
20
|
-
# describe Thing do
|
|
21
|
-
# let(:thing) { Thing.new }
|
|
22
|
-
#
|
|
23
|
-
# it "does something" do
|
|
24
|
-
# # first invocation, executes block, memoizes and returns result
|
|
25
|
-
# thing.do_something
|
|
26
|
-
#
|
|
27
|
-
# # second invocation, returns the memoized value
|
|
28
|
-
# thing.should be_something
|
|
29
|
-
# end
|
|
30
|
-
# end
|
|
31
|
-
def let(name, &block)
|
|
32
|
-
define_method(name) do
|
|
33
|
-
__memoized.fetch(name) {|k| __memoized[k] = instance_eval(&block) }
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# Just like `let`, except the block is invoked by an implicit `before`
|
|
38
|
-
# hook. This serves a dual purpose of setting up state and providing a
|
|
39
|
-
# memoized reference to that state.
|
|
40
|
-
#
|
|
41
|
-
# @example
|
|
42
|
-
#
|
|
43
|
-
# class Thing
|
|
44
|
-
# def self.count
|
|
45
|
-
# @count ||= 0
|
|
46
|
-
# end
|
|
47
|
-
#
|
|
48
|
-
# def self.count=(val)
|
|
49
|
-
# @count += val
|
|
50
|
-
# end
|
|
51
|
-
#
|
|
52
|
-
# def self.reset_count
|
|
53
|
-
# @count = 0
|
|
54
|
-
# end
|
|
55
|
-
#
|
|
56
|
-
# def initialize
|
|
57
|
-
# self.class.count += 1
|
|
58
|
-
# end
|
|
59
|
-
# end
|
|
60
|
-
#
|
|
61
|
-
# describe Thing do
|
|
62
|
-
# after(:each) { Thing.reset_count }
|
|
63
|
-
#
|
|
64
|
-
# context "using let" do
|
|
65
|
-
# let(:thing) { Thing.new }
|
|
66
|
-
#
|
|
67
|
-
# it "is not invoked implicitly" do
|
|
68
|
-
# Thing.count.should eq(0)
|
|
69
|
-
# end
|
|
70
|
-
#
|
|
71
|
-
# it "can be invoked explicitly" do
|
|
72
|
-
# thing
|
|
73
|
-
# Thing.count.should eq(1)
|
|
74
|
-
# end
|
|
75
|
-
# end
|
|
76
|
-
#
|
|
77
|
-
# context "using let!" do
|
|
78
|
-
# let!(:thing) { Thing.new }
|
|
79
|
-
#
|
|
80
|
-
# it "is invoked implicitly" do
|
|
81
|
-
# Thing.count.should eq(1)
|
|
82
|
-
# end
|
|
83
|
-
#
|
|
84
|
-
# it "returns memoized version on first invocation" do
|
|
85
|
-
# thing
|
|
86
|
-
# Thing.count.should eq(1)
|
|
87
|
-
# end
|
|
88
|
-
# end
|
|
89
|
-
# end
|
|
90
|
-
def let!(name, &block)
|
|
91
|
-
let(name, &block)
|
|
92
|
-
before { __send__(name) }
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
# @private
|
|
97
|
-
module ExampleMethods
|
|
98
|
-
# @private
|
|
99
|
-
def __memoized
|
|
100
|
-
@__memoized ||= {}
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
def self.included(mod)
|
|
105
|
-
mod.extend ExampleGroupMethods
|
|
106
|
-
mod.__send__ :include, ExampleMethods
|
|
107
|
-
end
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
end
|
data/lib/rspec/core/subject.rb
DELETED
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
module RSpec
|
|
2
|
-
module Core
|
|
3
|
-
module Subject
|
|
4
|
-
module ExampleMethods
|
|
5
|
-
# Returns the example group's `subject`.
|
|
6
|
-
#
|
|
7
|
-
# @note `subject` was contributed by Joe Ferris to support the one-liner
|
|
8
|
-
# syntax embraced by shoulda matchers:
|
|
9
|
-
#
|
|
10
|
-
# describe Widget do
|
|
11
|
-
# it { should validate_presence_of(:name) }
|
|
12
|
-
# end
|
|
13
|
-
#
|
|
14
|
-
# While the examples below demonstrate how to use `subject`
|
|
15
|
-
# explicitly in examples, we recommend that you define a method with
|
|
16
|
-
# an intention revealing name instead.
|
|
17
|
-
#
|
|
18
|
-
# @example
|
|
19
|
-
#
|
|
20
|
-
# # explicit declaration of subject
|
|
21
|
-
# describe Person do
|
|
22
|
-
# subject { Person.new(:birthdate => 19.years.ago) }
|
|
23
|
-
# it "should be eligible to vote" do
|
|
24
|
-
# subject.should be_eligible_to_vote
|
|
25
|
-
# # ^ ^ explicit reference to subject not recommended
|
|
26
|
-
# end
|
|
27
|
-
# end
|
|
28
|
-
#
|
|
29
|
-
# # implicit subject => { Person.new }
|
|
30
|
-
# describe Person do
|
|
31
|
-
# it "should be eligible to vote" do
|
|
32
|
-
# subject.should be_eligible_to_vote
|
|
33
|
-
# # ^ ^ explicit reference to subject not recommended
|
|
34
|
-
# end
|
|
35
|
-
# end
|
|
36
|
-
#
|
|
37
|
-
# # one-liner syntax - should is invoked on subject
|
|
38
|
-
# describe Person do
|
|
39
|
-
# it { should be_eligible_to_vote }
|
|
40
|
-
# end
|
|
41
|
-
#
|
|
42
|
-
# @see ExampleGroupMethods#subject
|
|
43
|
-
# @see #should
|
|
44
|
-
def subject
|
|
45
|
-
if defined?(@original_subject)
|
|
46
|
-
@original_subject
|
|
47
|
-
else
|
|
48
|
-
@original_subject = instance_eval(&self.class.subject)
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
# When `should` is called with no explicit receiver, the call is
|
|
53
|
-
# delegated to the object returned by `subject`. Combined with an
|
|
54
|
-
# implicit subject this supports very concise expressions.
|
|
55
|
-
#
|
|
56
|
-
# @example
|
|
57
|
-
#
|
|
58
|
-
# describe Person do
|
|
59
|
-
# it { should be_eligible_to_vote }
|
|
60
|
-
# end
|
|
61
|
-
#
|
|
62
|
-
# @see #subject
|
|
63
|
-
def should(matcher=nil, message=nil)
|
|
64
|
-
RSpec::Expectations::PositiveExpectationHandler.handle_matcher(subject, matcher, message)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
# Just like `should`, `should_not` delegates to the subject (implicit or
|
|
68
|
-
# explicit) of the example group.
|
|
69
|
-
#
|
|
70
|
-
# @example
|
|
71
|
-
#
|
|
72
|
-
# describe Person do
|
|
73
|
-
# it { should_not be_eligible_to_vote }
|
|
74
|
-
# end
|
|
75
|
-
#
|
|
76
|
-
# @see #subject
|
|
77
|
-
def should_not(matcher=nil, message=nil)
|
|
78
|
-
RSpec::Expectations::NegativeExpectationHandler.handle_matcher(subject, matcher, message)
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
private
|
|
82
|
-
|
|
83
|
-
def _attribute_chain(attribute)
|
|
84
|
-
attribute.to_s.split('.')
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def _nested_attribute(subject, attribute)
|
|
88
|
-
_attribute_chain(attribute).inject(subject) do |inner_subject, attr|
|
|
89
|
-
inner_subject.send(attr)
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
module ExampleGroupMethods
|
|
95
|
-
# Creates a nested example group named by the submitted `attribute`,
|
|
96
|
-
# and then generates an example using the submitted block.
|
|
97
|
-
#
|
|
98
|
-
# @example
|
|
99
|
-
#
|
|
100
|
-
# # This ...
|
|
101
|
-
# describe Array do
|
|
102
|
-
# its(:size) { should eq(0) }
|
|
103
|
-
# end
|
|
104
|
-
#
|
|
105
|
-
# # ... generates the same runtime structure as this:
|
|
106
|
-
# describe Array do
|
|
107
|
-
# describe "size" do
|
|
108
|
-
# it "should eq(0)" do
|
|
109
|
-
# subject.size.should eq(0)
|
|
110
|
-
# end
|
|
111
|
-
# end
|
|
112
|
-
# end
|
|
113
|
-
#
|
|
114
|
-
# The attribute can be a `Symbol` or a `String`. Given a `String`
|
|
115
|
-
# with dots, the result is as though you concatenated that `String`
|
|
116
|
-
# onto the subject in an expression.
|
|
117
|
-
#
|
|
118
|
-
# @example
|
|
119
|
-
#
|
|
120
|
-
# describe Person do
|
|
121
|
-
# subject do
|
|
122
|
-
# Person.new.tap do |person|
|
|
123
|
-
# person.phone_numbers << "555-1212"
|
|
124
|
-
# end
|
|
125
|
-
# end
|
|
126
|
-
#
|
|
127
|
-
# its("phone_numbers.first") { should eq("555-1212") }
|
|
128
|
-
# end
|
|
129
|
-
#
|
|
130
|
-
# When the subject is a `Hash`, you can refer to the Hash keys by
|
|
131
|
-
# specifying a `Symbol` or `String` in an array.
|
|
132
|
-
#
|
|
133
|
-
# @example
|
|
134
|
-
#
|
|
135
|
-
# describe "a configuration Hash" do
|
|
136
|
-
# subject do
|
|
137
|
-
# { :max_users => 3,
|
|
138
|
-
# 'admin' => :all_permissions }
|
|
139
|
-
# end
|
|
140
|
-
#
|
|
141
|
-
# its([:max_users]) { should eq(3) }
|
|
142
|
-
# its(['admin']) { should eq(:all_permissions) }
|
|
143
|
-
#
|
|
144
|
-
# # You can still access to its regular methods this way:
|
|
145
|
-
# its(:keys) { should include(:max_users) }
|
|
146
|
-
# its(:count) { should eq(2) }
|
|
147
|
-
# end
|
|
148
|
-
def its(attribute, &block)
|
|
149
|
-
describe(attribute) do
|
|
150
|
-
example do
|
|
151
|
-
self.class.class_eval do
|
|
152
|
-
define_method(:subject) do
|
|
153
|
-
if defined?(@_subject)
|
|
154
|
-
@_subject
|
|
155
|
-
else
|
|
156
|
-
@_subject = Array === attribute ? super()[*attribute] : _nested_attribute(super(), attribute)
|
|
157
|
-
end
|
|
158
|
-
end
|
|
159
|
-
end
|
|
160
|
-
instance_eval(&block)
|
|
161
|
-
end
|
|
162
|
-
end
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
# Declares a `subject` for an example group which can then be the
|
|
166
|
-
# implicit receiver (through delegation) of calls to `should`.
|
|
167
|
-
#
|
|
168
|
-
# Given a `name`, defines a method with that name which returns the
|
|
169
|
-
# `subject`. This lets you declare the subject once and access it
|
|
170
|
-
# implicitly in one-liners and explicitly using an intention revealing
|
|
171
|
-
# name.
|
|
172
|
-
#
|
|
173
|
-
# @param [String,Symbol] name used to define an accessor with an
|
|
174
|
-
# intention revealing name
|
|
175
|
-
# @param block defines the value to be returned by `subject` in examples
|
|
176
|
-
#
|
|
177
|
-
# @example
|
|
178
|
-
#
|
|
179
|
-
# describe CheckingAccount, "with $50" do
|
|
180
|
-
# subject { CheckingAccount.new(Money.new(50, :USD)) }
|
|
181
|
-
# it { should have_a_balance_of(Money.new(50, :USD)) }
|
|
182
|
-
# it { should_not be_overdrawn }
|
|
183
|
-
# end
|
|
184
|
-
#
|
|
185
|
-
# describe CheckingAccount, "with a non-zero starting balance" do
|
|
186
|
-
# subject(:account) { CheckingAccount.new(Money.new(50, :USD)) }
|
|
187
|
-
# it { should_not be_overdrawn }
|
|
188
|
-
# it "has a balance equal to the starting balance" do
|
|
189
|
-
# account.balance.should eq(Money.new(50, :USD))
|
|
190
|
-
# end
|
|
191
|
-
# end
|
|
192
|
-
#
|
|
193
|
-
# @see ExampleMethods#subject
|
|
194
|
-
# @see ExampleMethods#should
|
|
195
|
-
def subject(name=nil, &block)
|
|
196
|
-
if name
|
|
197
|
-
let(name, &block)
|
|
198
|
-
subject { send name }
|
|
199
|
-
else
|
|
200
|
-
block ? @explicit_subject_block = block : explicit_subject || implicit_subject
|
|
201
|
-
end
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
attr_reader :explicit_subject_block
|
|
205
|
-
|
|
206
|
-
private
|
|
207
|
-
|
|
208
|
-
def explicit_subject
|
|
209
|
-
group = self
|
|
210
|
-
while group.respond_to?(:explicit_subject_block)
|
|
211
|
-
return group.explicit_subject_block if group.explicit_subject_block
|
|
212
|
-
group = group.superclass
|
|
213
|
-
end
|
|
214
|
-
end
|
|
215
|
-
|
|
216
|
-
def implicit_subject
|
|
217
|
-
described = described_class || description
|
|
218
|
-
Class === described ? proc { described.new } : proc { described }
|
|
219
|
-
end
|
|
220
|
-
end
|
|
221
|
-
end
|
|
222
|
-
end
|
|
223
|
-
end
|
data/spec/rspec/core/let_spec.rb
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe "#let" do
|
|
4
|
-
let(:counter) do
|
|
5
|
-
Class.new do
|
|
6
|
-
def initialize
|
|
7
|
-
@count = 0
|
|
8
|
-
end
|
|
9
|
-
def count
|
|
10
|
-
@count += 1
|
|
11
|
-
end
|
|
12
|
-
end.new
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
let(:nil_value) do
|
|
16
|
-
@nil_value_count += 1
|
|
17
|
-
nil
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
it "generates an instance method" do
|
|
21
|
-
counter.count.should eq(1)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
it "caches the value" do
|
|
25
|
-
counter.count.should eq(1)
|
|
26
|
-
counter.count.should eq(2)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
it "caches a nil value" do
|
|
30
|
-
@nil_value_count = 0
|
|
31
|
-
nil_value
|
|
32
|
-
nil_value
|
|
33
|
-
|
|
34
|
-
@nil_value_count.should eq(1)
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
describe "#let!" do
|
|
39
|
-
let!(:creator) do
|
|
40
|
-
Class.new do
|
|
41
|
-
@count = 0
|
|
42
|
-
def self.count
|
|
43
|
-
@count += 1
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
it "evaluates the value non-lazily" do
|
|
49
|
-
lambda { creator.count }.should_not raise_error
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
it "does not interfere between tests" do
|
|
53
|
-
creator.count.should eq(1)
|
|
54
|
-
end
|
|
55
|
-
end
|
|
@@ -1,255 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
module RSpec::Core
|
|
4
|
-
|
|
5
|
-
describe Subject do
|
|
6
|
-
before(:each) { RSpec.configuration.configure_expectation_framework }
|
|
7
|
-
|
|
8
|
-
describe "implicit subject" do
|
|
9
|
-
describe "with a class" do
|
|
10
|
-
it "returns an instance of the class" do
|
|
11
|
-
ExampleGroup.describe(Array).subject.call.should eq([])
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
describe "with a Module" do
|
|
16
|
-
it "returns the Module" do
|
|
17
|
-
ExampleGroup.describe(Enumerable).subject.call.should eq(Enumerable)
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
describe "with a string" do
|
|
22
|
-
it "return the string" do
|
|
23
|
-
ExampleGroup.describe("Foo").subject.call.should eq("Foo")
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
describe "with a number" do
|
|
28
|
-
it "returns the number" do
|
|
29
|
-
ExampleGroup.describe(15).subject.call.should eq(15)
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
describe "explicit subject" do
|
|
36
|
-
[false, nil].each do |falsy_value|
|
|
37
|
-
context "with a value of #{falsy_value.inspect}" do
|
|
38
|
-
it "is evaluated once per example" do
|
|
39
|
-
group = ExampleGroup.describe(Array)
|
|
40
|
-
group.before do
|
|
41
|
-
Object.should_receive(:this_question?).once.and_return(falsy_value)
|
|
42
|
-
end
|
|
43
|
-
group.subject do
|
|
44
|
-
Object.this_question?
|
|
45
|
-
end
|
|
46
|
-
group.example do
|
|
47
|
-
subject
|
|
48
|
-
subject
|
|
49
|
-
end
|
|
50
|
-
group.run.should be_true, "expected subject block to be evaluated only once"
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
describe "defined in a top level group" do
|
|
56
|
-
it "replaces the implicit subject in that group" do
|
|
57
|
-
group = ExampleGroup.describe(Array)
|
|
58
|
-
group.subject { [1,2,3] }
|
|
59
|
-
group.subject.call.should eq([1,2,3])
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
describe "defined in a top level group" do
|
|
64
|
-
let(:group) do
|
|
65
|
-
ExampleGroup.describe do
|
|
66
|
-
subject{ [4,5,6] }
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
it "is available in a nested group (subclass)" do
|
|
71
|
-
nested_group = group.describe("I'm nested!") { }
|
|
72
|
-
nested_group.subject.call.should eq([4,5,6])
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
it "is available in a doubly nested group (subclass)" do
|
|
76
|
-
nested_group = group.describe("Nesting level 1") { }
|
|
77
|
-
doubly_nested_group = nested_group.describe("Nesting level 2") { }
|
|
78
|
-
doubly_nested_group.subject.call.should eq([4,5,6])
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
describe "with a name" do
|
|
83
|
-
it "defines a method that returns the memoized subject" do
|
|
84
|
-
group = ExampleGroup.describe do
|
|
85
|
-
subject(:list) { [1,2,3] }
|
|
86
|
-
example do
|
|
87
|
-
list.should equal(list)
|
|
88
|
-
subject.should equal(subject)
|
|
89
|
-
subject.should equal(list)
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
group.run.should be_true
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
it "is referred from inside subject by the name" do
|
|
96
|
-
group = ExampleGroup.describe do
|
|
97
|
-
subject(:list) { [1,2,3] }
|
|
98
|
-
describe 'first' do
|
|
99
|
-
subject(:first_element) { list.first }
|
|
100
|
-
it { should eq(1) }
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
group.run.should be_true
|
|
104
|
-
end
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
context "using 'self' as an explicit subject" do
|
|
109
|
-
it "delegates matcher to the ExampleGroup" do
|
|
110
|
-
group = ExampleGroup.describe("group") do
|
|
111
|
-
subject { self }
|
|
112
|
-
def ok?; true; end
|
|
113
|
-
def not_ok?; false; end
|
|
114
|
-
|
|
115
|
-
it { should eq(self) }
|
|
116
|
-
it { should be_ok }
|
|
117
|
-
it { should_not be_not_ok }
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
group.run.should be_true
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
describe "#its" do
|
|
125
|
-
subject do
|
|
126
|
-
Class.new do
|
|
127
|
-
def initialize
|
|
128
|
-
@call_count = 0
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
def call_count
|
|
132
|
-
@call_count += 1
|
|
133
|
-
end
|
|
134
|
-
end.new
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
context "with a call counter" do
|
|
138
|
-
its(:call_count) { should eq(1) }
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
context "with nil value" do
|
|
142
|
-
subject do
|
|
143
|
-
Class.new do
|
|
144
|
-
def nil_value
|
|
145
|
-
nil
|
|
146
|
-
end
|
|
147
|
-
end.new
|
|
148
|
-
end
|
|
149
|
-
its(:nil_value) { should be_nil }
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
context "with nested attributes" do
|
|
153
|
-
subject do
|
|
154
|
-
Class.new do
|
|
155
|
-
def name
|
|
156
|
-
"John"
|
|
157
|
-
end
|
|
158
|
-
end.new
|
|
159
|
-
end
|
|
160
|
-
its("name") { should eq("John") }
|
|
161
|
-
its("name.size") { should eq(4) }
|
|
162
|
-
its("name.size.class") { should eq(Fixnum) }
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
context "when it responds to #[]" do
|
|
166
|
-
subject do
|
|
167
|
-
Class.new do
|
|
168
|
-
def [](*objects)
|
|
169
|
-
objects.map do |object|
|
|
170
|
-
"#{object.class}: #{object.to_s}"
|
|
171
|
-
end.join("; ")
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
def name
|
|
175
|
-
"George"
|
|
176
|
-
end
|
|
177
|
-
end.new
|
|
178
|
-
end
|
|
179
|
-
its([:a]) { should eq("Symbol: a") }
|
|
180
|
-
its(['a']) { should eq("String: a") }
|
|
181
|
-
its([:b, 'c', 4]) { should eq("Symbol: b; String: c; Fixnum: 4") }
|
|
182
|
-
its(:name) { should eq("George") }
|
|
183
|
-
context "when referring to an attribute without the proper array syntax" do
|
|
184
|
-
context "it raises an error" do
|
|
185
|
-
its(:age) do
|
|
186
|
-
expect do
|
|
187
|
-
should eq(64)
|
|
188
|
-
end.to raise_error(NoMethodError)
|
|
189
|
-
end
|
|
190
|
-
end
|
|
191
|
-
end
|
|
192
|
-
end
|
|
193
|
-
|
|
194
|
-
context "when it does not respond to #[]" do
|
|
195
|
-
subject { Object.new }
|
|
196
|
-
|
|
197
|
-
context "it raises an error" do
|
|
198
|
-
its([:a]) do
|
|
199
|
-
expect do
|
|
200
|
-
should eq("Symbol: a")
|
|
201
|
-
end.to raise_error(NoMethodError)
|
|
202
|
-
end
|
|
203
|
-
end
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
context "calling and overriding super" do
|
|
207
|
-
it "calls to the subject defined in the parent group" do
|
|
208
|
-
group = ExampleGroup.describe(Array) do
|
|
209
|
-
subject { [1, 'a'] }
|
|
210
|
-
|
|
211
|
-
its(:last) { should eq("a") }
|
|
212
|
-
|
|
213
|
-
describe '.first' do
|
|
214
|
-
def subject; super().first; end
|
|
215
|
-
|
|
216
|
-
its(:next) { should eq(2) }
|
|
217
|
-
end
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
group.run.should be_true
|
|
221
|
-
end
|
|
222
|
-
end
|
|
223
|
-
|
|
224
|
-
context "with nil subject" do
|
|
225
|
-
subject do
|
|
226
|
-
Class.new do
|
|
227
|
-
def initialize
|
|
228
|
-
@counter = -1
|
|
229
|
-
end
|
|
230
|
-
def nil_if_first_time
|
|
231
|
-
@counter += 1
|
|
232
|
-
@counter == 0 ? nil : true
|
|
233
|
-
end
|
|
234
|
-
end.new
|
|
235
|
-
end
|
|
236
|
-
its(:nil_if_first_time) { should be(nil) }
|
|
237
|
-
end
|
|
238
|
-
|
|
239
|
-
context "with false subject" do
|
|
240
|
-
subject do
|
|
241
|
-
Class.new do
|
|
242
|
-
def initialize
|
|
243
|
-
@counter = -1
|
|
244
|
-
end
|
|
245
|
-
def false_if_first_time
|
|
246
|
-
@counter += 1
|
|
247
|
-
@counter > 0
|
|
248
|
-
end
|
|
249
|
-
end.new
|
|
250
|
-
end
|
|
251
|
-
its(:false_if_first_time) { should be(false) }
|
|
252
|
-
end
|
|
253
|
-
end
|
|
254
|
-
end
|
|
255
|
-
end
|