flip-flop 0.0.2 → 0.0.3

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: 876ae4f24582ebe07ddc6635c925eacd44bfd4de
4
- data.tar.gz: 1009ffb11e5896c310896fde803211ec6f63fea5
3
+ metadata.gz: 402aff4b7c0a288f0f8f6bf862faa253a991cdeb
4
+ data.tar.gz: 6344ef9e5da7ed8cfd854feaf488285f01f3bdef
5
5
  SHA512:
6
- metadata.gz: f2d7d4bbac7019588892afb82c06ce1bbaabc2b0548f32c347c59668682e27e1717ca72b6d2ef2069614fe6ffd7f5eb6675a2b938620deef4e808c239116a1de
7
- data.tar.gz: f4a91ff2fa037b1e824f94f4b4f17b63171d700a0973a006997a288a12d18294e716b05413f596672197034e551b770faf99b22a89c0485a20a07bc56fc9793d
6
+ metadata.gz: eb0ee52c53566d20e347126e2978c10606a0d04f460c426456fbe08d0bf115eeb9c261826148a3fd3668f66e23471a642dc68428da0a6e1b2207d6829adbd13e
7
+ data.tar.gz: ecaf65cefa2a7d68e85093e1ea3d1593ce2d09ba301dcf3ccdec4eaff90f93adbb865d7d90ceed942d633085e915ac8aba6276c3de3e4a53d2a148bd1e0b66cb
data/Gemfile CHANGED
@@ -2,4 +2,9 @@ source 'https://rubygems.org'
2
2
  gemspec :name => 'flip-flop'
3
3
 
4
4
  gem 'rake', '~> 10.4.2'
5
- gem 'rspec', '~> 3.0'
5
+ gem 'rspec', '~> 3.0'
6
+
7
+ group :test do
8
+ gem 'activerecord'
9
+ gem 'sqlite3'
10
+ end
data/Gemfile.lock CHANGED
@@ -1,12 +1,30 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- flip-flop (0.0.2)
4
+ flip-flop (0.0.3)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
+ activemodel (4.2.6)
10
+ activesupport (= 4.2.6)
11
+ builder (~> 3.1)
12
+ activerecord (4.2.6)
13
+ activemodel (= 4.2.6)
14
+ activesupport (= 4.2.6)
15
+ arel (~> 6.0)
16
+ activesupport (4.2.6)
17
+ i18n (~> 0.7)
18
+ json (~> 1.7, >= 1.7.7)
19
+ minitest (~> 5.1)
20
+ thread_safe (~> 0.3, >= 0.3.4)
21
+ tzinfo (~> 1.1)
22
+ arel (6.0.3)
23
+ builder (3.2.2)
9
24
  diff-lcs (1.2.5)
25
+ i18n (0.7.0)
26
+ json (1.8.3)
27
+ minitest (5.8.4)
10
28
  rake (10.4.2)
11
29
  rspec (3.4.0)
12
30
  rspec-core (~> 3.4.0)
@@ -21,14 +39,20 @@ GEM
21
39
  diff-lcs (>= 1.2.0, < 2.0)
22
40
  rspec-support (~> 3.4.0)
23
41
  rspec-support (3.4.1)
42
+ sqlite3 (1.3.11)
43
+ thread_safe (0.3.5)
44
+ tzinfo (1.2.2)
45
+ thread_safe (~> 0.1)
24
46
 
25
47
  PLATFORMS
26
48
  ruby
27
49
 
28
50
  DEPENDENCIES
51
+ activerecord
29
52
  flip-flop!
30
53
  rake (~> 10.4.2)
31
54
  rspec (~> 3.0)
55
+ sqlite3
32
56
 
33
57
  BUNDLED WITH
34
- 1.11.2
58
+ 1.12.4
data/README.md CHANGED
@@ -36,7 +36,7 @@ FlipFlop.configure do |config|
36
36
  end
37
37
  ```
38
38
 
39
- and add a YAML file: `config/flip-flop.yml`
39
+ and add a YAML file: `config/flip_flop.yml`
40
40
 
41
41
  for example:
42
42
 
@@ -57,12 +57,23 @@ for example:
57
57
  begin: 2016-01-01
58
58
  end: 2016-02-01
59
59
  excl: false
60
+ :rails_env_example:
61
+ :type: :rails_env
62
+ :value: :production
63
+ :another_rails_env_example:
64
+ :type: :rails_env
65
+ :env:
66
+ - :production
67
+ - :test
60
68
  ```
61
69
 
62
70
  Example Usage
63
71
  -------------
64
72
 
