flipflop 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +5 -0
  3. data/.travis.yml +51 -0
  4. data/Gemfile +20 -0
  5. data/LICENSE +22 -0
  6. data/README.md +261 -0
  7. data/Rakefile +16 -0
  8. data/app/assets/stylesheets/flipflop.scss +109 -0
  9. data/app/controllers/concerns/flipflop/environment_filters.rb +5 -0
  10. data/app/controllers/flipflop/features_controller.rb +59 -0
  11. data/app/controllers/flipflop/strategies_controller.rb +30 -0
  12. data/app/models/flipflop/feature.rb +3 -0
  13. data/app/views/flipflop/features/index.html.erb +60 -0
  14. data/app/views/layouts/flipflop.html.erb +1 -0
  15. data/config/routes.rb +5 -0
  16. data/flipflop.gemspec +23 -0
  17. data/lib/flipflop/configurable.rb +27 -0
  18. data/lib/flipflop/engine.rb +58 -0
  19. data/lib/flipflop/facade.rb +23 -0
  20. data/lib/flipflop/feature_cache.rb +64 -0
  21. data/lib/flipflop/feature_definition.rb +15 -0
  22. data/lib/flipflop/feature_set.rb +99 -0
  23. data/lib/flipflop/strategies/abstract_strategy.rb +103 -0
  24. data/lib/flipflop/strategies/active_record_strategy.rb +43 -0
  25. data/lib/flipflop/strategies/cookie_strategy.rb +44 -0
  26. data/lib/flipflop/strategies/default_strategy.rb +15 -0
  27. data/lib/flipflop/strategies/lambda_strategy.rb +25 -0
  28. data/lib/flipflop/strategies/query_string_strategy.rb +17 -0
  29. data/lib/flipflop/strategies/session_strategy.rb +29 -0
  30. data/lib/flipflop/strategies/test_strategy.rb +40 -0
  31. data/lib/flipflop/version.rb +3 -0
  32. data/lib/flipflop.rb +26 -0
  33. data/lib/generators/flipflop/features/USAGE +8 -0
  34. data/lib/generators/flipflop/features/features_generator.rb +7 -0
  35. data/lib/generators/flipflop/features/templates/features.rb +21 -0
  36. data/lib/generators/flipflop/install/install_generator.rb +21 -0
  37. data/lib/generators/flipflop/migration/USAGE +5 -0
  38. data/lib/generators/flipflop/migration/migration_generator.rb +23 -0
  39. data/lib/generators/flipflop/migration/templates/create_features.rb +10 -0
  40. data/lib/generators/flipflop/routes/USAGE +7 -0
  41. data/lib/generators/flipflop/routes/routes_generator.rb +5 -0
  42. data/test/integration/app_test.rb +32 -0
  43. data/test/integration/dashboard_test.rb +162 -0
  44. data/test/test_helper.rb +96 -0
  45. data/test/unit/configurable_test.rb +104 -0
  46. data/test/unit/feature_cache_test.rb +142 -0
  47. data/test/unit/feature_definition_test.rb +42 -0
  48. data/test/unit/feature_set_test.rb +136 -0
  49. data/test/unit/flipflop_test.rb +99 -0
  50. data/test/unit/strategies/abstract_strategy_request_test.rb +42 -0
  51. data/test/unit/strategies/abstract_strategy_test.rb +124 -0
  52. data/test/unit/strategies/active_record_strategy_test.rb +157 -0
  53. data/test/unit/strategies/cookie_strategy_test.rb +126 -0
  54. data/test/unit/strategies/default_strategy_test.rb +44 -0
  55. data/test/unit/strategies/lambda_strategy_test.rb +137 -0
  56. data/test/unit/strategies/query_string_strategy_test.rb +70 -0
  57. data/test/unit/strategies/session_strategy_test.rb +101 -0
  58. data/test/unit/strategies/test_strategy_test.rb +76 -0
  59. metadata +134 -0
