Skip to content
This repository was archived by the owner on Nov 30, 2024. It is now read-only.

Commit 444a160

Browse files
committed
Stash methods that get and set thread local variables to allow the user to mock them
Fixes #605.
1 parent 42b18c4 commit 444a160

File tree

2 files changed

+21
-7
lines changed

2 files changed

+21
-7
lines changed

lib/rspec/support.rb

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,18 @@ def self.class_of(object)
9090
singleton_class.ancestors.find { |ancestor| !ancestor.equal?(singleton_class) }
9191
end
9292

93-
# A single thread local variable so we don't excessively pollute that namespace.
93+
# Stash original methods to allow the user to mock them.
9494
if RUBY_VERSION.to_f >= 2
95-
def self.thread_local_data
96-
Thread.current.thread_variable_get(:__rspec) || Thread.current.thread_variable_set(:__rspec, {})
97-
end
95+
THREAD_VARIABLE_GET = Thread.instance_method(:thread_variable_get)
96+
THREAD_VARIABLE_SET = Thread.instance_method(:thread_variable_set)
9897
else
99-
def self.thread_local_data
100-
Thread.current[:__rspec] ||= {}
101-
end
98+
THREAD_VARIABLE_GET = Thread.instance_method(:[])
99+
THREAD_VARIABLE_SET = Thread.instance_method(:[]=)
100+
end
101+
102+
# A single thread local variable so we don't excessively pollute that namespace.
103+
def self.thread_local_data
104+
THREAD_VARIABLE_GET.bind(Thread.current).call(:__rspec) || THREAD_VARIABLE_SET.bind(Thread.current).call(:__rspec, {})
102105
end
103106

104107
# @api private

spec/rspec/support_spec.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,17 @@ def object.some_method
204204
end.resume
205205
end
206206
end
207+
208+
it "works when Thread#thread_variable_get and Thread#thread_variable_set are mocked" do
209+
expect(Thread.current).to receive(:thread_variable_set).with(:test, true).once.and_return(true)
210+
expect(Thread.current).to receive(:thread_variable_get).with(:test).once.and_return(true)
211+
212+
Thread.current.thread_variable_set(:test, true)
213+
expect(Thread.current.thread_variable_get(:test)).to eq true
214+
215+
RSpec::Support.thread_local_data[:__for_test] = :oh_hai
216+
expect(RSpec::Support.thread_local_data[:__for_test]).to eq :oh_hai
217+
end
207218
end
208219

209220
describe "failure notification" do

0 commit comments

Comments
 (0)