Skip to content

Commit d483277

Browse files
committed
Improve Dual Adapter
1 parent e7ab0e7 commit d483277

File tree

2 files changed

+105
-81
lines changed

2 files changed

+105
-81
lines changed
Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
# frozen_string_literal: true
22

3-
require 'forwardable'
4-
53
module Split
64
module Persistence
75
class DualAdapter
8-
extend Forwardable
9-
def_delegators :@adapter, :keys, :[], :[]=, :delete
6+
def self.with_config(options={})
7+
self.config.merge!(options)
8+
self
9+
end
10+
11+
def self.config
12+
@config ||= {}
13+
end
1014

1115
def initialize(context)
1216
if logged_in = self.class.config[:logged_in]
@@ -22,22 +26,28 @@ def initialize(context)
2226
raise "Please configure :logged_out_adapter"
2327
end
2428

25-
if logged_in.call(context)
26-
@adapter = logged_in_adapter.new(context)
27-
else
28-
@adapter = logged_out_adapter.new(context)
29-
end
29+
@logged_in = logged_in.call(context)
30+
@logged_in_adapter = logged_in_adapter.new(context)
31+
@logged_out_adapter = logged_out_adapter.new(context)
3032
end
3133

32-
def self.with_config(options={})
33-
self.config.merge!(options)
34-
self
34+
def keys
35+
@logged_in_adapter.keys + @logged_out_adapter.keys
3536
end
3637

37-
def self.config
38-
@config ||= {}
38+
def [](key)
39+
@logged_in && @logged_in_adapter[key] || @logged_out_adapter[key]
40+
end
41+
42+
def []=(key, value)
43+
@logged_in_adapter[key] = value if @logged_in
44+
@logged_out_adapter[key] = value
3945
end
4046

47+
def delete(key)
48+
@logged_in_adapter.delete(key)
49+
@logged_out_adapter.delete(key)
50+
end
4151
end
4252
end
4353
end
Lines changed: 81 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,102 +1,116 @@
11
# frozen_string_literal: true
2-
require "spec_helper"
2+
3+
require 'spec_helper'
34

45
describe Split::Persistence::DualAdapter do
6+
let(:context) { 'some context' }
57

6-
let(:context){ "some context" }
7-
8-
let(:just_adapter){ Class.new }
9-
let(:selected_adapter_instance){ double }
10-
let(:selected_adapter){
11-
c = Class.new
12-
expect(c).to receive(:new){ selected_adapter_instance }
13-
c
14-
}
15-
let(:not_selected_adapter){
16-
c = Class.new
17-
expect(c).not_to receive(:new)
18-
c
19-
}
20-
21-
shared_examples_for "forwarding calls" do
22-
it "#[]=" do
23-
expect(selected_adapter_instance).to receive(:[]=).with('my_key', 'my_value')
24-
expect_any_instance_of(not_selected_adapter).not_to receive(:[]=)
25-
subject["my_key"] = "my_value"
26-
end
8+
let(:logged_in_adapter_instance) { double }
9+
let(:logged_in_adapter) do
10+
Class.new.tap { |c| allow(c).to receive(:new) { logged_in_adapter_instance } }
11+
end
12+
let(:logged_out_adapter_instance) { double }
13+
let(:logged_out_adapter) do
14+
Class.new.tap { |c| allow(c).to receive(:new) { logged_out_adapter_instance } }
15+
end
2716

28-
it "#[]" do
29-
expect(selected_adapter_instance).to receive(:[]).with('my_key'){'my_value'}
30-
expect_any_instance_of(not_selected_adapter).not_to receive(:[])
31-
expect(subject["my_key"]).to eq('my_value')
17+
context 'when logged in' do
18+
subject do
19+
described_class.with_config(
20+
logged_in: lambda { |context| true },
21+
logged_in_adapter: logged_in_adapter,
22+
logged_out_adapter: logged_out_adapter
23+
).new(context)
3224
end
3325

34-
it "#delete" do
35-
expect(selected_adapter_instance).to receive(:delete).with('my_key'){'my_value'}
36-
expect_any_instance_of(not_selected_adapter).not_to receive(:delete)
37-
expect(subject.delete("my_key")).to eq('my_value')
26+
it '#[]=' do
27+
expect(logged_in_adapter_instance).to receive(:[]=).with('my_key', 'my_value')
28+
expect(logged_out_adapter_instance).to receive(:[]=).with('my_key', 'my_value')
29+
subject['my_key'] = 'my_value'
3830
end
3931

