offs 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f7f44fb139c3f2a88d2510ee22559e18037d9a32
4
- data.tar.gz: 0b224e3575e8f241ffec5e5f2a370b2d402ba565
3
+ metadata.gz: cc1b08f770214df36eb4c408459b0060fc9dd8af
4
+ data.tar.gz: 43f9ab69b33a234eae79f53555c52772933628ed
5
5
  SHA512:
6
- metadata.gz: fcea828f9ec2c1819e231f8964083575d8f1d83277ee3371826d62c1b4057d6487e6a5f6da178b9c3621dd7c0616d04539ab2c8534d22205ef042238559b9ee0
7
- data.tar.gz: 19b9c2ccbb99a95b397421a2c17731408cf73a6502098d7bb3ab1a2acf6412d8c22200b609759e0b1f11db1744107ddff8be2c583fa69ed964c4fcb7f9a837cc
6
+ metadata.gz: eb477f36c3cac9362b242d04ca9b66019a4d888131f1543ce9168d35f61fde7d683122dbefcddab14ef3ed18ea949a6aa6d7069733b1b1980eb91ffdef3e7b01
7
+ data.tar.gz: 4ffce2d90133a5072a75bb2085e68faf20a8a366ae1da7a82a87565cc371db79b7e2dc3e1655644430a4740ae235e6abc64fe99299b0a49d17e332a0a812efd2
data/README.md CHANGED
@@ -38,8 +38,10 @@ you could put the following in `config/initializers/offs_flags.rb`:
38
38
  ```ruby
39
39
  require 'offs'
40
40
 
41
- OFFS.flag :use_my_million_dollar_idea, false
42
- OFFS.flag :use_this_mostly_done_feature, true
41
+ OFFS::Flags.set do |offs|
42
+ offs.flag :use_my_million_dollar_idea, false
43
+ offs.flag :use_this_mostly_done_feature, true
44
+ end
43
45
  ```
44
46
 
45
47
  You've now defined the flags that your app will use, and you've given
data/lib/offs/flags.rb ADDED
@@ -0,0 +1,45 @@
1
+ class OFFS
2
+ class Flags
3
+ UndefinedFlagError = Class.new(StandardError)
4
+
5
+ class << self
6
+ def instance
7
+ @instance ||= new
8
+ end
9
+
10
+ def set(&block)
11
+ block.call(instance)
12
+ instance
13
+ end
14
+ end
15
+
16
+ def flag(name, default)
17
+ env_var_name = name.to_s.upcase
18
+ feature_flags[name] = if ENV.has_key?(env_var_name)
19
+ ENV[env_var_name].strip == '1'
20
+ else
21
+ default
22
+ end
23
+ end
24
+
25
+ def feature_flags
26
+ @feature_flags ||= {}
27
+ end
28
+
29
+ def enabled?(flag)
30
+ !!feature_flags[flag]
31
+ end
32
+
33
+ def valid?(flag)
34
+ feature_flags.has_key?(flag)
35
+ end
36
+
37
+ def validate!(flag)
38
+ if valid?(flag)
39
+ flag
40
+ else
41
+ raise UndefinedFlagError, "The #{flag} flag has not been defined."
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,28 @@
1
+ require 'delegate'
2
+ require 'injectable_dependencies'
3
+
4
+ class OFFS
5
+ class Permutations < DelegateClass(Enumerator)
6
+ include InjectableDependencies
7
+
8
+ dependency(:flags) { Flags.instance }
9
+
10
+ def initialize(options={})
11
+ initialize_dependencies(options[:dependencies])
12
+ __setobj__ create_permutations
13
+ end
14
+
15
+ private
16
+
17
+ def create_permutations
18
+ keys = flags.to_a
19
+ permutations = [true,false].repeated_permutation(keys.size).map { |values|
20
+ keys.zip(values).inject({}) { |m, pair|
21
+ m[pair[0]] = pair[1]
22
+ m
23
+ }
24
+ }
25
+ permutations.each
26
+ end
27
+ end
28
+ end
data/lib/offs/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class OFFS
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
data/lib/offs.rb CHANGED
@@ -1,31 +1,17 @@
1
1
  require "offs/version"
2
+ require 'offs/flags'
2
3
  require 'injectable_dependencies'
3
4
 
4
5
  class OFFS
5
6
  include InjectableDependencies
6
7
 
7
- UndefinedFlagError = Class.new(StandardError)
8
-
9
8
  class << self
10
9
  def so_you_want_to(flag, &block)
11
10
  new(flag).so_you_want_to(&block)
12
11
  end
13
-
14
- def flag(name, default)
15
- env_var_name = name.to_s.upcase
16
- feature_flags[name] = if ENV.has_key?(env_var_name)
17
- ENV[env_var_name].strip == '1'
18
- else
19
- default
20
- end
21
- end
22
-
23
- def feature_flags
24
- @feature_flags ||= {}
25
- end
26
12
  end