65
- In a view:
73
+ Once FlipFlop has been configured, (see above section) you can start checking if features
74
+ are enabled or not.
75
+
76
+ ### In a Rails View:
66
77
 
67
78
  ```ruby
68
79
  if feature_enabled? :my_cool_feature
@@ -73,7 +84,7 @@ end
73
84
 
74
85
  ```
75
86
 
76
- In a controller:
87
+ ### In a Rails Controller:
77
88
 
78
89
  ```ruby
79
90
  class SomeController < ApplicationController
@@ -85,10 +96,10 @@ class SomeController < ApplicationController
85
96
  end
86
97
  ```
87
98
 
88
- Without Rails:
99
+ ### Without Rails:
89
100
 
90
101
  ```ruby
91
- if FlipFlop::get_instance.feature_enabled? :some_feature
102
+ if FlipFlop.feature_enabled? :some_feature
92
103
  puts 'something'
93
104
  else
94
105
  puts 'something else'
@@ -106,6 +117,7 @@ Gates
106
117
  * `until_time` &mdash; enable a feature until a time has passed
107
118
  * `time_range` &mdash; enable a feature for the duration of a time range
108
119
  * `percentage_of_time` &mdash; enable a feature for a given percentage of checks
120
+ * `rails_env` &mdash; enable a feature for a specified Rails environment
109
121
 
110
122
  Adapters
111
123
  --------
@@ -122,6 +134,11 @@ about enabled and disabled features. The YAML file is parsed once when the appli
122
134
  loaded. It's quick and easy to use, but it requres a deployment if a feature needs
123
135
  to be quickly flipped.
124
136
 
137
+ ### ActiveRecord
138
+
139
+ Allows feature settings to be stored in a database table. Because of typecasting and
140
+ additional garbage collection this will not be as fast as the YAML adapter. Futher
141
+ efforts will be made to makeing The ActiveRecord adapter more performant.
125
142
 
126
143
  Extending FlipFlop
127
144
  ------------------
@@ -151,4 +168,4 @@ Contributing to FlipFlop
151
168
  * branch
152
169
  * commit
153
170
  * push
154
- * pull request
171
+ * pull request
@@ -0,0 +1,61 @@
1
+ require 'active_record'
2
+
3
+ module FlipFlop
4
+ module Adapters
5
+ module ActiveRecord
6
+
7
+ # override this method to prevent the feature being loaded from the
8
+ # database twice.
9
+ def feature_enabled?(feature_name)
10
+ f = get_feature(feature_name)
11
+ public_send f.gate_type, f.value
12
+ rescue
13
+ false
14
+ end
15
+
16
+ def get_feature(name)
17
+ Feature::find_by_name(name)
18
+ end
19
+
20
+ # Load the record from the DB if it's already there, and store
21
+ # the gate type and value
22
+ def set_feature(name, gate_type, value)
23
+ f = Feature::find_or_initialize_by(name: name)
24
+ f.gate_type = gate_type
25
+ f.value = value
26
+ f.save
27
+ end
28
+
29
+ # Diable the feature by deleting the record from the DB
30
+ def disable_feature(name)
31
+ get_feature(name).delete
32
+ end
33
+
34
+ # here for compatability, should not really be used
35
+ def feature_type(name)
36
+ get_feature(name).gate_type.to_sym
37
+ end
38
+
39
+ # here for compatabilty, should not really be used
40
+ def feature_value(name)
41
+ get_feature(name).value
42
+ end
43
+
44
+ class Feature < ::ActiveRecord::Base
45
+ self.table_name = 'flip_flop_features'.freeze
46
+ serialize :value
47
+
48
+ # getter to type case to symbol
49
+ def name
50
+ super.to_sym
51
+ end
52
+
53
+ # getter to type case to symbol
54
+ def gate_type
55
+ super.to_sym
56
+ end
57
+
58
+ end
59
+ end
60
+ end
61
+ end
@@ -23,15 +23,19 @@ module FlipFlop
23
23
  end
24
24
 
25
25
  def until_time(value)
26
- Time.now < value
26
+ Time.now.utc < value
27
27
  end
28
28
 
29
29
  def after_time(value)
30
- Time.now > value
30
+ Time.now.utc > value
31
31
  end
32
32
 
33
33
  def percentage_of_time(value)
34
34
  rand < (value / 100.0)
35
35
  end
36
+
37
+ def rails_env(value)
38
+ value == Rails.env.to_sym || value.include?(Rails.env.to_sym)
39
+ end
36
40
  end
37
41
  end
@@ -1,3 +1,3 @@
1
1
  module FlipFlop
2
- VERSION = "0.0.2"
2
+ VERSION = '0.0.3'
3
3
  end
data/lib/flip-flop.rb CHANGED
@@ -21,7 +21,8 @@ module FlipFlop
21
21
  # Arguments:
22
22
  # configuration block: (block)
23
23
  def self.configure(&block)
24
- get_instance.configure(&block)
24
+ @flip_flop = FlipFlop.new
25
+ @flip_flop.configure(&block)
25
26
  end
26
27
 
27
28
  # Check if a feature is enabled or not
@@ -0,0 +1,20 @@
1
+ require 'rails/generators/active_record'
2
+
3
+ module FlipFlop
4
+ module Generators
5
+ class MigrationsGenerator < ::Rails::Generators::Base
6
+ include ::Rails::Generators::Migration
7
+ desc 'Generates migration for FlipFlop tables'
8
+
9
+ source_paths << File.join(File.dirname(__FILE__), 'templates')
10
+
11
+ def create_migration_file
12
+ migration_template 'migration.rb', 'db/migrate/create_flip_flop_tables.rb'
13
+ end
14
+
15
+ def self.next_migration_number(dirname)
16
+ ::ActiveRecord::Generators::Base.next_migration_number(dirname)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ class CreateFlipFlopFeatureTable < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :flip_flop_features do |t|
4
+ t.string :name
5
+ t.string :gate_type
6
+ t.text :value
7
+ end
8
+
9
+ add_index :flip_flop_features, :name, unique: true
10
+ end
11
+
12
+ def self.down
13
+ drop_table :flip_flop_features
14
+ end
15
+ end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+ require 'flip-flop/adapters/active_record'
3
+ require 'generators/templates/migration'
4
+
5
+ ActiveRecord::Migration.verbose = false
6
+
7
+ describe FlipFlop::Adapters::ActiveRecord do
8
+ context 'ActiveRecord' do
9
+
10
+ before :all do
11
+ ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:'
12
+ FlipFlop.configure { |config| config[:adapter] = FlipFlop::Adapters::ActiveRecord }
13
+ end
14
+
15
+ before :each do
16
+ CreateFlipFlopFeatureTable.up
17
+ FlipFlop.get_instance.set_feature :db, :boolean, true
18
+ end
19
+
20
+ after :each do
21
+ CreateFlipFlopFeatureTable.down
22
+ end
23
+
24
+ it 'should save a feature to the database' do
25
+ r = FlipFlop::Adapters::ActiveRecord::Feature.all
26
+ expect(r.size).to eql 1
27
+ expect(r.first.name).to eql :db
28
+ expect(r.first.value).to be_truthy
29
+ expect(r.first.gate_type).to eql :boolean
30
+ end
31
+
32
+ it 'should return true for a bool' do
33
+ expect(FlipFlop.feature_enabled?(:db)).to be_truthy
34
+ end
35
+
36
+ it 'should be changeable' do
37
+ FlipFlop.get_instance.set_feature :db, :boolean, false
38
+ r = FlipFlop::Adapters::ActiveRecord::Feature.all
39
+ expect(r.size).to eql 1
40
+ expect(r.first.name).to eql :db
41
+ expect(r.first.value).to be_falsey
42
+ expect(r.first.gate_type).to eql :boolean
43
+ end
44
+
45
+ it 'should still work with other datatypes' do
46
+ FlipFlop.get_instance.set_feature :dates, :date_range, (Date.today - 2)..(Date.today + 2)
47
+ expect(FlipFlop.feature_enabled?(:dates)).to be_truthy
48
+ end
49
+
50
+ end
51
+ end
@@ -7,7 +7,18 @@ class DummyController
7
7
  include FlipFlop::ViewHelpers
8
8
  end
9
9
 
10
- describe DummyController do
10
+ if !defined? Rails
11
+ module Rails
12
+ def self.env
13
+ :test
14
+ end
15
+ end
16
+ end
17
+
18
+ describe DummyController do
19
+ before :each do
20
+ FlipFlop.configure {}
21
+ end
11
22
 
12
23
  describe '#feature_enabled?' do
13
24
  it 'should return false if nothing has been set' do
@@ -101,15 +112,42 @@ describe DummyController do
101
112
  end
102
113
 
103
114
  it 'feature should be disabled if range not started yet' do
104
- ::FlipFlop::get_instance.set_feature(:ranged, :date_range, (Time.now.utc + 60)..(Time.now.utc + ONE_DAY))
115
+ ::FlipFlop::get_instance.set_feature(:ranged, :time_range, (Time.now.utc + 60)..(Time.now.utc + ONE_DAY))
105
116
  expect(subject.feature_enabled? :ranged).to be_falsey
106
117
  end
107
118
 
108
119
  it 'feature should be disabled if range is past' do
109
- ::FlipFlop::get_instance.set_feature(:ranged, :date_range, (Time.now.utc - ONE_DAY)..(Time.now.utc - 60))
120
+ ::FlipFlop::get_instance.set_feature(:ranged, :time_range, (Time.now.utc - ONE_DAY)..(Time.now.utc - 60))
110
121
  expect(subject.feature_enabled? :ranged).to be_falsey
111
122
  end
112
123
  end
124
+
125
+ context 'rails_env gate' do
126
+ it 'should work if value is equal to rails env' do
127
+ ::FlipFlop::get_instance.set_feature(:qwerty, :rails_env, :test)
128
+ expect(subject.feature_enabled? :qwerty).to be_truthy
129
+ end
130
+
131
+ it 'should fail if value is not equal to rails env' do
132
+ ::FlipFlop::get_instance.set_feature(:qwerty, :rails_env, :production)
133
+ expect(subject.feature_enabled? :qwerty).to be_falsey
134
+ end
135
+
136
+ it 'should pass in value is an array containing the env' do
137
+ ::FlipFlop::get_instance.set_feature(:qwerty, :rails_env, [:production, :test])
138
+ expect(subject.feature_enabled? :qwerty).to be_truthy
139
+ end
140
+
141
+ it 'should fail in value is an array not containing the env' do
142
+ ::FlipFlop::get_instance.set_feature(:qwerty, :rails_env, [:production, :dev])
143
+ expect(subject.feature_enabled? :qwerty).to be_falsey
144
+ end
145
+
146
+ it 'should fail if the env contains part of the value' do
147
+ ::FlipFlop::get_instance.set_feature(:qwerty, :rails_env, [:production, :testing])
148
+ expect(subject.feature_enabled? :test).to be_falsey
149
+ end
150
+ end
113
151
  end
114
152
 
115
- end
153
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,4 @@
1
- $:.unshift(File.expand_path('../lib', __FILE__))
1
+ $LOAD_PATH.unshift(File.expand_path('../lib', __FILE__))
2
2
 
3
3
  require 'pathname'
4
4
  FlopFlopRoot = Pathname(__FILE__).dirname.join('..').expand_path
@@ -6,10 +6,10 @@ FlopFlopRoot = Pathname(__FILE__).dirname.join('..').expand_path
6
6
  require 'rubygems'
7
7
  require 'bundler'
8
8
 
9
- Bundler.setup(:default)
9
+ Bundler.setup(:default, :test)
10
10
 
11
11
  require 'flip-flop'
12
12
 
13
- RSpec.configure do |config|
13
+ RSpec.configure do
14
14
  FlipFlop.configure {}
15
- end
15
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flip-flop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Kulyk
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-26 00:00:00.000000000 Z
11
+ date: 2016-05-23 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Enable or disable features easily
14
14
  email:
@@ -23,12 +23,16 @@ files:
23
23
  - Rakefile
24
24
  - flip-flop.gemspec
25
25
  - lib/flip-flop.rb
26
+ - lib/flip-flop/adapters/active_record.rb
26
27
  - lib/flip-flop/adapters/memory.rb
27
28
  - lib/flip-flop/adapters/yaml.rb
28
29
  - lib/flip-flop/gates.rb
29
30
  - lib/flip-flop/railtie.rb
30
31
  - lib/flip-flop/version.rb
31
32
  - lib/flip-flop/view_helpers.rb
33
+ - lib/generators/flip-flop/migrations_generator.rb
34
+ - lib/generators/templates/migration.rb
35
+ - spec/lib/adapters/active_record_spec.rb
32
36
  - spec/lib/adapters/yaml_spec.rb
33
37
  - spec/lib/view_helpers_spec.rb
34
38
  - spec/spec_helper.rb
@@ -53,11 +57,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
53
57
  version: '0'
54
58
  requirements: []
55
59
  rubyforge_project:
56
- rubygems_version: 2.4.8
60
+ rubygems_version: 2.5.1
57
61
  signing_key:
58
62
  specification_version: 4
59
63
  summary: Feature flipper
60
64
  test_files:
65
+ - spec/lib/adapters/active_record_spec.rb
61
66
  - spec/lib/adapters/yaml_spec.rb
62
67
  - spec/lib/view_helpers_spec.rb
63
68
  - spec/spec_helper.rb