Skip to content
This repository was archived by the owner on Nov 30, 2024. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions features/subject/attribute_of_subject.feature
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ Feature: attribute of subject

its("phone_numbers.size") { should eq(2) }

You can pass additional arguments that will be passed along to the send call
and thus the underlying attribute (method). This will only occur for the top
level if using nested attributes.

its(:at, 1) { should eq('b') }
its("slice.first", 1, 1) { should eq('b') }

When the subject is a hash, you can pass in an array with a single key to
access the value at that key in the hash.

Expand Down Expand Up @@ -100,3 +107,22 @@ Feature: attribute of subject
"""
When I run "rspec example_spec.rb"
Then the examples should all pass

Scenario: specify additional arguments of an attribute
Given a file named "example_spec.rb" with:
"""
describe Array do
context "when populated" do
subject { ['a', 'b', 'c'] }
its(:at, 1) { should eq('b') }
end
end
"""
When I run "rspec example_spec.rb --format documentation"
Then the output should contain:
"""
Array
when populated
at 1
should == b
"""
12 changes: 9 additions & 3 deletions lib/rspec/core/subject.rb
Original file line number Diff line number Diff line change
Expand Up @@ -119,16 +119,22 @@ module ClassMethods
# its(:keys) { should include(:max_users) }
# its(:count) { should == 2 }
# end
def its(attribute, &block)
describe(attribute) do
def its(attribute, *args, &block)
describe(attribute, *args) do
example do
self.class.class_eval do
define_method(:subject) do
@_subject ||= if super().is_a?(Hash) && attribute.is_a?(Array)
OpenStruct.new(super()).send(attribute.first)
else
attribute.to_s.split('.').inject(super()) do |target, method|
target.send(method)
if args
temp = args
args = nil
target.send(method, *temp)
else
target.send(method)
end
end
end
end
Expand Down
11 changes: 11 additions & 0 deletions spec/rspec/core/subject_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ def initialize
def call_count
@call_count += 1
end

def idiot_bird(*args)
return *args
end
end.new
end

Expand Down Expand Up @@ -173,6 +177,13 @@ def subject; super().first; end
end
end

context "passing arguments" do
its(:idiot_bird) { should eql(nil) }
its(:idiot_bird, 1) { should eql(1) }
its(:idiot_bird, nil) { should eql(nil) }
its(:idiot_bird, 1, 2) { should eql([1,2]) }
its(:'idiot_bird.first', [1, 2]) { should eql(1) }
end
end
end
end