flip_fab 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +29 -0
  3. data/example/rails_app/Gemfile +2 -19
  4. data/example/rails_app/app/assets/javascripts/application.js +0 -1
  5. data/example/rails_app/app/controllers/beavers_controller.rb +11 -12
  6. data/example/rails_app/bin/rails +1 -1
  7. data/example/rails_app/config.ru +1 -1
  8. data/example/rails_app/config/environments/development.rb +1 -1
  9. data/example/rails_app/config/environments/test.rb +2 -2
  10. data/example/rails_app/config/initializers/cookies_serializer.rb +1 -1
  11. data/example/rails_app/db/schema.rb +5 -7
  12. data/example/rails_app/spec/rails_helper.rb +2 -2
  13. data/example/rails_app/spec/spec_helper.rb +0 -1
  14. data/example/rails_app/test/controllers/beavers_controller_test.rb +12 -12
  15. data/flip_fab.gemspec +9 -8
  16. data/lib/flip_fab.rb +3 -3
  17. data/lib/flip_fab/contextual_feature.rb +11 -17
  18. data/lib/flip_fab/cookie_persistence.rb +11 -16
  19. data/lib/flip_fab/feature.rb +2 -3
  20. data/lib/flip_fab/features_by_name.rb +4 -4
  21. data/lib/flip_fab/helper.rb +0 -1
  22. data/lib/flip_fab/persistence.rb +2 -3
  23. data/lib/flip_fab/version.rb +1 -1
  24. data/script/cibuild +10 -0
  25. data/spec/lib/flip_fab/contextual_feature_spec.rb +47 -56
  26. data/spec/lib/flip_fab/cookie_persistence_spec.rb +40 -43
  27. data/spec/lib/flip_fab/feature_spec.rb +6 -9
  28. data/spec/lib/flip_fab/features_by_name_spec.rb +3 -6
  29. data/spec/lib/flip_fab/helper_spec.rb +35 -38
  30. data/spec/lib/flip_fab/persistence_spec.rb +2 -5
  31. data/spec/lib/flip_fab_spec.rb +11 -15
  32. data/spec/spec_helper.rb +47 -49
  33. data/spec/support/test_app.rb +2 -2
  34. data/spec/support/test_context.rb +1 -1
  35. data/spec/support/test_multiple_persistence.rb +2 -3
  36. data/spec/support/test_persistence.rb +2 -3
  37. data/spec/support/test_rack_context.rb +3 -3
  38. metadata +38 -25
  39. data/example/rails_app/README.rdoc +0 -28
  40. data/example/rails_app/config/rabbit_feed.yml +0 -8
  41. data/example/rails_app/config/unicorn.rb +0 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b178cc3f97fb1405b48a143a52b83bc205891f57
4
- data.tar.gz: 78b6d508d839d2dfdfa955645f98c71164bd0a2f
3
+ metadata.gz: 41ce116c1d345217c1e9b1eb22afb50ae36cf0b5
4
+ data.tar.gz: 30446aedb0dab73151be9b4bb1744b9dbad8d15e
5
5
  SHA512:
6
- metadata.gz: 55be299324bf08e81c806491487d3c81e76aa98c61d3601cf3a8c3b3be61bea7e5c044e8e7e65a263e183accac1423870c1d584a0af47f826949729b4fa3416d
7
- data.tar.gz: 13a8bebb70660b3987caf0aa797518a22f62b0b32eac6e055d8dc15ef9435e88dfa46417229c9528af2187bb6636aaa203363a995bcffc0bab176e0edb737271
6
+ metadata.gz: f39f8b192ab5a888ef29d325ee94de4eb88f86a78b09b76ef872a61e3895ff1018ce1223185cb8cd53df92edfb34823ed05106ca2b2792f23b15ea334a21a26f
7
+ data.tar.gz: 8758cb9740f64f0abe4035ef0048c000e9e671fc88ea52cf36f81b37ff03f09948c21e77f80f71e23dc1952c03e0c9d759e9ca8ebf3846f01843ec0734f67e19
@@ -0,0 +1,29 @@
1
+ AllCops:
2
+ DisplayCopNames: true
3
+ DisplayStyleGuide: true
4
+
5
+ Lint/EndAlignment:
6
+ Enabled: true
7
+
8
+ Lint/UnusedMethodArgument:
9
+ Exclude:
10
+ - 'lib/flip_fab/persistence.rb'
11
+
12
+ Metrics/AbcSize:
13
+ Exclude:
14
+ - 'spec/support/test_app.rb'
15
+
16
+ Metrics/LineLength:
17
+ Enabled: false
18
+
19
+ Metrics/ModuleLength:
20
+ Exclude:
21
+ - 'spec/lib/flip_fab/contextual_feature_spec.rb'
22
+
23
+ Style/ClassAndModuleChildren:
24
+ Exclude:
25
+ - 'example/rails_app/test/test_helper.rb'
26
+
27
+ Style/Documentation:
28
+ Enabled: false
29
+
@@ -1,7 +1,7 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
4
- gem 'rails', '~> 4.2'
4
+ gem 'rails', '~> 5.0'
5
5
  # Use sqlite3 as the database for Active Record
