spec/flipper/adapter_spec.rb in flipper-0.3.0 vs spec/flipper/adapter_spec.rb in flipper-0.4.0

- old
+ new

@@ -1,25 +1,31 @@ require 'helper' require 'flipper/adapter' require 'flipper/adapters/memory' +require 'flipper/instrumenters/memory' describe Flipper::Adapter do let(:local_cache) { {} } - let(:adapter) { Flipper::Adapters::Memory.new } + let(:source) { {} } + let(:adapter) { Flipper::Adapters::Memory.new(source) } let(:features_key) { described_class::FeaturesKey } - subject { described_class.new(adapter, local_cache) } + subject { described_class.new(adapter, :local_cache => local_cache) } describe ".wrap" do context "with Flipper::Adapter instance" do before do @result = described_class.wrap(subject) end - it "returns self" do - @result.should be(subject) + it "returns same Flipper::Adapter instance" do + @result.should equal(subject) end + + it "wraps adapter that instance was wrapping" do + @result.adapter.should be(subject.adapter) + end end context "with adapter instance" do before do @result = described_class.wrap(adapter) @@ -28,15 +34,58 @@ it "returns Flipper::Adapter instance" do @result.should be_instance_of(described_class) end it "wraps adapter" do - @result.adapter.should eq(adapter) + @result.adapter.should be(adapter) end end + + context "with adapter instance and options" do + let(:instrumenter) { double('Instrumentor') } + + before do + @result = described_class.wrap(adapter, :instrumenter => instrumenter) + end + + it "returns Flipper::Adapter instance" do + @result.should be_instance_of(described_class) + end + + it "wraps adapter" do + @result.adapter.should be(adapter) + end + + it "passes options to initialization" do + @result.instrumenter.should be(instrumenter) + end + end end + describe "#initialize" do + it "sets adapter" do + instance = described_class.new(adapter) + instance.adapter.should be(adapter) + end + + it "sets adapter name" do + instance = described_class.new(adapter) + instance.name.should be(:memory) + end + + it "defaults instrumenter" do + instance = described_class.new(adapter) + instance.instrumenter.should be(Flipper::Instrumenters::Noop) + end + + it "allows overriding instrumenter" do + instrumenter = double('Instrumentor', :instrument => nil) + instance = described_class.new(adapter, :instrumenter => instrumenter) + instance.instrumenter.should be(instrumenter) + end + end + describe "#use_local_cache=" do it "sets value" do subject.use_local_cache = true subject.using_local_cache?.should be_true @@ -84,22 +133,22 @@ end end describe "#set_members" do before do - adapter.write 'foo', Set[1, 2] + source['foo'] = Set['1', '2'] @result = subject.set_members('foo') end it "returns result of adapter set members" do - @result.should eq(Set[1, 2]) + @result.should eq(Set['1', '2']) end it "memoizes key" do - local_cache['foo'].should eq(Set[1, 2]) + local_cache['foo'].should eq(Set['1', '2']) adapter.should_not_receive(:set_members) - subject.set_members('foo').should eq(Set[1, 2]) + subject.set_members('foo').should eq(Set['1', '2']) end end describe "#write" do before do @@ -130,33 +179,33 @@ end end describe "#set_add" do before do - adapter.write 'foo', Set[1] - local_cache['foo'] = Set[1] - subject.set_add 'foo', 2 + source['foo'] = Set['1'] + local_cache['foo'] = Set['1'] + subject.set_add 'foo', '2' end it "returns result of adapter set members" do - adapter.set_members('foo').should eq(Set[1, 2]) + adapter.set_members('foo').should eq(Set['1', '2']) end it "unmemoizes key" do local_cache.key?('foo').should be_false end end describe "#set_delete" do before do - adapter.write 'foo', Set[1, 2, 3] - local_cache['foo'] = Set[1, 2, 3] - subject.set_delete 'foo', 3 + source['foo'] = Set['1', '2', '3'] + local_cache['foo'] = Set['1', '2', '3'] + subject.set_delete 'foo', '3' end it "returns result of adapter set members" do - adapter.set_members('foo').should eq(Set[1, 2]) + adapter.set_members('foo').should eq(Set['1', '2']) end it "unmemoizes key" do local_cache.key?('foo').should be_false end @@ -183,16 +232,16 @@ end end describe "#set_members" do before do - adapter.write 'foo', Set[1, 2] + source['foo'] = Set['1', '2'] @result = subject.set_members('foo') end it "returns result of adapter set members" do - @result.should eq(Set[1, 2]) + @result.should eq(Set['1', '2']) end it "does not memoize the adapter set member result" do local_cache.key?('foo').should be_false end @@ -230,33 +279,33 @@ end end describe "#set_add" do before do - adapter.write 'foo', Set[1] - local_cache['foo'] = Set[1] - subject.set_add 'foo', 2 + source['foo'] = Set['1'] + local_cache['foo'] = Set['1'] + subject.set_add 'foo', '2' end it "performs adapter set add" do - adapter.set_members('foo').should eq(Set[1, 2]) + adapter.set_members('foo').should eq(Set['1', '2']) end it "does not attempt to delete local cache key" do local_cache.key?('foo').should be_true end end describe "#set_delete" do before do - adapter.write 'foo', Set[1, 2, 3] - local_cache['foo'] = Set[1, 2, 3] - subject.set_delete 'foo', 3 + source['foo'] = Set['1', '2', '3'] + local_cache['foo'] = Set['1', '2', '3'] + subject.set_delete 'foo', '3' end it "performs adapter set delete" do - adapter.set_members('foo').should eq(Set[1, 2]) + adapter.set_members('foo').should eq(Set['1', '2']) end it "does not attempt to delete local cache key" do local_cache.key?('foo').should be_true end @@ -320,8 +369,95 @@ end it "adds string to set" do subject.set_members(features_key).should include('search') end + end + end + + describe "instrumentation" do + let(:instrumenter) { Flipper::Instrumenters::Memory.new } + + subject { + described_class.new(adapter, :instrumenter => instrumenter) + } + + it "is recorded for read" do + subject.read('foo') + + event = instrumenter.events.last + event.should_not be_nil + event.name.should eq('adapter_operation.flipper') + event.payload[:key].should eq('foo') + event.payload[:operation].should eq(:read) + event.payload[:adapter_name].should eq(:memory) + event.payload[:result].should be_nil + end + + it "is recorded for write" do + subject.write('foo', 'bar') + + event = instrumenter.events.last + event.should_not be_nil + event.name.should eq('adapter_operation.flipper') + event.payload[:key].should eq('foo') + event.payload[:value].should eq('bar') + event.payload[:operation].should eq(:write) + event.payload[:adapter_name].should eq(:memory) + event.payload[:result].should eq('bar') + end + + it "is recorded for delete" do + subject.delete('foo') + + event = instrumenter.events.last + event.should_not be_nil + event.name.should eq('adapter_operation.flipper') + event.payload[:key].should eq('foo') + event.payload[:operation].should eq(:delete) + event.payload[:adapter_name].should eq(:memory) + event.payload[:result].should be_nil + end + + it "is recorded for set_members" do + subject.set_members('foo') + + event = instrumenter.events.last + event.should_not be_nil + event.name.should eq('adapter_operation.flipper') + event.payload[:key].should eq('foo') + event.payload[:operation].should eq(:set_members) + event.payload[:adapter_name].should eq(:memory) + event.payload[:result].should eq(Set.new) + end + + it "is recorded for set_add" do + subject.set_add('foo', 'bar') + + event = instrumenter.events.last + event.should_not be_nil + event.name.should eq('adapter_operation.flipper') + event.payload[:key].should eq('foo') + event.payload[:operation].should eq(:set_add) + event.payload[:adapter_name].should eq(:memory) + event.payload[:result].should eq(Set['bar']) + end + + it "is recorded for set_delete" do + subject.set_delete('foo', 'bar') + + event = instrumenter.events.last + event.should_not be_nil + event.name.should eq('adapter_operation.flipper') + event.payload[:key].should eq('foo') + event.payload[:operation].should eq(:set_delete) + event.payload[:adapter_name].should eq(:memory) + event.payload[:result].should eq(Set.new) + end + end + + describe "#inspect" do + it "returns easy to read string representation" do + subject.inspect.should eq("#<Flipper::Adapter:#{subject.object_id} name=:memory, use_local_cache=nil>") end end end