1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
RSpec.describe Unparser::Adamantium::Memory do
describe '#fetch' do
let(:events) { [] }
let(:monitor) { instance_double(Monitor) }
let(:name) { :some_name }
let(:object) { described_class.new(proxy) }
let(:value_was_read) { -> {} }
let(:block) do
lambda do
events << :block_call
@counter += 1
end
end
let(:proxy) do
proxy = instance_double(Hash)
values = values()
allow(proxy).to receive(:fetch) do |name, &block|
events << :fetch
values.fetch(name) do
value_was_read.call
block.call
end
end
allow(proxy).to receive(:[]=) do |name, value|
events << :set
values[name] = value
end
proxy
end
def apply
object.fetch(name, &block)
end
before do
allow(Monitor).to receive_messages(new: monitor)
allow(monitor).to receive(:synchronize) do |&block|
events << :synchronize_start
block.call.tap do
events << :synchronize_end
end
end
@counter = 0
end
shared_examples 'expected events' do
it 'triggers expected events' do
expect { apply }
.to change(events, :to_a)
.from([]).to(expected_events)
end
it 'returns expected value' do
expect(apply).to be(1)
end
it 'creates frozen objects' do
expect(object.frozen?).to be(true)
end
end
context 'when value is present in memory' do
let(:values) { { name => 1 } }
let(:expected_events) { %i[fetch] }
include_examples 'expected events'
end
context 'when value is not present in memory initially' do
let(:values) { {} }
let(:expected_events) do
%i[
fetch
synchronize_start
fetch
block_call
set
synchronize_end
]
end
include_examples 'expected events'
context 'but is present inside the lock' do
let(:value_was_read) { ->() { values[name] = 1 } }
let(:expected_events) do
%i[
fetch
synchronize_start
fetch
synchronize_end
]
end
include_examples 'expected events'
end
context 'and is re-read after initial generation' do
def apply
super()
super()
end
let(:expected_events) do
%i[
fetch
synchronize_start
fetch
block_call
set
synchronize_end
fetch
]
end
include_examples 'expected events'
end
end
end
end
|