Skip to content
Browse files

Implement enable/disable groups.

  • Loading branch information...
1 parent adf83de commit 2246dddaa7cdc0eb5ad5b653859e2a707e57ca5d @jnunemaker committed Jul 25, 2012
Showing with 155 additions and 41 deletions.
  1. +0 −3 flipper.gemspec
  2. +39 −15 lib/flipper/feature.rb
  3. +116 −23 spec/flipper/feature_spec.rb
View
3 flipper.gemspec
@@ -14,7 +14,4 @@ Gem::Specification.new do |gem|
gem.name = "flipper"
gem.require_paths = ["lib"]
gem.version = Flipper::VERSION
-
- gem.add_dependency 'mongo', '~> 1.6'
- gem.add_dependency 'adapter', '~> 0.5'
end
View
54 lib/flipper/feature.rb
@@ -1,32 +1,56 @@
-require 'adapter'
-
module Flipper
class Feature
+ attr_reader :name
+
def initialize(name, adapter)
@name = name
@adapter = adapter
end
- def enable
- @adapter.write(boolean_key(@name), true)
+ def enable(thing = nil)
+ case thing
+ when nil
+ @adapter.write "#{@name}.boolean", true
+ when Flipper::Group
+ @adapter.set_add "#{@name}.groups", thing.name
+ end
end
- def disable
- @adapter.write(boolean_key(@name), false)
+ def disable(thing = nil)
+ case thing
+ when nil
+ @adapter.delete "#{@name}.boolean"
+ @adapter.delete "#{@name}.groups"
+ when Flipper::Group
+ @adapter.set_delete "#{@name}.groups", thing.name
+ end
end
- def enabled?
- @adapter.read(boolean_key(@name)) == true
- end
+ # thing is..
+ # nil => boolean key
+ # group => group key
+ # else =>
+ # - true if boolean key true
+ # - true if any enabled groups match actor
+ def enabled?(thing = nil)
+ boolean_flip = @adapter.read("#{@name}.boolean")
- def disabled?
- !enabled?
- end
+ if boolean_flip || thing.nil?
+ return boolean_flip
+ end
- private
+ if thing.is_a?(Flipper::Group)
+ group_names = @adapter.set_members("#{@name}.groups")
+ return group_names.include?(thing.name)
+ else
+ group_names = @adapter.set_members("#{@name}.groups")
+ groups = group_names.map { |name| Group.get(name) }.compact
+ groups.any? { |group| group.match?(thing) }
+ end
+ end
- def boolean_key(name)
- "#{name}_boolean"
+ def disabled?(thing = nil)
+ !enabled?(thing)
end
end
end
View
139 spec/flipper/feature_spec.rb
@@ -1,17 +1,20 @@
require 'helper'
require 'flipper/feature'
-require 'adapter/memory'
+require 'flipper/memory_adapter'
describe Flipper::Feature do
- subject {
- Flipper::Feature.new(:search, adapter)
- }
+ subject { Flipper::Feature.new(:search, adapter) }
- let(:adapter) {
- Adapter[:memory].new({})
- }
+ let(:adapter) { Flipper::MemoryAdapter.new }
+ let(:admin_group) { Flipper::Group.get(:admins) }
+ let(:dev_group) { Flipper::Group.get(:devs) }
before do
+ Flipper::Group.all.clear
+
+ Flipper::Group.define(:admins) { |actor| actor.admin? }
+ Flipper::Group.define(:devs) { |actor| actor.dev? }
+
adapter.clear
end
@@ -20,37 +23,127 @@
feature.should be_instance_of(Flipper::Feature)
end
- describe "#enabled?" do
- it "defaults to false" do
- subject.enabled?.should be_false
+ describe "#name" do
+ it "returns name" do
+ subject.name.should eq(:search)
end
end
describe "#enable" do
- before do
- subject.enable
- end
+ context "with no arguments" do
+ before do
+ subject.enable
+ end
- it "is enabled" do
- subject.enabled?.should be_true
+ it "enables feature for all" do
+ subject.enabled?.should be_true
+ end
end
- it "is not disabled" do
- subject.disabled?.should be_false
+ context "with a group" do
+ before do
+ subject.enable(admin_group)
+ end
+
+ it "enables feature for group" do
+ subject.enabled?(admin_group).should be_true
+ end
+
+ it "does not enable feature for all" do
+ subject.enabled?.should be_false
+ end
end
end
describe "#disable" do
- before do
- subject.disable
+ context "with no arguments" do
+ before do
+ adapter.set_add("#{subject.name}.groups", admin_group.name)
+ subject.disable
+ end
+
+ it "disables feature" do
+ subject.disabled?.should be_true
+ end
+
+ it "disables feature for all enabled groups" do
+ subject.disabled?(admin_group).should be_true
+ end
+ end
+
+ context "with a group" do
+ before do
+ adapter.set_add("#{subject.name}.groups", dev_group.name)
+ subject.disable(admin_group)
+ end
+
+ it "disables the feature for the group" do
+ subject.disabled?(admin_group).should be_true
+ end
+
+ it "does not disable feature for other groups" do
+ subject.disabled?(dev_group).should be_false
+ end
+ end
+ end
+
+ describe "#enabled?" do
+ context "with no arguments" do
+ it "defaults to false" do
+ subject.enabled?.should be_false
+ end
+ end
+
+ context "for a group" do
+ it "returns true if group enabled" do
+ adapter.set_add("#{subject.name}.groups", admin_group.name)
+ subject.enabled?(admin_group).should be_true
+ end
+
+ it "returns false if group not enabled" do
+ subject.enabled?(admin_group).should be_false
+ end
+ end
+
+ context "for an actor" do
+ let(:admin_actor) { double('Actor', :admin? => true) }
+ let(:non_admin_actor) { double('Actor', :admin? => false) }
+
+ before do
+ adapter.set_add("#{subject.name}.groups", admin_group.name)
+ end
+
+ it "returns true if in enabled group" do
+ subject.enabled?(admin_actor).should be_true
+ end
+
+ it "returns false if not in enabled group" do
+ subject.enabled?(non_admin_actor).should be_false
+ end
end
- it "is not enabled" do
- subject.enabled?.should be_false
+ context "for an actor that does not respond to something in group block" do
+ let(:actor) { double('Actor') }
+
+ before do
+ adapter.set_add("#{subject.name}.groups", admin_group.name)
+ end
+
+ it "returns false" do
+ expect { subject.enabled?(actor) }.to raise_error
+ end
end
- it "is disabled" do
- subject.disabled?.should be_true
+ context "for an actor when group not defined" do
+ let(:actor) { double('Actor') }
+
+ before do
+ adapter.set_add("#{subject.name}.groups", :support)
+ end
+
+ it "does not raise error" do
+ subject.enabled?(actor).should be_false
+ end
end
end
end

0 comments on commit 2246ddd

Please sign in to comment.
Something went wrong with that request. Please try again.