40-
it "#keys" do
41-
expect(selected_adapter_instance).to receive(:keys){'my_value'}
42-
expect_any_instance_of(not_selected_adapter).not_to receive(:keys)
43-
expect(subject.keys).to eq('my_value')
32+
it '#[]' do
33+
expect(logged_in_adapter_instance).to receive(:[]).with('my_key') { 'my_value' }
34+
expect_any_instance_of(logged_out_adapter).not_to receive(:[])
35+
expect(subject['my_key']).to eq('my_value')
4436
end
45-
end
4637

47-
context "when logged in" do
48-
subject {
49-
described_class.with_config(
50-
logged_in: lambda { |context| true },
51-
logged_in_adapter: selected_adapter,
52-
logged_out_adapter: not_selected_adapter
53-
).new(context)
54-
}
38+
it '#delete' do
39+
expect(logged_in_adapter_instance).to receive(:delete).with('my_key') { 'my_value' }
40+
expect(logged_out_adapter_instance).to receive(:delete).with('my_key') { 'my_value' }
41+
expect(subject.delete('my_key')).to eq('my_value')
42+
end
5543

56-
it_should_behave_like "forwarding calls"
44+
it '#keys' do
45+
expect(logged_in_adapter_instance).to receive(:keys) { ['my_value'] }
46+
expect(logged_out_adapter_instance).to receive(:keys) { ['my_value'] }
47+
expect(subject.keys).to eq(['my_value', 'my_value'])
48+
end
5749
end
5850

59-
context "when not logged in" do
60-
subject {
51+
context 'when logged out' do
52+
subject do
6153
described_class.with_config(
6254
logged_in: lambda { |context| false },
63-
logged_in_adapter: not_selected_adapter,
64-
logged_out_adapter: selected_adapter
65-
).new(context)
66-
}
55+
logged_in_adapter: logged_in_adapter,
56+
logged_out_adapter: logged_out_adapter
57+
).new(context)
58+
end
6759

68-
it_should_behave_like "forwarding calls"
60+
it '#[]=' do
61+
expect_any_instance_of(logged_in_adapter).not_to receive(:[])
62+
expect(logged_out_adapter_instance).to receive(:[]=).with('my_key', 'my_value')
63+
subject['my_key'] = 'my_value'
64+
end
65+
66+
it '#[]' do
67+
expect_any_instance_of(logged_in_adapter).not_to receive(:[])
68+
expect(logged_out_adapter_instance).to receive(:[]).with('my_key') { 'my_value' }
69+
expect(subject['my_key']).to eq('my_value')
70+
end
71+
72+
it '#delete' do
73+
expect(logged_in_adapter_instance).to receive(:delete).with('my_key') { 'my_value' }
74+
expect(logged_out_adapter_instance).to receive(:delete).with('my_key') { 'my_value' }
75+
expect(subject.delete('my_key')).to eq('my_value')
76+
end
77+
78+
it '#keys' do
79+
expect(logged_in_adapter_instance).to receive(:keys) { ['my_value'] }
80+
expect(logged_out_adapter_instance).to receive(:keys) { ['my_value'] }
81+
expect(subject.keys).to eq(['my_value', 'my_value'])
82+
end
6983
end
7084

71-
describe "when errors in config" do
72-
before{
73-
described_class.config.clear
74-
}
75-
let(:some_proc){ ->{} }
76-
it "when no logged in adapter" do
85+
describe 'when errors in config' do
86+
before { described_class.config.clear }
87+
let(:some_proc) { ->{} }
88+
89+
it 'when no logged in adapter' do
7790
expect{
7891
described_class.with_config(
7992
logged_in: some_proc,
80-
logged_out_adapter: just_adapter
81-
).new(context)
93+
logged_out_adapter: logged_out_adapter
94+
).new(context)
8295
}.to raise_error(StandardError, /:logged_in_adapter/)
8396
end
84-
it "when no logged out adapter" do
97+
98+
it 'when no logged out adapter' do
8599
expect{
86100
described_class.with_config(
87101
logged_in: some_proc,
88-
logged_in_adapter: just_adapter
89-
).new(context)
102+
logged_in_adapter: logged_in_adapter
103+
).new(context)
90104
}.to raise_error(StandardError, /:logged_out_adapter/)
91105
end
92-
it "when no logged in detector" do
106+
107+
it 'when no logged in detector' do
93108
expect{
94109
described_class.with_config(
95-
logged_in_adapter: just_adapter,
96-
logged_out_adapter: just_adapter
97-
).new(context)
110+
logged_in_adapter: logged_in_adapter,
111+
logged_out_adapter: logged_out_adapter
112+
).new(context)
98113
}.to raise_error(StandardError, /:logged_in$/)
99114
end
100115
end
101-
102116
end

0 commit comments

Comments
 (0)