@@ -0,0 +1,44 @@
1
+ require File.expand_path("../../../test_helper", __FILE__)
2
+
3
+ describe Flipflop::Strategies::DefaultStrategy do
4
+ before do
5
+ Flipflop.configure do
6
+ feature :one, default: true
7
+ feature :two
8
+ end
9
+ end
10
+
11
+ describe "with defaults" do
12
+ subject do
13
+ Flipflop::Strategies::DefaultStrategy.new.freeze
14
+ end
15
+
16
+ it "should have default name" do
17
+ assert_equal "default", subject.name
18
+ end
19
+
20
+ it "should have no default description" do
21
+ assert_equal "Uses feature default status.", subject.description
22
+ end
23
+
24
+ it "should not be switchable" do
25
+ assert_equal false, subject.switchable?
26
+ end
27
+
28
+ it "should have unique key" do
29
+ assert_match /^\d+$/, subject.key
30
+ end
31
+
32
+ describe "with explicitly defaulted feature" do
33
+ it "should have feature enabled" do
34
+ assert_equal true, subject.enabled?(:one)
35
+ end
36
+ end
37
+
38
+ describe "with implicitly defaulted feature" do
39
+ it "should not have feature enabled" do
40
+ assert_equal false, subject.enabled?(:two)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,137 @@
1
+ require File.expand_path("../../../test_helper", __FILE__)
2
+
3
+ describe Flipflop::Strategies::LambdaStrategy do
4
+ subject do
5
+ Flipflop::Strategies::LambdaStrategy.new.freeze
6
+ end
7
+
8
+ describe "with defaults" do
9
+ it "should have default name" do
10
+ assert_equal "lambda", subject.name
11
+ end
12
+
13
+ it "should not have default description" do
14
+ assert_equal "Resolves feature settings with custom code.",
15
+ subject.description
16
+ end
17
+
18
+ it "should not be switchable" do
19
+ assert_equal false, subject.switchable?
20
+ end
21
+
22
+ it "should have unique key" do
23
+ assert_match /^\d+$/, subject.key
24
+ end
25
+ end
26
+
27
+ describe "with lambda" do
28
+ attr_accessor :features
29
+
30
+ before do
31
+ self.features = {}
32
+ end
33
+
34
+ subject do
35
+ features = self.features
36
+ Flipflop::Strategies::LambdaStrategy.new(lambda: ->(feature) { features[feature] }).freeze
37
+ end
38
+
39
+ describe "with enabled feature" do
40
+ before do
41
+ features[:one] = true
42
+ end
43
+
44
+ it "should have feature enabled" do
45
+ assert_equal true, subject.enabled?(:one)
46
+ end
47
+ end
48
+
49
+ describe "with disabled feature" do
50
+ before do
51
+ features[:two] = false
52
+ end
53
+
54
+ it "should not have feature enabled" do
55
+ assert_equal false, subject.enabled?(:two)
56
+ end
57
+ end
58
+
59
+ describe "with unknown feature" do
60
+ it "should not know feature" do
61
+ assert_nil subject.enabled?(:three)
62
+ end
63
+ end
64
+ end
65
+
66
+ describe "with request lambda" do
67
+ subject do
68
+ Flipflop::Strategies::LambdaStrategy.new(lambda: ->(feature) {
69
+ request.params[feature]
70
+ }).freeze
71
+ end
72
+
73
+ before do
74
+ Flipflop::Strategies::AbstractStrategy::RequestInterceptor.request = create_request
75
+ end
76
+
77
+ after do
78
+ Flipflop::Strategies::AbstractStrategy::RequestInterceptor.request = nil
79
+ end
80
+
81
+ describe "with enabled feature" do
82
+ before do
83
+ subject.send(:request).params[:one] = true
84
+ end
85
+
86
+ it "should have feature enabled" do
87
+ assert_equal true, subject.enabled?(:one)
88
+ end
89
+ end
90
+ end
91
+
92
+ describe "with non conforming parameters" do
93
+ subject do
94
+ Flipflop::Strategies::LambdaStrategy.new(lambda: ->() { }).freeze
95
+ end
96
+
97
+ it "should raise error" do
98
+ assert_raises Flipflop::StrategyError do
99
+ subject
100
+ end
101
+ end
102
+
103
+ it "should raise with message" do
104
+ message = nil
105
+ begin
106
+ subject
107
+ rescue => err
108
+ message = err.message
109
+ end
110
+ assert_equal "Strategy 'lambda' has lambda with arity 0, expected 1 or -1.", message
111
+ end
112
+ end
113
+
114
+ describe "with non conforming return value" do
115
+ subject do
116
+ Flipflop::Strategies::LambdaStrategy.new(lambda: ->(feature) {
117
+ return feature
118
+ }).freeze
119
+ end
120
+
121
+ it "should raise error" do
122
+ assert_raises Flipflop::StrategyError do
123
+ subject.enabled?(:one)
124
+ end
125
+ end
126
+
127
+ it "should raise with message" do
128
+ message = nil
129
+ begin
130
+ subject.enabled?(:one)
131
+ rescue => err
132
+ message = err.message
133
+ end
134
+ assert_equal "Strategy 'lambda' returned invalid result :one for feature 'one'.", message
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,70 @@
1
+ require File.expand_path("../../../test_helper", __FILE__)
2
+
3
+ describe Flipflop::Strategies::QueryStringStrategy do
4
+ subject do
5
+ Flipflop::Strategies::QueryStringStrategy.new.freeze
6
+ end
7
+
8
+ describe "in request context" do
9
+ before do
10
+ Flipflop::Strategies::AbstractStrategy::RequestInterceptor.request = create_request
11
+ end
12
+
13
+ after do
14
+ Flipflop::Strategies::AbstractStrategy::RequestInterceptor.request = nil
15
+ end
16
+
17
+ it "should have default name" do
18
+ assert_equal "query_string", subject.name
19
+ end
20
+
21
+ it "should not have default description" do
22
+ assert_equal "Interprets query string parameters as features.",
23
+ subject.description
24
+ end
25
+
26
+ it "should not be switchable" do
27
+ assert_equal false, subject.switchable?
28
+ end
29
+
30
+ it "should have unique key" do
31
+ assert_match /^\d+$/, subject.key
32
+ end
33
+
34
+ describe "with enabled feature" do
35
+ before do
36
+ subject.send(:request).params[:one] = "1"
37
+ end
38
+
39
+ it "should have feature enabled" do
40
+ assert_equal true, subject.enabled?(:one)
41
+ end
42
+ end
43
+
44
+ describe "with disabled feature" do
45
+ before do
46
+ subject.send(:request).params[:two] = "0"
47
+ end
48
+
49
+ it "should not have feature enabled" do
50
+ assert_equal false, subject.enabled?(:two)
51
+ end
52
+ end
53
+
54
+ describe "with unknown feature" do
55
+ it "should not know feature" do
56
+ assert_nil subject.enabled?(:three)
57
+ end
58
+ end
59
+ end
60
+
61
+ describe "outside request context" do
62
+ it "should not know feature" do
63
+ assert_nil subject.enabled?(:one)
64
+ end
65
+
66
+ it "should not be switchable" do
67
+ assert_equal false, subject.switchable?
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,101 @@
1
+ require File.expand_path("../../../test_helper", __FILE__)
2
+
3
+ describe Flipflop::Strategies::SessionStrategy do
4
+ subject do
5
+ Flipflop::Strategies::SessionStrategy.new.freeze
6
+ end
7
+
8
+ describe "in request context" do
9
+ before do
10
+ Flipflop::Strategies::AbstractStrategy::RequestInterceptor.request = create_request
11
+ end
12
+
13
+ after do
14
+ Flipflop::Strategies::AbstractStrategy::RequestInterceptor.request = nil
15
+ end
16
+
17
+ it "should have default name" do
18
+ assert_equal "session", subject.name
19
+ end
20
+
21
+ it "should have default description" do
22
+ assert_equal "Stores features in the user session. Applies to current user.",
23
+ subject.description
24
+ end
25
+
26
+ it "should be switchable" do
27
+ assert_equal true, subject.switchable?
28
+ end
29
+
30
+ it "should have unique key" do
31
+ assert_match /^\d+$/, subject.key
32
+ end
33
+
34
+ describe "with enabled feature" do
35
+ before do
36
+ subject.send(:request).session[:one] = true
37
+ end
38
+
39
+ it "should have feature enabled" do
40
+ assert_equal true, subject.enabled?(:one)
41
+ end
42
+
43
+ it "should be able to switch feature off" do
44
+ subject.switch!(:one, false)
45
+ assert_equal false, subject.enabled?(:one)
46
+ end
47
+
48
+ it "should be able to clear feature" do
49
+ subject.clear!(:one)
50
+ assert_nil subject.enabled?(:one)
51
+ end
52
+ end
53
+
54
+ describe "with disabled feature" do
55
+ before do
56
+ subject.send(:request).session[:two] = false
57
+ end
58
+
59
+ it "should not have feature enabled" do
60
+ assert_equal false, subject.enabled?(:two)
61
+ end
62
+
63
+ it "should be able to switch feature on" do
64
+ subject.switch!(:two, true)
65
+ assert_equal true, subject.enabled?(:two)
66
+ end
67
+
68
+ it "should be able to clear feature" do
69
+ subject.clear!(:two)
70
+ assert_nil subject.enabled?(:two)
71
+ end
72
+ end
73
+
74
+ describe "with unsessioned feature" do
75
+ it "should not know feature" do
76
+ assert_nil subject.enabled?(:three)
77
+ end
78
+
79
+ it "should be able to switch feature on" do
80
+ subject.switch!(:three, true)
81
+ assert_equal true, subject.enabled?(:three)
82
+ end
83
+ end
84
+ end
85
+
86
+ describe "outside request context" do
87
+ it "should not know feature" do
88
+ assert_nil subject.enabled?(:one)
89
+ end
90
+
91
+ it "should not be switchable" do
92
+ assert_equal false, subject.switchable?
93
+ end
94
+
95
+ it "should not be able to switch feature on" do
96
+ assert_raises Flipflop::StrategyError do
97
+ subject.switch!(:one, true)
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,76 @@
1
+ require File.expand_path("../../../test_helper", __FILE__)
2
+
3
+ describe Flipflop::Strategies::TestStrategy do
4
+ describe "with defaults" do
5
+ subject do
6
+ Flipflop::Strategies::TestStrategy.new.freeze
7
+ end
8
+
9
+ it "should have default name" do
10
+ assert_equal "test", subject.name
11
+ end
12
+
13
+ it "should not have default description" do
14
+ assert_nil subject.description
15
+ end
16
+
17
+ it "should be switchable" do
18
+ assert_equal true, subject.switchable?
19
+ end
20
+
21
+ it "should have unique key" do
22
+ assert_match /^\d+$/, subject.key
23
+ end
24
+
25
+ describe "with enabled feature" do
26
+ before do
27
+ subject.switch!(:one, true)
28
+ end
29
+
30
+ it "should have feature enabled" do
31
+ assert_equal true, subject.enabled?(:one)
32
+ end
33
+
34
+ it "should be able to switch feature off" do
35
+ subject.switch!(:one, false)
36
+ assert_equal false, subject.enabled?(:one)
37
+ end
38
+
39
+ it "should be able to clear feature" do
40
+ subject.clear!(:one)
41
+ assert_nil subject.enabled?(:one)
42
+ end
43
+ end
44
+
45
+ describe "with disabled feature" do
46
+ before do
47
+ subject.switch!(:two, false)
48
+ end
49
+
50
+ it "should not have feature enabled" do
51
+ assert_equal false, subject.enabled?(:two)
52
+ end
53
+
54
+ it "should be able to switch feature on" do
55
+ subject.switch!(:two, true)
56
+ assert_equal true, subject.enabled?(:two)
57
+ end
58
+
59
+ it "should be able to clear feature" do
60
+ subject.clear!(:two)
61
+ assert_nil subject.enabled?(:two)
62
+ end
63
+ end
64
+
65
+ describe "with unsaved feature" do
66
+ it "should not know feature" do
67
+ assert_nil subject.enabled?(:three)
68
+ end
69
+
70
+ it "should be able to switch feature on" do
71
+ subject.switch!(:three, true)
72
+ assert_equal true, subject.enabled?(:three)
73
+ end
74
+ end
75
+ end
76
+ end
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: flipflop
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Paul Annesley
8
+ - Rolf Timmermans
9
+ - Jippe Holwerda
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2016-03-17 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activesupport
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '4.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ! '>='
27
+ - !ruby/object:Gem::Version
28
+ version: '4.0'
29
+ - !ruby/object:Gem::Dependency
30
+ name: bootstrap
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ~>
34
+ - !ruby/object:Gem::Version
35
+ version: 4.0.0.alpha3
36
+ type: :runtime
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ~>
41
+ - !ruby/object:Gem::Version
42
+ version: 4.0.0.alpha3
43
+ description: Declarative API for specifying features, switchable in declaration, database
44
+ and cookies.
45
+ email:
46
+ - paul@annesley.cc
47
+ - rolftimmermans@voormedia.com
48
+ - jippeholwerda@voormedia.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - .travis.yml
55
+ - Gemfile
56
+ - LICENSE
57
+ - README.md
58
+ - Rakefile
59
+ - app/assets/stylesheets/flipflop.scss
60
+ - app/controllers/concerns/flipflop/environment_filters.rb
61
+ - app/controllers/flipflop/features_controller.rb
62
+ - app/controllers/flipflop/strategies_controller.rb
63
+ - app/models/flipflop/feature.rb
64
+ - app/views/flipflop/features/index.html.erb
65
+ - app/views/layouts/flipflop.html.erb
66
+ - config/routes.rb
67
+ - flipflop.gemspec
68
+ - lib/flipflop.rb
69
+ - lib/flipflop/configurable.rb
70
+ - lib/flipflop/engine.rb
71
+ - lib/flipflop/facade.rb
72
+ - lib/flipflop/feature_cache.rb
73
+ - lib/flipflop/feature_definition.rb
74
+ - lib/flipflop/feature_set.rb
75
+ - lib/flipflop/strategies/abstract_strategy.rb
76
+ - lib/flipflop/strategies/active_record_strategy.rb
77
+ - lib/flipflop/strategies/cookie_strategy.rb
78
+ - lib/flipflop/strategies/default_strategy.rb
79
+ - lib/flipflop/strategies/lambda_strategy.rb
80
+ - lib/flipflop/strategies/query_string_strategy.rb
81
+ - lib/flipflop/strategies/session_strategy.rb
82
+ - lib/flipflop/strategies/test_strategy.rb
83
+ - lib/flipflop/version.rb
84
+ - lib/generators/flipflop/features/USAGE
85
+ - lib/generators/flipflop/features/features_generator.rb
86
+ - lib/generators/flipflop/features/templates/features.rb
87
+ - lib/generators/flipflop/install/install_generator.rb
88
+ - lib/generators/flipflop/migration/USAGE
89
+ - lib/generators/flipflop/migration/migration_generator.rb
90
+ - lib/generators/flipflop/migration/templates/create_features.rb
91
+ - lib/generators/flipflop/routes/USAGE
92
+ - lib/generators/flipflop/routes/routes_generator.rb
93
+ - test/integration/app_test.rb
94
+ - test/integration/dashboard_test.rb
95
+ - test/test_helper.rb
96
+ - test/unit/configurable_test.rb
97
+ - test/unit/feature_cache_test.rb
98
+ - test/unit/feature_definition_test.rb
99
+ - test/unit/feature_set_test.rb
100
+ - test/unit/flipflop_test.rb
101
+ - test/unit/strategies/abstract_strategy_request_test.rb
102
+ - test/unit/strategies/abstract_strategy_test.rb
103
+ - test/unit/strategies/active_record_strategy_test.rb
104
+ - test/unit/strategies/cookie_strategy_test.rb
105
+ - test/unit/strategies/default_strategy_test.rb
106
+ - test/unit/strategies/lambda_strategy_test.rb
107
+ - test/unit/strategies/query_string_strategy_test.rb
108
+ - test/unit/strategies/session_strategy_test.rb
109
+ - test/unit/strategies/test_strategy_test.rb
110
+ homepage: https://github.com/voormedia/flipflop
111
+ licenses:
112
+ - MIT
113
+ metadata: {}
114
+ post_install_message:
115
+ rdoc_options: []
116
+ require_paths:
117
+ - lib
118
+ required_ruby_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ! '>='
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ required_rubygems_version: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - ! '>='
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ requirements: []
129
+ rubyforge_project:
130
+ rubygems_version: 2.4.5
131
+ signing_key:
132
+ specification_version: 4
133
+ summary: A feature flipflopper for Rails web applications.
134
+ test_files: []