flip_fab 0.0.1

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.
Files changed (109) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +5 -0
  3. data/Gemfile +16 -0
  4. data/Gemfile.lock +92 -0
  5. data/LICENSE.txt +9 -0
  6. data/README.md +168 -0
  7. data/example/rails_app/.gitignore +17 -0
  8. data/example/rails_app/Gemfile +36 -0
  9. data/example/rails_app/Gemfile.lock +178 -0
  10. data/example/rails_app/README.rdoc +28 -0
  11. data/example/rails_app/Rakefile +6 -0
  12. data/example/rails_app/app/assets/images/.keep +0 -0
  13. data/example/rails_app/app/assets/images/justin_beaver.jpg +0 -0
  14. data/example/rails_app/app/assets/images/regular_beaver.jpg +0 -0
  15. data/example/rails_app/app/assets/javascripts/application.js +16 -0
  16. data/example/rails_app/app/assets/javascripts/beavers.js.coffee +3 -0
  17. data/example/rails_app/app/assets/stylesheets/application.css +15 -0
  18. data/example/rails_app/app/assets/stylesheets/beavers.css.scss +3 -0
  19. data/example/rails_app/app/assets/stylesheets/scaffolds.css.scss +69 -0
  20. data/example/rails_app/app/controllers/application_controller.rb +5 -0
  21. data/example/rails_app/app/controllers/beavers_controller.rb +74 -0
  22. data/example/rails_app/app/controllers/concerns/.keep +0 -0
  23. data/example/rails_app/app/helpers/application_helper.rb +2 -0
  24. data/example/rails_app/app/helpers/beavers_helper.rb +2 -0
  25. data/example/rails_app/app/mailers/.keep +0 -0
  26. data/example/rails_app/app/models/.keep +0 -0
  27. data/example/rails_app/app/models/beaver.rb +2 -0
  28. data/example/rails_app/app/models/concerns/.keep +0 -0
  29. data/example/rails_app/app/views/beavers/_form.html.erb +21 -0
  30. data/example/rails_app/app/views/beavers/edit.html.erb +6 -0
  31. data/example/rails_app/app/views/beavers/index.html.erb +25 -0
  32. data/example/rails_app/app/views/beavers/index.json.jbuilder +4 -0
  33. data/example/rails_app/app/views/beavers/new.html.erb +5 -0
  34. data/example/rails_app/app/views/beavers/show.html.erb +9 -0
  35. data/example/rails_app/app/views/beavers/show.json.jbuilder +1 -0
  36. data/example/rails_app/app/views/layouts/application.html.erb +18 -0
  37. data/example/rails_app/bin/bundle +3 -0
  38. data/example/rails_app/bin/rails +4 -0
  39. data/example/rails_app/bin/rake +4 -0
  40. data/example/rails_app/config/application.rb +25 -0
  41. data/example/rails_app/config/boot.rb +4 -0
  42. data/example/rails_app/config/database.yml +22 -0
  43. data/example/rails_app/config/environment.rb +5 -0
  44. data/example/rails_app/config/environments/development.rb +83 -0
  45. data/example/rails_app/config/environments/test.rb +41 -0
  46. data/example/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  47. data/example/rails_app/config/initializers/cookies_serializer.rb +3 -0
  48. data/example/rails_app/config/initializers/filter_parameter_logging.rb +4 -0
  49. data/example/rails_app/config/initializers/flip_fab.rb +1 -0
  50. data/example/rails_app/config/initializers/inflections.rb +16 -0
  51. data/example/rails_app/config/initializers/mime_types.rb +4 -0
  52. data/example/rails_app/config/initializers/session_store.rb +3 -0
  53. data/example/rails_app/config/initializers/wrap_parameters.rb +14 -0
  54. data/example/rails_app/config/locales/en.yml +23 -0
  55. data/example/rails_app/config/rabbit_feed.yml +8 -0
  56. data/example/rails_app/config/routes.rb +58 -0
  57. data/example/rails_app/config/secrets.yml +18 -0
  58. data/example/rails_app/config/unicorn.rb +4 -0
  59. data/example/rails_app/config.ru +4 -0
  60. data/example/rails_app/db/migrate/20140424102400_create_beavers.rb +9 -0
  61. data/example/rails_app/db/schema.rb +22 -0
  62. data/example/rails_app/db/seeds.rb +7 -0
  63. data/example/rails_app/lib/assets/.keep +0 -0
  64. data/example/rails_app/lib/tasks/.keep +0 -0
  65. data/example/rails_app/log/.keep +0 -0
  66. data/example/rails_app/public/404.html +67 -0
  67. data/example/rails_app/public/422.html +67 -0
  68. data/example/rails_app/public/500.html +66 -0
  69. data/example/rails_app/public/favicon.ico +0 -0
  70. data/example/rails_app/public/robots.txt +5 -0
  71. data/example/rails_app/spec/rails_helper.rb +50 -0
  72. data/example/rails_app/spec/spec_helper.rb +8 -0
  73. data/example/rails_app/test/controllers/.keep +0 -0
  74. data/example/rails_app/test/controllers/beavers_controller_test.rb +49 -0
  75. data/example/rails_app/test/fixtures/.keep +0 -0
  76. data/example/rails_app/test/fixtures/beavers.yml +7 -0
  77. data/example/rails_app/test/helpers/.keep +0 -0
  78. data/example/rails_app/test/helpers/beavers_helper_test.rb +4 -0
  79. data/example/rails_app/test/integration/.keep +0 -0
  80. data/example/rails_app/test/mailers/.keep +0 -0
  81. data/example/rails_app/test/models/.keep +0 -0
  82. data/example/rails_app/test/models/beaver_test.rb +7 -0
  83. data/example/rails_app/test/test_helper.rb +13 -0
  84. data/flip_fab.gemspec +20 -0
  85. data/lib/flip_fab/contextual_feature.rb +83 -0
  86. data/lib/flip_fab/cookie_persistence.rb +52 -0
  87. data/lib/flip_fab/feature.rb +24 -0
  88. data/lib/flip_fab/features_by_name.rb +22 -0
  89. data/lib/flip_fab/helper.rb +8 -0
  90. data/lib/flip_fab/persistence.rb +19 -0
  91. data/lib/flip_fab/version.rb +3 -0
  92. data/lib/flip_fab.rb +24 -0
  93. data/spec/lib/flip_fab/contextual_feature_spec.rb +352 -0
  94. data/spec/lib/flip_fab/cookie_persistence.feature +50 -0
  95. data/spec/lib/flip_fab/cookie_persistence_spec.rb +90 -0
  96. data/spec/lib/flip_fab/feature_spec.rb +86 -0
  97. data/spec/lib/flip_fab/features_by_name_spec.rb +34 -0
  98. data/spec/lib/flip_fab/helper.feature +31 -0
  99. data/spec/lib/flip_fab/helper_spec.rb +90 -0
  100. data/spec/lib/flip_fab/persistence_spec.rb +32 -0
  101. data/spec/lib/flip_fab.feature +10 -0
  102. data/spec/lib/flip_fab_spec.rb +47 -0
  103. data/spec/spec_helper.rb +93 -0
  104. data/spec/support/test_app.rb +16 -0
  105. data/spec/support/test_context.rb +10 -0
  106. data/spec/support/test_multiple_persistence.rb +14 -0
  107. data/spec/support/test_persistence.rb +14 -0
  108. data/spec/support/test_rack_context.rb +15 -0
  109. metadata +168 -0