6
6
  gem 'sqlite3'
7
7
  # Use SCSS for stylesheets
@@ -10,27 +10,10 @@ gem 'sass-rails'
10
10
  gem 'uglifier', '>= 1.3.0'
11
11
  # Use CoffeeScript for .js.coffee assets and views
12
12
  gem 'coffee-rails'
13
- # See https://github.com/sstephenson/execjs#readme for more supported runtimes
14
- # gem 'therubyracer', platforms: :ruby
15
-
16
13
  # Use jquery as the JavaScript library
17
14
  gem 'jquery-rails'
18
- # Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
19
- gem 'turbolinks'
20
- # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
21
- gem 'jbuilder', '~> 2.0'
22
- # bundle exec rake doc:rails generates the API under doc/api.
23
- gem 'sdoc', '~> 0.4.0', group: :doc
24
-
25
- # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
26
- gem 'spring', group: :development
27
-
28
- # Use unicorn as the app server
29
- gem 'unicorn'
30
-
31
- # Use Capistrano for deployment
32
- # gem 'capistrano-rails', group: :development
33
15
 
34
16
  gem 'flip_fab', path: '../../'
35
17
 
18
+ gem 'rails-controller-testing', group: :test
36
19
  gem 'rspec-rails', group: :test
@@ -12,5 +12,4 @@
12
12
  //
13
13
  //= require jquery
14
14
  //= require jquery_ujs
15
- //= require turbolinks
16
15
  //= require_tree .
@@ -9,8 +9,7 @@ class BeaversController < ApplicationController
9
9
 
10
10
  # GET /beavers/1
11
11
  # GET /beavers/1.json
12
- def show
13
- end
12
+ def show; end
14
13
 
15
14
  # GET /beavers/new
16
15
  def new
@@ -18,8 +17,7 @@ class BeaversController < ApplicationController
18
17
  end
19
18
 
20
19
  # GET /beavers/1/edit
21
- def edit
22
- end
20
+ def edit; end
23
21
 
24
22
  # POST /beavers
25
23
  # POST /beavers.json
@@ -62,13 +60,14 @@ class BeaversController < ApplicationController
62
60
  end
63
61
 
64
62
  private
65
- # Use callbacks to share common setup or constraints between actions.
66
- def set_beaver
67
- @beaver = Beaver.find(params[:id])
68
- end
69
63
 
70
- # Never trust parameters from the scary internet, only allow the white list through.
71
- def beaver_params
72
- params.require(:beaver).permit(:name)
73
- end
64
+ # Use callbacks to share common setup or constraints between actions.
65
+ def set_beaver
66
+ @beaver = Beaver.find(params[:id])
67
+ end
68
+
69
+ # Never trust parameters from the scary internet, only allow the white list through.
70
+ def beaver_params
71
+ params.require(:beaver).permit(:name)
72
+ end
74
73
  end
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- APP_PATH = File.expand_path('../../config/application', __FILE__)
2
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
3
3
  require_relative '../config/boot'
4
4
  require 'rails/commands'
@@ -1,4 +1,4 @@
1
1
  # This file is used by Rack-based servers to start the application.
2
2
 
3
- require ::File.expand_path('../config/environment', __FILE__)
3
+ require ::File.expand_path('../config/environment', __FILE__)
4
4
  run Rails.application
