flip_fab 1.0.1 → 1.0.2

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 (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