27
13
 
28
- dependency(:feature_flags) { OFFS.feature_flags }
14
+ dependency(:feature_flags) { Flags.instance }
29
15
 
30
16
  def initialize(flag, options={})
31
17
  initialize_dependencies options[:dependencies]
@@ -37,28 +23,26 @@ class OFFS
37
23
  end
38
24
 
39
25
  def would_like_to(&block)
40
- return unless flag_is_on?
41
- block.call
26
+ when_flag(true, &block)
42
27
  end
43
28
 
44
29
  def may_still_need_to(&block)
45
- return if flag_is_on?
46
- block.call
30
+ when_flag(false, &block)
47
31
  end
48
32
 
49
33
  private
50
34
 
51
35
  attr_reader :flag
52
36
 
53
- def flag_is_on?
54
- !!feature_flags[flag]
37
+ def when_flag(bool, &block)
38
+ block.call if flag_status == bool
39
+ end
40
+
41
+ def flag_status
42
+ feature_flags.enabled?(flag)
55
43
  end
56
44
 
57
45
  def flag=(new_flag)
58
- if feature_flags.has_key?(new_flag)
59
- @flag = new_flag
60
- else
61
- raise UndefinedFlagError, "The #{new_flag} flag has not been defined."
62
- end
46
+ @flag = feature_flags.validate!(new_flag)
63
47
  end
64
48
  end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+ require 'offs/permutations'
3
+
4
+ describe OFFS::Permutations do
5
+ subject { described_class.new(dependencies: dependencies) }
6
+
7
+ let(:dependencies) {{
8
+ flags: flags
9
+ }}
10
+
11
+ let(:flags) { double(:flags, to_a: [:feature_a, :feature_b, :feature_c]) }
12
+
13
+ let(:possible_permutations) {[
14
+ { feature_a: true, feature_b: true, feature_c: true },
15
+ { feature_a: false, feature_b: true, feature_c: true },
16
+ { feature_a: true, feature_b: false, feature_c: true },
17
+ { feature_a: true, feature_b: true, feature_c: false },
18
+ { feature_a: false, feature_b: false, feature_c: true },
19
+ { feature_a: false, feature_b: true, feature_c: false },
20
+ { feature_a: true, feature_b: false, feature_c: false },
21
+ { feature_a: false, feature_b: false, feature_c: false },
22
+ ]}
23
+
24
+ let(:receiver) { double(:receiver) }
25
+
26
+ it 'yields every permutation of feature flag combinations' do
27
+ possible_permutations.each do |permutation|
28
+ expect(receiver).to receive(:flags).with(permutation)
29
+ end
30
+
31
+ subject.each do |flags|
32
+ receiver.flags(flags)
33
+ end
34
+ end
35
+ end
data/spec/offs_spec.rb CHANGED
@@ -13,18 +13,18 @@ describe OFFS do
13
13
  feature_flags: feature_flags
14
14
  }}
15
15
 
16
- let(:feature_flags) {{
17
- :my_cool_new_feature => feature_status
18
- }}
19
-
20
- let(:feature_status) { true }
16
+ let(:feature_flags) {
17
+ OFFS::Flags.set do |f|
18
+ f.flag :my_cool_new_feature, feature_status
19
+ end
20
+ }
21
21
 
22
22
  context 'when the specified feature flag is not defined' do
23
- let(:feature_flags) {{}}
23
+ let(:feature_flags) { OFFS::Flags.new }
24
24
 
25
25
  it 'raises an error' do
26
26
  expect{ subject.so_you_want_to {} }.to \
27
- raise_error(OFFS::UndefinedFlagError,
27
+ raise_error(OFFS::Flags::UndefinedFlagError,
28
28
  "The #{flag} flag has not been defined.")
29
29
  end
30
30
  end
@@ -41,6 +41,8 @@ describe OFFS do
41
41
  end
42
42
 
43
43
  context "and the feature is turned on by default" do
44
+ let(:feature_status) { true }
45
+
44
46
  it 'executes the would_like_to block' do
45
47
  expect(would_like_to_blk).to receive(:call)
46
48
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: offs
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Wilger
@@ -85,8 +85,11 @@ files:
85
85
  - README.md
86
86
  - Rakefile
87
87
  - lib/offs.rb
88
+ - lib/offs/flags.rb
89
+ - lib/offs/permutations.rb
88
90
  - lib/offs/version.rb
89
91
  - offs.gemspec
92
+ - spec/offs/permutations_spec.rb
90
93
  - spec/offs_spec.rb
91
94
  - spec/spec_helper.rb
92
95
  homepage: ''
@@ -114,5 +117,6 @@ signing_key:
114
117
  specification_version: 4
115
118
  summary: OFFS Feature Flagging System
116
119
  test_files:
120
+ - spec/offs/permutations_spec.rb
117
121
  - spec/offs_spec.rb
118
122
  - spec/spec_helper.rb