@@ -20,7 +20,7 @@ Rails.application.configure do
20
20
  # config.action_dispatch.rack_cache = true
21
21
 
22
22
  # Disable Rails's static asset server (Apache or nginx will already do this).
23
- config.serve_static_files = false
23
+ config.public_file_server.enabled = false
24
24
 
25
25
  # Compress JavaScripts and CSS.
26
26
  config.assets.js_compressor = :uglifier
@@ -13,8 +13,8 @@ Rails.application.configure do
13
13
  config.eager_load = false
14
14
 
15
15
  # Configure static asset server for tests with Cache-Control for performance.
16
- config.serve_static_files = true
17
- config.static_cache_control = 'public, max-age=3600'
16
+ config.public_file_server.enabled = true
17
+ config.public_file_server.headers = { 'Cache-Control' => 'public, max-age=3600' }
18
18
 
19
19
  # Show full error reports and disable caching.
20
20
  config.consider_all_requests_local = true
@@ -1,3 +1,3 @@
1
1
  # Be sure to restart your server when you modify this file.
2
2
 
3
- Rails.application.config.action_dispatch.cookies_serializer = :json
3
+ Rails.application.config.action_dispatch.cookies_serializer = :json
@@ -11,12 +11,10 @@
11
11
  #
12
12
  # It's strongly recommended that you check this file into your version control system.
13
13
 
14
- ActiveRecord::Schema.define(version: 20140424102400) do
15
-
16
- create_table "beavers", force: true do |t|
17
- t.string "name"
18
- t.datetime "created_at"
19
- t.datetime "updated_at"
14
+ ActiveRecord::Schema.define(version: 20_140_424_102_400) do
15
+ create_table 'beavers', force: true do |t|
16
+ t.string 'name'
17
+ t.datetime 'created_at'
18
+ t.datetime 'updated_at'
20
19
  end
21
-
22
20
  end
@@ -1,7 +1,7 @@
1
1
  # This file is copied to spec/ when you run 'rails generate rspec:install'
2
- ENV["RAILS_ENV"] ||= 'test'
2
+ ENV['RAILS_ENV'] ||= 'test'
3
3
  require 'spec_helper'
4
- require File.expand_path("../../config/environment", __FILE__)
4
+ require File.expand_path('../../config/environment', __FILE__)
5
5
  require 'rspec/rails'
6
6
  # Add additional requires below this line. Rails is not loaded until this point!
7
7
 
@@ -1,5 +1,4 @@
1
1
  RSpec.configure do |config|
2
-
3
2
  # Run specs in random order to surface order dependencies. If you find an
4
3
  # order dependency and want to debug it, you can fix the order by providing
5
4
  # the seed, which is printed after each run.
@@ -5,43 +5,43 @@ class BeaversControllerTest < ActionController::TestCase
5
5
  @beaver = beavers(:one)
6
6
  end
7
7
 
8
- test "should get index" do
8
+ test 'should get index' do
9
9
  get :index
10
10
  assert_response :success
11
11
  assert_not_nil assigns(:beavers)
12
12
  end
13
13
 
14
- test "should get new" do
14
+ test 'should get new' do
15
15
  get :new
16
16
  assert_response :success
17
17
  end
18
18
 
19
- test "should create beaver" do
19
+ test 'should create beaver' do
20
20
  assert_difference('Beaver.count') do
21
- post :create, beaver: { name: @beaver.name }
21
+ post :create, params: { beaver: { name: @beaver.name } }
22
22
  end
23
23
 
24
24
  assert_redirected_to beaver_path(assigns(:beaver))
25
25
  end
26
26
 
27
- test "should show beaver" do
28
- get :show, id: @beaver
27
+ test 'should show beaver' do
28
+ get :show, params: { id: @beaver }
29
29
  assert_response :success
30
30
  end
31
31
 
32
- test "should get edit" do
33
- get :edit, id: @beaver
32
+ test 'should get edit' do
33
+ get :edit, params: { id: @beaver }
34
34
  assert_response :success
35
35
  end
36
36
 
37
- test "should update beaver" do
38
- patch :update, id: @beaver, beaver: { name: @beaver.name }
37
+ test 'should update beaver' do
38
+ patch :update, params: { id: @beaver, beaver: { name: @beaver.name } }
39
39
  assert_redirected_to beaver_path(assigns(:beaver))