@@ -0,0 +1,90 @@
1
+ require 'rack/test'
2
+
3
+ module FlipFab
4
+ describe Helper do
5
+ include Rack::Test::Methods
6
+ let(:app) { TestApp.new }
7
+ after { FlipFab.features.clear }
8
+
9
+ it 'runs the feature' do
10
+ feature
11
+ end
12
+
13
+ step 'there is a feature with a default state of :default_state' do |default_state|
14
+ FlipFab.define_feature :example_feature, { default: default_state.to_sym, persistence_adapters: [TestPersistence] }
15
+ end
16
+
17
+ step 'there are two contexts' do
18
+ @first_context = TestContext.new
19
+ @second_context = TestContext.new
20
+ end
21
+
22
+ step 'the feature is :expected_state_in_first_context in the first context, :expected_state_in_second_context in the second context' do |expected_state_in_first_context, expected_state_in_second_context|
23
+ expect(@first_context.features[:example_feature].enabled?).to eq(expected_state_in_first_context == 'enabled')
24
+ expect(@second_context.features[:example_feature].enabled?).to eq(expected_state_in_second_context == 'enabled')
25
+ end
26
+
27
+ step 'I :enable_or_disable the feature in the first context' do |enable_or_disable|
28
+ @first_context.features[:example_feature].send(enable_or_disable.to_sym)
29
+ end
30
+
31
+ step 'there is a feature with a default state of :default_state with cookie persistence' do |default_state|
32
+ FlipFab.define_feature :example_feature, { default: default_state.to_sym }
33
+ end
34
+
35
+ step 'I override the state in the URL parameters with :overridden_state' do |overridden_state|
36
+ get "/?example_feature=#{overridden_state}"
37
+ end
38
+
39
+ step 'the feature is :state for the user' do |state|
40
+ expect(app.contextual_features[:example_feature].enabled?).to eq(state=='enabled')
41
+ end
42
+
43
+ step 'I :enable_or_disable the feature for the user' do |enable_or_disable|
44
+ app.contextual_features[:example_feature].send(enable_or_disable.to_sym)
45
+ end
46
+
47
+ describe '#features' do
48
+ let(:params) {{}}
49
+ let(:feature_states) {{ example_feature: :enabled }}
50
+ let(:context) { (TestContext.new feature_states, params) }
51
+ before { FlipFab.define_feature :example_feature, { persistence_adapters: [TestPersistence] } }
52
+ subject { context.features }
53
+
54
+ it 'maps the features to contextual features by feature name' do
55
+ expect(subject[:example_feature]).to be_a ContextualFeature
56
+ end
57
+
58
+ it 'is a FeaturesByName' do
59
+ expect(subject).to be_a FeaturesByName
60
+ end
61
+
62
+ context 'when the feature is overridden in the params' do
63
+ let(:params) {{'example_feature' => 'disabled'}}
64
+
65
+ it 'applies the override to the feature' do
66
+ expect(subject[:example_feature].disabled?).to be_truthy
67
+ end
68
+
69
+ it 'prevents the feature\'s state from being changed' do
70
+ expect{ subject[:example_feature].enable }.not_to change{ subject[:example_feature].enabled? }.from(false)
71
+ end
72
+ end
73
+
74
+ context 'passing the context to the feature' do
75
+
76
+ it 'feature toggling is applied to the context' do
77
+ expect{ subject[:example_feature].disable }.to change{ subject[:example_feature].enabled? }.from(true).to(false)
78
+ end
79
+
80
+ it 'feature toggling is persisted in the context' do
81
+ expect{ subject[:example_feature].disable }.to change{ feature_states }.from({ example_feature: :enabled }).to({ example_feature: :disabled })
82
+ end
83
+ end
84
+
85
+ it 'caches the features' do
86
+ expect(subject).to eq(context.features)
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,32 @@
1
+ module FlipFab
2
+ describe Persistence do
3
+ let(:feature_name) { :example_test }
4
+ let(:context) { double(:context) }
5
+ subject { described_class.new feature_name, context }
6
+
7
+ describe '.new' do
8
+
9
+ it 'assigns the feature name' do
10
+ expect(subject.feature_name).to eq(:example_test)
11
+ end
12
+
13
+ it 'assigns the context' do
14
+ expect(subject.context).to eq(context)
15
+ end
16
+ end
17
+
18
+ describe '#read' do
19
+
20
+ it 'is not implemented' do
21
+ expect{ subject.read }.to raise_error NotImplementedError
22
+ end
23
+ end
24
+
25
+ describe '#write' do
26
+
27
+ it 'is not implemented' do
28
+ expect{ subject.write feature_name }.to raise_error NotImplementedError
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,10 @@
1
+ Feature: Feature flipping at an application level
2
+
3
+ Scenario Outline: Features can be declared as enabled or disabled and remain as such
4
+ When I define a feature that is '<enabled_or_disabled>'
5
+ Then the feature is '<enabled_or_disabled>'
6
+
7
+ Examples:
8
+ | enabled_or_disabled |
9
+ | enabled |
10
+ | disabled |
@@ -0,0 +1,47 @@
1
+ describe FlipFab do
2
+ let(:name) { :example_feature }
3
+
4
+ it 'runs the feature' do
5
+ feature
6
+ end
7
+
8
+ step 'I define a feature that is :enabled_or_disabled' do |enabled_or_disabled|
9
+ described_class.define_feature name, { default: enabled_or_disabled.to_sym }
10
+ end
11
+
12
+ step 'the feature is :enabled_or_disabled' do |enabled_or_disabled|
13
+ expect(described_class.features[name].enabled?).to eq(enabled_or_disabled == 'enabled')
14
+ end
15
+
16
+ it 'initializes features' do
17
+ expect(described_class.features).to be_a FlipFab::FeaturesByName
18
+ end
19
+
20
+ context '.define_feature' do
21
+ subject{ described_class.define_feature name }
22
+ after{ described_class.features.clear }
23
+
24
+ it 'returns the feature' do
25
+ expect(subject).to be_a FlipFab::Feature
26
+ expect(subject.name).to eq(:example_feature)
27
+ end
28
+
29
+ context 'when the feature exists' do
30
+
31
+ it 'overwrites the existing feature' do
32
+ existing_feature = described_class.define_feature name
33
+ expect{ subject }.not_to change{ described_class.features.count }.from(1)
34
+ expect(subject).not_to eq(existing_feature)
35
+ end
36
+ end
37
+
38
+ context 'when the feature does not exist' do
39
+
40
+ it 'saves the feature' do
41
+ expect{ subject }.to change{ described_class.features.count }.from(0).to(1)
42
+ expected_feature = subject
43
+ expect(described_class.features[:example_feature]).to eq(expected_feature)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,93 @@
1
+ require 'flip_fab'
2
+
3
+ Dir['./spec/support/**/*.rb'].sort.each { |f| require f}
4
+
5
+ # This file was generated by the `rspec --init` command. Conventionally, all
6
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
7
+ # The generated `.rspec` file contains `--require spec_helper` which will cause this
8
+ # file to always be loaded, without a need to explicitly require it in any files.
9
+ #
10
+ # Given that it is always loaded, you are encouraged to keep this file as
11
+ # light-weight as possible. Requiring heavyweight dependencies from this file
12
+ # will add to the boot time of your test suite on EVERY test run, even for an
13
+ # individual file that may not need all of that loaded. Instead, consider making
14
+ # a separate helper file that requires the additional dependencies and performs
15
+ # the additional setup, and require it from the spec files that actually need it.
16
+ #
17
+ # The `.rspec` file also contains a few flags that are not defaults but that
18
+ # users commonly want.
19
+ #
20
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
21
+ RSpec.configure do |config|
22
+ # rspec-expectations config goes here. You can use an alternate
23
+ # assertion/expectation library such as wrong or the stdlib/minitest
24
+ # assertions if you prefer.
25
+ config.expect_with :rspec do |expectations|
26
+ # This option will default to `true` in RSpec 4. It makes the `description`
27
+ # and `failure_message` of custom matchers include text for helper methods
28
+ # defined using `chain`, e.g.:
29
+ # be_bigger_than(2).and_smaller_than(4).description
30
+ # # => "be bigger than 2 and smaller than 4"
31
+ # ...rather than:
32
+ # # => "be bigger than 2"
33
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
34
+ end
35
+
36
+ # rspec-mocks config goes here. You can use an alternate test double
37
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
38
+ config.mock_with :rspec do |mocks|
39
+ # Prevents you from mocking or stubbing a method that does not exist on
40
+ # a real object. This is generally recommended, and will default to
41
+ # `true` in RSpec 4.
42
+ mocks.verify_partial_doubles = true
43
+ end
44
+
45
+ # The settings below are suggested to provide a good initial experience
46
+ # with RSpec, but feel free to customize to your heart's content.
47
+ =begin
48
+ # These two settings work together to allow you to limit a spec run
49
+ # to individual examples or groups you care about by tagging them with
50
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
51
+ # get run.
52
+ config.filter_run :focus
53
+ config.run_all_when_everything_filtered = true
54
+
55
+ # Limits the available syntax to the non-monkey patched syntax that is recommended.
56
+ # For more details, see:
57
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
58
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
59
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
60
+ config.disable_monkey_patching!
61
+
62
+ # This setting enables warnings. It's recommended, but in some cases may
63
+ # be too noisy due to issues in dependencies.
64
+ config.warnings = true
65
+
66
+ # Many RSpec users commonly either run the entire suite or an individual
67
+ # file, and it's useful to allow more verbose output when running an
68
+ # individual spec file.
69
+ if config.files_to_run.one?
70
+ # Use the documentation formatter for detailed output,
71
+ # unless a formatter has already been configured
72
+ # (e.g. via a command-line flag).
73
+ config.default_formatter = 'doc'
74
+ end
75
+
76
+ # Print the 10 slowest examples and example groups at the
77
+ # end of the spec run, to help surface which specs are running
78
+ # particularly slow.
79
+ config.profile_examples = 10
80
+
81
+ # Run specs in random order to surface order dependencies. If you find an
82
+ # order dependency and want to debug it, you can fix the order by providing
83
+ # the seed, which is printed after each run.
84
+ # --seed 1234
85
+ config.order = :random
86
+
87
+ # Seed global randomization in this process using the `--seed` CLI option.
88
+ # Setting this allows you to use `--seed` to deterministically reproduce
89
+ # test failures related to randomization by passing the same `--seed` value
90
+ # as the one that triggered the failure.
91
+ Kernel.srand config.seed
92
+ =end
93
+ end
@@ -0,0 +1,16 @@
1
+ class TestApp
2
+ include FlipFab::Helper
3
+
4
+ attr_reader :request, :response, :params, :contextual_features
5
+
6
+ def call env
7
+ @request = Rack::Request.new env
8
+ @response = Rack::Response.new
9
+ @params = request.params
10
+
11
+ @contextual_features = features
12
+
13
+ request.cookies.each{|k,v| response.set_cookie k, v }
14
+ [response.status, response.header, response.body]
15
+ end
16
+ end
@@ -0,0 +1,10 @@
1
+ class TestContext
2
+ include FlipFab::Helper
3
+
4
+ attr_reader :feature_states, :params
5
+
6
+ def initialize feature_states={}, params={}
7
+ @feature_states = feature_states
8
+ @params = params
9
+ end
10
+ end
@@ -0,0 +1,14 @@
1
+ class TestMultiplePersistence < FlipFab::Persistence
2
+
3
+ def initialize feature_name, context
4
+ super
5
+ end
6
+
7
+ def read
8
+ context.feature_states[:different_example_feature]
9
+ end
10
+
11
+ def write value
12
+ context.feature_states[:different_example_feature] = value
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ class TestPersistence < FlipFab::Persistence
2
+
3
+ def initialize feature_name, context
4
+ super
5
+ end
6
+
7
+ def read
8
+ context.feature_states[feature_name]
9
+ end
10
+
11
+ def write state
12
+ context.feature_states[feature_name] = state
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ class TestRackContext
2
+ include FlipFab::Helper
3
+
4
+ attr_reader :request, :response
5
+
6
+ def initialize cookies, host
7
+ @request = Rack::Request.new({ 'HTTP_COOKIE' => cookies, 'HTTP_HOST' => host })
8
+ @response = Rack::Response.new
9
+ request.cookies.each{|k,v| response.set_cookie k, v }
10
+ end
11
+
12
+ def response_cookies
13
+ response.header['Set-Cookie']
14
+ end
15
+ end
metadata ADDED
@@ -0,0 +1,168 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: flip_fab
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Simply Business
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-24 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A gem providing persistent, per-user feature flipping to Rack applications.
14
+ email:
15
+ - tech@simplybusiness.co.uk
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".rspec"
21
+ - Gemfile
22
+ - Gemfile.lock
23
+ - LICENSE.txt
24
+ - README.md
25
+ - example/rails_app/.gitignore
26
+ - example/rails_app/Gemfile
27
+ - example/rails_app/Gemfile.lock
28
+ - example/rails_app/README.rdoc
29
+ - example/rails_app/Rakefile
30
+ - example/rails_app/app/assets/images/.keep
31
+ - example/rails_app/app/assets/images/justin_beaver.jpg
32
+ - example/rails_app/app/assets/images/regular_beaver.jpg
33
+ - example/rails_app/app/assets/javascripts/application.js
34
+ - example/rails_app/app/assets/javascripts/beavers.js.coffee
35
+ - example/rails_app/app/assets/stylesheets/application.css
36
+ - example/rails_app/app/assets/stylesheets/beavers.css.scss
37
+ - example/rails_app/app/assets/stylesheets/scaffolds.css.scss
38
+ - example/rails_app/app/controllers/application_controller.rb
39
+ - example/rails_app/app/controllers/beavers_controller.rb
40
+ - example/rails_app/app/controllers/concerns/.keep
41
+ - example/rails_app/app/helpers/application_helper.rb
42
+ - example/rails_app/app/helpers/beavers_helper.rb
43
+ - example/rails_app/app/mailers/.keep
44
+ - example/rails_app/app/models/.keep
45
+ - example/rails_app/app/models/beaver.rb
46
+ - example/rails_app/app/models/concerns/.keep
47
+ - example/rails_app/app/views/beavers/_form.html.erb
48
+ - example/rails_app/app/views/beavers/edit.html.erb
49
+ - example/rails_app/app/views/beavers/index.html.erb
50
+ - example/rails_app/app/views/beavers/index.json.jbuilder
51
+ - example/rails_app/app/views/beavers/new.html.erb
52
+ - example/rails_app/app/views/beavers/show.html.erb
53
+ - example/rails_app/app/views/beavers/show.json.jbuilder
54
+ - example/rails_app/app/views/layouts/application.html.erb
55
+ - example/rails_app/bin/bundle
56
+ - example/rails_app/bin/rails
57
+ - example/rails_app/bin/rake
58
+ - example/rails_app/config.ru
59
+ - example/rails_app/config/application.rb
60
+ - example/rails_app/config/boot.rb
61
+ - example/rails_app/config/database.yml
62
+ - example/rails_app/config/environment.rb
63
+ - example/rails_app/config/environments/development.rb
64
+ - example/rails_app/config/environments/test.rb
65
+ - example/rails_app/config/initializers/backtrace_silencers.rb
66
+ - example/rails_app/config/initializers/cookies_serializer.rb
67
+ - example/rails_app/config/initializers/filter_parameter_logging.rb
68
+ - example/rails_app/config/initializers/flip_fab.rb
69
+ - example/rails_app/config/initializers/inflections.rb
70
+ - example/rails_app/config/initializers/mime_types.rb
71
+ - example/rails_app/config/initializers/session_store.rb
72
+ - example/rails_app/config/initializers/wrap_parameters.rb
73
+ - example/rails_app/config/locales/en.yml
74
+ - example/rails_app/config/rabbit_feed.yml
75
+ - example/rails_app/config/routes.rb
76
+ - example/rails_app/config/secrets.yml
77
+ - example/rails_app/config/unicorn.rb
78
+ - example/rails_app/db/migrate/20140424102400_create_beavers.rb
79
+ - example/rails_app/db/schema.rb
80
+ - example/rails_app/db/seeds.rb
81
+ - example/rails_app/lib/assets/.keep
82
+ - example/rails_app/lib/tasks/.keep
83
+ - example/rails_app/log/.keep
84
+ - example/rails_app/public/404.html
85
+ - example/rails_app/public/422.html
86
+ - example/rails_app/public/500.html
87
+ - example/rails_app/public/favicon.ico
88
+ - example/rails_app/public/robots.txt
89
+ - example/rails_app/spec/rails_helper.rb
90
+ - example/rails_app/spec/spec_helper.rb
91
+ - example/rails_app/test/controllers/.keep
92
+ - example/rails_app/test/controllers/beavers_controller_test.rb
93
+ - example/rails_app/test/fixtures/.keep
94
+ - example/rails_app/test/fixtures/beavers.yml
95
+ - example/rails_app/test/helpers/.keep
96
+ - example/rails_app/test/helpers/beavers_helper_test.rb
97
+ - example/rails_app/test/integration/.keep
98
+ - example/rails_app/test/mailers/.keep
99
+ - example/rails_app/test/models/.keep
100
+ - example/rails_app/test/models/beaver_test.rb
101
+ - example/rails_app/test/test_helper.rb
102
+ - flip_fab.gemspec
103
+ - lib/flip_fab.rb
104
+ - lib/flip_fab/contextual_feature.rb
105
+ - lib/flip_fab/cookie_persistence.rb
106
+ - lib/flip_fab/feature.rb
107
+ - lib/flip_fab/features_by_name.rb
108
+ - lib/flip_fab/helper.rb
109
+ - lib/flip_fab/persistence.rb
110
+ - lib/flip_fab/version.rb
111
+ - spec/lib/flip_fab.feature
112
+ - spec/lib/flip_fab/contextual_feature_spec.rb
113
+ - spec/lib/flip_fab/cookie_persistence.feature
114
+ - spec/lib/flip_fab/cookie_persistence_spec.rb
115
+ - spec/lib/flip_fab/feature_spec.rb
116
+ - spec/lib/flip_fab/features_by_name_spec.rb
117
+ - spec/lib/flip_fab/helper.feature
118
+ - spec/lib/flip_fab/helper_spec.rb
119
+ - spec/lib/flip_fab/persistence_spec.rb
120
+ - spec/lib/flip_fab_spec.rb
121
+ - spec/spec_helper.rb
122
+ - spec/support/test_app.rb
123
+ - spec/support/test_context.rb
124
+ - spec/support/test_multiple_persistence.rb
125
+ - spec/support/test_persistence.rb
126
+ - spec/support/test_rack_context.rb
127
+ homepage: https://github.com/simplybusiness/flip_fab
128
+ licenses:
129
+ - MIT
130
+ metadata: {}
131
+ post_install_message:
132
+ rdoc_options: []
133
+ require_paths:
134
+ - lib
135
+ required_ruby_version: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ required_rubygems_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ requirements: []
146
+ rubyforge_project:
147
+ rubygems_version: 2.0.14
148
+ signing_key:
149
+ specification_version: 4
150
+ summary: A gem providing persistent, per-user feature flipping to Rack applications.
151
+ test_files:
152
+ - spec/lib/flip_fab.feature
153
+ - spec/lib/flip_fab/contextual_feature_spec.rb
154
+ - spec/lib/flip_fab/cookie_persistence.feature
155
+ - spec/lib/flip_fab/cookie_persistence_spec.rb
156
+ - spec/lib/flip_fab/feature_spec.rb
157
+ - spec/lib/flip_fab/features_by_name_spec.rb
158
+ - spec/lib/flip_fab/helper.feature
159
+ - spec/lib/flip_fab/helper_spec.rb
160
+ - spec/lib/flip_fab/persistence_spec.rb
161
+ - spec/lib/flip_fab_spec.rb
162
+ - spec/spec_helper.rb
163
+ - spec/support/test_app.rb
164
+ - spec/support/test_context.rb
165
+ - spec/support/test_multiple_persistence.rb
166
+ - spec/support/test_persistence.rb
167
+ - spec/support/test_rack_context.rb
168
+ has_rdoc: