Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Supports Rails 4.1 inversible associations #896

Merged
merged 3 commits into from Dec 28, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion Gemfile
Expand Up @@ -47,7 +47,7 @@ eval File.read(custom_gemfile) if File.exist?(custom_gemfile)
version_file = File.expand_path("../.rails-version", __FILE__)
case version = ENV['RAILS_VERSION'] || (File.exist?(version_file) && File.read(version_file).chomp)
when /master/
gem "rails", :git => "git://github.com/rails/rails.git"
gem "rails", :git => "git://github.com/alindeman/rails.git", :branch => "issue_13390"
gem "arel", :git => "git://github.com/rails/arel.git"
gem "journey", :git => "git://github.com/rails/journey.git"
gem "activerecord-deprecated_finders", :git => "git://github.com/rails/activerecord-deprecated_finders.git"
Expand Down
20 changes: 20 additions & 0 deletions lib/rspec/rails/mocks.rb
Expand Up @@ -29,6 +29,19 @@ def respond_to?(message, include_private=false)
end
end

# Starting with Rails 4.1, ActiveRecord associations are inversible
# by default. This class represents an association from the mocked
# model's perspective.
#
# @private
class Association
attr_accessor :target, :inversed

def initialize(association_name)
@association_name = association_name
end
end

module ActiveRecordInstanceMethods
# Stubs `persisted?` to return `false` and `id` to return `nil`.
def destroy
Expand All @@ -45,6 +58,13 @@ def [](key)
def new_record?
!persisted?
end

# Returns an object representing an association from the mocked
# model's perspective. For use by Rails internally only.
def association(association_name)
@associations ||= Hash.new { |h, k| h[k] = Association.new(k) }
@associations[association_name]
end
end

# Creates a test double representing `string_or_model_class` with common
Expand Down
23 changes: 23 additions & 0 deletions spec/rspec/rails/mocks/mock_model_spec.rb
Expand Up @@ -54,6 +54,29 @@
end
end

describe "association" do
it "constructs a mock association object" do
model = mock_model(MockableModel)
expect(model.association(:association_name)).to be
end

it "returns a different association object for each association name" do
model = mock_model(MockableModel)
posts = model.association(:posts)
authors = model.association(:authors)

expect(posts).not_to equal(authors)
end

it "returns the same association model each time for the same association name" do
model = mock_model(MockableModel)
posts1 = model.association(:posts)
posts2 = model.association(:posts)

expect(posts1).to equal(posts2)
end
end

describe "errors" do
context "default" do
it "is empty" do
Expand Down