40
40
  end
41
41
 
42
- test "should destroy beaver" do
42
+ test 'should destroy beaver' do
43
43
  assert_difference('Beaver.count', -1) do
44
- delete :destroy, id: @beaver
44
+ delete :destroy, params: { id: @beaver }
45
45
  end
46
46
 
47
47
  assert_redirected_to beavers_path
@@ -8,19 +8,20 @@ Gem::Specification.new do |spec|
8
8
  spec.version = FlipFab::VERSION
9
9
  spec.authors = ['Simply Business']
10
10
  spec.email = ['tech@simplybusiness.co.uk']
11
- spec.description = %q{A gem providing persistent, per-user feature flipping to Rack applications.}
12
- spec.summary = %q{A gem providing persistent, per-user feature flipping to Rack applications.}
11
+ spec.description = 'A gem providing persistent, per-user feature flipping to Rack applications.'
12
+ spec.summary = 'A gem providing persistent, per-user feature flipping to Rack applications.'
13
13
  spec.homepage = 'https://github.com/simplybusiness/flip_fab'
14
14
  spec.license = 'MIT'
15
15
 
16
- spec.files = `git ls-files`.split($/)
16
+ spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ['lib']
20
20
 
21
- spec.add_development_dependency 'rack'
22
- spec.add_development_dependency 'rack-test'
23
- spec.add_development_dependency 'rspec'
24
- spec.add_development_dependency 'rutabaga'
25
- spec.add_development_dependency 'timecop'
21
+ spec.add_development_dependency 'rack', '~> 2.0'
22
+ spec.add_development_dependency 'rack-test', '~> 0.6'
23
+ spec.add_development_dependency 'rspec', '~> 3.5'
24
+ spec.add_development_dependency 'rutabaga', '~> 2.1'
25
+ spec.add_development_dependency 'timecop', '~> 0.8'
26
+ spec.add_development_dependency 'rubocop', '~> 0.46'
26
27
  end
@@ -6,16 +6,16 @@ require 'flip_fab/persistence'
6
6
  require 'flip_fab/cookie_persistence'
7
7
 
8
8
  module FlipFab
9
- extend self
10
-
11
9
  attr_reader :features
12
10
 
13
- def define_feature name, options={}
11
+ def define_feature(name, options = {})
14
12
  @features ||= {}
15
13
  @features[name] = Feature.new name, options
16
14
  end
17
15
 
18
16
  @features ||= FeaturesByName.new
17
+
18
+ module_function :features, :define_feature
19
19
  end
20
20
 
21
21
  if defined?(ActionController)
@@ -2,13 +2,12 @@ module FlipFab
2
2
  class ContextualFeature
3
3
  attr_reader :feature, :context
4
4
 
5
- def initialize feature, context
5
+ def initialize(feature, context)
6
6
  @feature = feature
7
7
  @context = context
8
- if overridden?
9
- @state = override
10
- persist
11
- end
8
+ return unless overridden?
9
+ @state = override
10
+ persist
12
11
  end
13
12
 
14
13
  def enabled?
@@ -27,16 +26,15 @@ module FlipFab
27
26
  self.state = :disabled
28
27
  end
29
28
 
30
- def state= value
29
+ def state=(value)
31
30
  raise "Invalid state provided: `#{value}`, possible states are :enabled, :disabled" unless %i(enabled disabled).include? value
32
- unless overridden?
33
- @state = value
34
- persist
35
- end
31
+ return if overridden?
32
+ @state = value
33
+ persist
36
34
  end
37
35
 
38
36
  def persist
39
- persistence_adapters.each{ |adapter| adapter.write state }
37
+ persistence_adapters.each { |adapter| adapter.write state }
40
38
  end
41
39
 
42
40
  private
@@ -46,11 +44,7 @@ module FlipFab
46
44
  end
47
45
 
48
46
  def state
49
- @state ||= if state_in_context?
50
- state_from_context
51
- else
52
- default_state
53
- end
47
+ @state ||= state_in_context? ? state_from_context : default_state
54
48
  end
55
49
 
56
50
  def state_in_context?
@@ -62,7 +56,7 @@ module FlipFab
62
56
  end
63
57
 
64
58
  def first_adapter_with_state
65
- persistence_adapters.detect{|adapter| !adapter.read.nil?}
59
+ persistence_adapters.detect { |adapter| !adapter.read.nil? }
66
60
  end
67
61
 
68
62
  def default_state
@@ -1,12 +1,11 @@
1
1
  module FlipFab
2
2
  class CookiePersistence < FlipFab::Persistence
3
+ COOKIE_PATH = '/'.freeze
4
+ COOKIE_DURATION_MONTHS = 12
5
+ # See: https://github.com/rails/rails/blob/b1124a2ac88778c0feb0157ac09367cbd204bf01/actionpack/lib/action_dispatch/middleware/cookies.rb#L214
6
+ DOMAIN_REGEXP = /[^.]*\.([^.]*|..\...|...\...)$/
3
7
 
4
- COOKIE_PATH = '/'
5
- COOKIE_DURATION_MONTHS = 12
6
- # See: https://github.com/rails/rails/blob/b1124a2ac88778c0feb0157ac09367cbd204bf01/actionpack/lib/action_dispatch/middleware/cookies.rb#L214
7
- DOMAIN_REGEXP = /[^.]*\.([^.]*|..\...|...\...)$/
8
-
9
- def initialize feature_name, context
8
+ def initialize(feature_name, context)
10
9
  super
11
10
  end
12
11
 
@@ -14,14 +13,12 @@ module FlipFab
14
13
  value.to_sym unless value.nil?
15
14
  end
16
15
 
17
- def write state
16
+ def write(state)
18
17
  cookie_domain = ".#{top_level_domain}" unless top_level_domain.nil?
19
- context.response.set_cookie key, {
20
- value: state,
21
- expires: cookie_expiration,
22
- domain: cookie_domain,
23
- path: COOKIE_PATH,
24
- }
18
+ context.response.set_cookie key, value: state,
19
+ expires: cookie_expiration,
20
+ domain: cookie_domain,
21
+ path: COOKIE_PATH
25
22
  end
26
23
 
27
24
  private
@@ -36,9 +33,7 @@ module FlipFab
36
33
 
37
34
  # See: https://github.com/rails/rails/blob/b1124a2ac88778c0feb0157ac09367cbd204bf01/actionpack/lib/action_dispatch/middleware/cookies.rb#L286-L294
38
35
  def top_level_domain
39
- if (host !~ /^[\d.]+$/) && (host =~ DOMAIN_REGEXP)
40
- $&
41
- end
36
+ $& if (host !~ /^[\d.]+$/) && (host =~ DOMAIN_REGEXP)
42
37
  end
43
38
 
44
39
  def cookie_expiration
@@ -1,9 +1,8 @@
1
1
  module FlipFab
2
2
  class Feature
3
-
4
3
  attr_reader :name, :default, :persistence_adapters
5
4
 
6
- def initialize name, options={}
5
+ def initialize(name, options = {})
7
6
  @name = name
8
7
  @default = options[:default] || :disabled
9
8
  @persistence_adapters = options[:persistence_adapters] || [CookiePersistence]
@@ -17,7 +16,7 @@ module FlipFab
17
16
  !enabled?
18
17
  end
19
18
 
20
- def with_context context
19
+ def with_context(context)
21
20
  ContextualFeature.new self, context
22
21
  end
23
22
  end
@@ -4,17 +4,17 @@ module FlipFab
4
4
  class FeaturesByName
5
5
  extend Forwardable
6
6
 
7
- def initialize features_by_name={}
7
+ def initialize(features_by_name = {})
8
8
  @features_by_name = features_by_name
9
9
  end
10
10
 
11
- def [] name
11
+ def [](name)
12
12
  raise "no feature has been defined with the name: #{name}" if @features_by_name[name].nil?
13
13
  @features_by_name[name]
14
14
  end
15
15
 
16
- def with_context context
17
- FeaturesByName.new Hash[@features_by_name.map{|name, feature| [name, (feature.with_context context)]}]
16
+ def with_context(context)
17
+ FeaturesByName.new Hash[@features_by_name.map { |name, feature| [name, (feature.with_context context)] }]
18
18
  end
19
19
 
20
20
  def_delegators :@features_by_name, :[]=, :clear, :count, :each