rack-flags 0.2.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 030accbc9290006cd0fd32c0b783197aba732931
4
+ data.tar.gz: 449cdfc9a26ab58d7e392899775fd200e2050ccb
5
+ SHA512:
6
+ metadata.gz: 49a6f1149f461095dd315f5a97e8c4405798d2297819ce2a0fe0a1e1b59eba2bed1e673a2a1ef2c0d5cb485f07ee89a2d4fd15b78bb8cff671286df8533214e5
7
+ data.tar.gz: 6c02ae4688ae33a4857f2bce118d26840c1531f61b79813dfef04840e553328a394f14da8eac38beb58d04f4d8bfa4e2b42d2acf17319875e69c0f41d4ddf3d3
@@ -4,16 +4,22 @@ module RackFlags
4
4
 
5
5
  def initialize( app, args )
6
6
  @app = app
7
- yaml_path = args.fetch( :yaml_path ){ raise ArgumentError.new( 'yaml_path must be provided' ) }
8
- @config = Config.load( yaml_path )
7
+ @disable_config_caching = args.fetch(:disable_config_caching, false)
8
+ @yaml_path = args.fetch( :yaml_path ){ raise ArgumentError.new( 'yaml_path must be provided' ) }
9
9
  end
10
10
 
11
11
  def call( env )
12
12
  overrides = CookieCodec.new.overrides_from_env( env )
13
- reader = Reader.new( @config.flags, overrides )
13
+ reader = Reader.new( config.flags, overrides )
14
14
  env[ENV_KEY] = reader
15
15
 
16
16
  @app.call(env)
17
17
  end
18
+
19
+ private
20
+ def config
21
+ @config = nil if @disable_config_caching
22
+ @config ||= Config.load(@yaml_path)
23
+ end
18
24
  end
19
25
  end
@@ -1,3 +1,3 @@
1
1
  module RackFlags
2
- VERSION = "0.2.0"
2
+ VERSION = '0.3.1'
3
3
  end
@@ -38,16 +38,16 @@ describe 'displaying flags in admin app' do
38
38
  it 'renders the feature flag name, default and description' do
39
39
  AdminPage.visiting do |page|
40
40
  on_flag_section = page.section_for_flag_named('on_by_default')
41
- on_flag_section.should_not be_nil
42
- on_flag_section.find('h3').text.should == 'on_by_default'
43
- on_flag_section.find('p').text.should == 'this flag on by default'
44
- on_flag_section.find('label.default').text.should include('Default (On)')
41
+ expect(on_flag_section).to_not be_nil
42
+ expect(on_flag_section.find('h3').text).to eq 'on_by_default'
43
+ expect(on_flag_section.find('p').text).to eq 'this flag on by default'
44
+ expect(on_flag_section.find('label.default').text).to include('Default (On)')
45
45
 
46
46
  off_flag_section = page.section_for_flag_named('off_by_default')
47
- off_flag_section.should_not be_nil
48
- off_flag_section.find('h3').text.should == 'off_by_default'
49
- off_flag_section.find('p').text.should == 'this flag off by default'
50
- off_flag_section.find('label.default').text.should include('Default (Off)')
47
+ expect(off_flag_section).to_not be_nil
48
+ expect(off_flag_section.find('h3').text).to eq 'off_by_default'
49
+ expect(off_flag_section.find('p').text).to eq 'this flag off by default'
50
+ expect(off_flag_section.find('label.default').text).to include('Default (Off)')
51
51
  end
52
52
  end
53
53
 
@@ -23,7 +23,7 @@ describe 'reading feature flags in an app' do
23
23
  context 'no base flags, no overrides' do
24
24
  it 'should interpret both foo and bar as off by default' do
25
25
  get '/'
26
- last_response.body.should == 'foo is off; bar is off'
26
+ expect(last_response.body).to eql 'foo is off; bar is off'
27
27
  end
28
28
  end
29
29
 
@@ -36,7 +36,7 @@ describe 'reading feature flags in an app' do
36
36
 
37
37
  it 'should interpret foo as on and bar as off' do
38
38
  get '/'
39
- last_response.body.should == 'foo is on; bar is off'
39
+ expect(last_response.body).to eql 'foo is on; bar is off'
40
40
  end
41
41
  end
42
42
 
@@ -50,7 +50,7 @@ describe 'reading feature flags in an app' do
50
50
 
51
51
  it 'should interpret foo as off and bar as on' do
52
52
  get '/'
53
- last_response.body.should == 'foo is off; bar is on'
53
+ expect(last_response.body).to eql 'foo is off; bar is on'
54
54
  end
55
55
  end
56
56
 
@@ -66,7 +66,7 @@ describe 'reading feature flags in an app' do
66
66
 
67
67
  it 'should interpret foo as on and bar as off' do
68
68
  get '/'
69
- last_response.body.should == 'foo is on; bar is off'
69
+ expect(last_response.body).to eql 'foo is on; bar is off'
70
70
  end
71
71
  end
72
72
 
@@ -20,14 +20,14 @@ class AdminPage
20
20
  section_for_flag_named(flag_name).choose('On')
21
21
  update_button.click
22
22
  end
23
-
23
+
24
24
  def turn_off_flag_name(flag_name)
25
25
  section_for_flag_named(flag_name).choose('Off')
26
26
  update_button.click
27
27
  end
28
28
 
29
29
 
30
- def update_button
30
+ def update_button
31
31
  page.find('input[type="submit"]')
32
32
  end
33
33
 
@@ -40,27 +40,26 @@ class AdminPage
40
40
 
41
41
  case expected_state.to_sym
42
42
  when :default
43
- section.find('label.default input').should be_checked
43
+ expect(section.find('label.default input')).to be_checked
44
44
 
45
- section.find('label.on input').should_not be_checked
46
- section.find('label.off input').should_not be_checked
45
+ expect(section.find('label.on input')).to_not be_checked
46
+ expect(section.find('label.off input')).to_not be_checked
47
47
  when :on
48
- section.find('label.on input').should be_checked
48
+ expect(section.find('label.on input')).to be_checked
49
49
 
50
- section.find('label.default input').should_not be_checked
51
- section.find('label.off input').should_not be_checked
50
+ expect(section.find('label.default input')).to_not be_checked
51
+ expect(section.find('label.off input')).to_not be_checked
52
52
  when :off
53
- section.find('label.off input').should be_checked
53
+ expect(section.find('label.off input')).to be_checked
54
54
 
55
- section.find('label.default input').should_not be_checked
56
- section.find('label.on input').should_not be_checked
57
- else
55
+ expect(section.find('label.default input')).to_not be_checked
56
+ expect(section.find('label.on input')).to_not be_checked
57
+ else
58
58
  raise "unrecognized state '#{expected_state}'"
59
59
  end
60
60
  end
61
61
 
62
62
  def verify_status_code_is(expected_status_code)
63
- status_code.should == expected_status_code
63
+ expect(status_code).to eql expected_status_code
64
64
  end
65
-
66
- end
65
+ end
@@ -17,11 +17,11 @@ class ReaderPage
17
17
  end
18
18
 
19
19
  def verify_flag_is_off(flag_name)
20
- page.should have_content("#{flag_name} is off")
20
+ expect(page).to have_content("#{flag_name} is off")
21
21
  end
22
22
 
23
23
  def verify_flag_is_on(flag_name)
24
- page.should have_content("#{flag_name} is on")
24
+ expect(page).to have_content("#{flag_name} is on")
25
25
  end
26
26
 
27
27
  end
data/spec/spec_helper.rb CHANGED
@@ -2,6 +2,8 @@ require 'rr'
2
2
  require 'pry'
3
3
  require 'rack'
4
4
  require 'rack/test'
5
+ require 'rspec/its'
6
+ require 'rspec/collection_matchers'
5
7
 
6
8
  require_relative '../lib/rack-flags'
7
9
 
@@ -1,7 +1,7 @@
1
1
  require_relative 'spec_helper'
2
2
 
3
3
  module RackFlags
4
-
4
+
5
5
  describe Config do
6
6
  let( :config_file ) { Tempfile.new('rack-flags-config-unit-test') }
7
7
  let( :yaml ) { raise NotImplementedError }
@@ -21,7 +21,7 @@ module RackFlags
21
21
  context 'regular yaml' do
22
22
  let(:yaml) do
23
23
  <<-EOS
24
- foo:
24
+ foo:
25
25
  description: the description
26
26
  default: true
27
27
  bar:
@@ -31,33 +31,33 @@ module RackFlags
31
31
  end
32
32
 
33
33
  it 'loads a set of BaseFlags' do
34
- config.should have(2).flags
35
- config.flags.map(&:name) .should =~ [:foo,:bar]
36
- config.flags.map(&:description).should =~ ["the description","another description"]
37
- config.flags.map(&:default).should =~ [true,false]
34
+ expect(config).to have(2).flags
35
+ expect(config.flags.map(&:name)).to include(:foo, :bar)
36
+ expect(config.flags.map(&:description)).to include('the description', 'another description')
37
+ expect(config.flags.map(&:default)).to include(true, false)
38
38
  end
39
39
  end
40
40
 
41
41
  context 'empty file' do
42
42
  let(:yaml){ "" }
43
43
  it 'loads as an empty config' do
44
- config.should have(0).flags
44
+ expect(config).to have(0).flags
45
45
  end
46
46
  end
47
47
 
48
48
  context 'symbolized yaml' do
49
49
  let :yaml do
50
50
  <<-EOS
51
- :foo:
51
+ :foo:
52
52
  :default: true
53
53
  :description: a description
54
54
  EOS
55
55
  end
56
56
 
57
- subject(:flag){ config.flags.first }
57
+ subject(:flag){ config.flags.first }
58
58
 
59
59
  it { should_not be_nil }
60
- its(:default) { should be_true }
60
+ its(:default) { should be_truthy }
61
61
  its(:description) { should == "a description" }
62
62
  end
63
63
  end
@@ -1,32 +1,46 @@
1
1
  require_relative 'spec_helper'
2
2
 
3
3
  module RackFlags
4
-
5
4
  describe RackMiddleware do
6
-
7
5
  def mock_out_config_loading
8
6
  stub(Config).load(anything){ OpenStruct.new( flags: {} ) }
9
7
  end
10
8
 
9
+ def create_middleware(fake_app = false, additional_args = {})
10
+ args = {yaml_path: 'blah'}.merge additional_args
11
+ fake_app ||= Proc.new {}
12
+ RackMiddleware.new( fake_app, args )
13
+ end
14
+
11
15
  it 'raise an exception if no yaml path is provided' do
12
- lambda{
16
+ expect {
13
17
  RackMiddleware.new( :fake_app, {} )
14
- }.should raise_error( ArgumentError, 'yaml_path must be provided' )
18
+ }.to raise_error( ArgumentError, 'yaml_path must be provided' )
15
19
  end
16
20
 
17
21
  it 'loads the config from the specified yaml file' do
18
- mock(Config).load('some/config/path')
19
- RackMiddleware.new( :fake_app, yaml_path: 'some/config/path' )
22
+ mock(Config).load('some/config/path'){ OpenStruct.new flags: {} }
23
+ middleware = create_middleware(false, yaml_path: 'some/config/path')
24
+ middleware.call({})
20
25
  end
21
26
 
22
- describe '#call' do
27
+ it 'caches configuration by default' do
28
+ mock(Config).load(anything){ OpenStruct.new( flags: {} ) }
29
+
30
+ middleware = create_middleware()
31
+ middleware.call({})
32
+ middleware.call({})
33
+ end
23
34
 
24
- def create_middleware( fake_app = false)
25
- fake_app ||= Proc.new {}
35
+ it 'does not cache if specified' do
36
+ mock(Config).load(anything).times(2){ OpenStruct.new( flags: {} ) }
26
37
 
27
- RackMiddleware.new( fake_app, yaml_path: 'blah' )
28
- end
38
+ middleware = create_middleware(false, disable_config_caching: true)
39
+ middleware.call({})
40
+ middleware.call({})
41
+ end
29
42
 
43
+ describe '#call' do
30
44
  it 'creates a Reader using the config flags when called' do
31
45
  stub(Config).load(anything){ OpenStruct.new( flags: 'fake flags from config' ) }
32
46
  mock(Reader).new( 'fake flags from config', anything )
@@ -43,7 +57,7 @@ module RackFlags
43
57
  middleware = create_middleware()
44
58
  fake_env = {}
45
59
  middleware.call( fake_env )
46
- fake_env[RackMiddleware::ENV_KEY].should == 'fake derived flags'
60
+ expect(fake_env[RackMiddleware::ENV_KEY]).to eq 'fake derived flags'
47
61
  end
48
62
 
49
63
  it 'reads overrides from cookies' do
@@ -51,7 +65,6 @@ module RackFlags
51
65
 
52
66
  fake_env = { fake: 'env' }
53
67
 
54
-
55
68
  fake_cookie_codec = mock( Object.new )
56
69
  mock(CookieCodec).new{ fake_cookie_codec }
57
70
 
@@ -73,15 +86,14 @@ module RackFlags
73
86
  mock_out_config_loading
74
87
 
75
88
  fake_app ||= Proc.new do
76
- "downstream app response"
89
+ 'downstream app response'
77
90
  end
78
91
 
79
92
  middleware = create_middleware( fake_app )
80
93
  middleware_response = middleware.call( {} )
81
94
 
82
- middleware_response.should == "downstream app response"
95
+ expect(middleware_response).to eq 'downstream app response'
83
96
  end
84
97
  end
85
98
  end
86
-
87
99
  end
@@ -4,14 +4,14 @@ module RackFlags
4
4
  describe '.for_env' do
5
5
  it 'should return the flags which the middleware stuffed in the env' do
6
6
  fake_env = {RackMiddleware::ENV_KEY => 'fake flags from env'}
7
- RackFlags.for_env(fake_env).should == 'fake flags from env'
7
+ expect(RackFlags.for_env(fake_env)).to eq 'fake flags from env'
8
8
  end
9
9
 
10
10
  it 'returns a generic empty reader if none is in the env' do
11
11
  fake_env = {}
12
12
  reader = RackFlags.for_env(fake_env)
13
- reader.should_not be_nil
14
- reader.should respond_to(:on?)
13
+ expect(reader).to_not be_nil
14
+ expect(reader).to respond_to(:on?)
15
15
  end
16
16
  end
17
17
  end
@@ -29,11 +29,11 @@ module RackFlags
29
29
 
30
30
  expect(full_flags[0].name).to eq(:usually_on)
31
31
  expect(full_flags[0].description).to eq('a flag')
32
- expect(full_flags[0].default).to be_true
32
+ expect(full_flags[0].default).to be_truthy
33
33
 
34
34
  expect(full_flags[1].name).to eq(:usually_off)
35
35
  expect(full_flags[1].description).to eq('another flag')
36
- expect(full_flags[1].default).to be_false
36
+ expect(full_flags[1].default).to be_falsey
37
37
  end
38
38
 
39
39
  end
@@ -44,15 +44,15 @@ module RackFlags
44
44
  its(:base_flags){ should == {usually_on: true, usually_off: false} }
45
45
 
46
46
  specify 'on? is true for a flag which is on by default' do
47
- subject.on?( :usually_on ).should be_true
47
+ expect(reader.on?(:usually_on)).to be_truthy
48
48
  end
49
49
 
50
50
  specify 'on? is false for a flag which is off by default' do
51
- subject.on?( :usually_off ).should be_false
51
+ expect(reader.on?(:usually_off)).to be_falsey
52
52
  end
53
53
 
54
54
  specify 'on? is false for unknown flags' do
55
- subject.on?( :unknown_flag ).should be_false
55
+ expect(reader.on?(:unknown_flag)).to be_falsey
56
56
  end
57
57
 
58
58
  it_behaves_like 'full flags that mimic the base flags'
@@ -68,7 +68,7 @@ module RackFlags
68
68
  let( :overrides ){ {usually_on: false} }
69
69
 
70
70
  specify 'on? is false' do
71
- subject.on?( :usually_on ).should be_false
71
+ expect(reader.on?(:usually_on)).to be_falsey
72
72
  end
73
73
 
74
74
  it_behaves_like 'full flags that mimic the base flags'
@@ -84,7 +84,7 @@ module RackFlags
84
84
  let( :overrides ){ {no_base: true} }
85
85
 
86
86
  specify 'on? is false' do
87
- subject.on?( :no_base ).should be_false
87
+ expect(reader.on?(:no_base)).to be_falsy
88
88
  end
89
89
 
90
90
  it_behaves_like 'full flags that mimic the base flags'
@@ -96,5 +96,4 @@ module RackFlags
96
96
  end
97
97
  end
98
98
  end
99
-
100
- end
99
+ end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-flags
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
5
- prerelease:
4
+ version: 0.3.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Pete Hodgson
@@ -10,134 +9,132 @@ authors:
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2013-08-18 00:00:00.000000000 Z
12
+ date: 2014-06-21 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: rake
17
16
  requirement: !ruby/object:Gem::Requirement
18
- none: false
19
17
  requirements:
20
- - - ! '>='
18
+ - - ">="
21
19
  - !ruby/object:Gem::Version
22
20
  version: '0'
23
21
  type: :runtime
24
22
  prerelease: false
25
23
  version_requirements: !ruby/object:Gem::Requirement
26
- none: false
27
24
  requirements:
28
- - - ! '>='
25
+ - - ">="
29
26
  - !ruby/object:Gem::Version
30
27
  version: '0'
31
28
  - !ruby/object:Gem::Dependency
32
29
  name: rack
33
30
  requirement: !ruby/object:Gem::Requirement
34
- none: false
35
31
  requirements:
36
- - - ~>
32
+ - - "~>"
37
33
  - !ruby/object:Gem::Version
38
34
  version: '1.4'
39
35
  type: :runtime
40
36
  prerelease: false
41
37
  version_requirements: !ruby/object:Gem::Requirement
42
- none: false
43
38
  requirements:
44
- - - ~>
39
+ - - "~>"
45
40
  - !ruby/object:Gem::Version
46
41
  version: '1.4'
47
42
  - !ruby/object:Gem::Dependency
48
43
  name: sinatra
49
44
  requirement: !ruby/object:Gem::Requirement
50
- none: false
51
45
  requirements:
52
- - - ~>
46
+ - - "~>"
53
47
  - !ruby/object:Gem::Version
54
48
  version: '1.3'
55
49
  type: :runtime
56
50
  prerelease: false
57
51
  version_requirements: !ruby/object:Gem::Requirement
58
- none: false
59
52
  requirements:
60
- - - ~>
53
+ - - "~>"
61
54
  - !ruby/object:Gem::Version
62
55
  version: '1.3'
63
56
  - !ruby/object:Gem::Dependency
64
57
  name: pry-debugger
65
58
  requirement: !ruby/object:Gem::Requirement
66
- none: false
67
59
  requirements:
68
- - - ! '>='
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: 0.2.2
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: 0.2.2
70
+ - !ruby/object:Gem::Dependency
71
+ name: rspec
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
69
75
  - !ruby/object:Gem::Version
70
76
  version: '0'
71
77
  type: :development
72
78
  prerelease: false
73
79
  version_requirements: !ruby/object:Gem::Requirement
74
- none: false
75
80
  requirements:
76
- - - ! '>='
81
+ - - ">="
77
82
  - !ruby/object:Gem::Version
78
83
  version: '0'
79
84
  - !ruby/object:Gem::Dependency
80
- name: rspec-core
85
+ name: rspec-its
81
86
  requirement: !ruby/object:Gem::Requirement
82
- none: false
83
87
  requirements:
84
- - - ! '>='
88
+ - - ">="
85
89
  - !ruby/object:Gem::Version
86
90
  version: '0'
87
91
  type: :development
88
92
  prerelease: false
89
93
  version_requirements: !ruby/object:Gem::Requirement
90
- none: false
91
94
  requirements:
92
- - - ! '>='
95
+ - - ">="
93
96
  - !ruby/object:Gem::Version
94
97
  version: '0'
95
98
  - !ruby/object:Gem::Dependency
96
- name: rspec-expectations
99
+ name: rspec-collection_matchers
97
100
  requirement: !ruby/object:Gem::Requirement
98
- none: false
99
101
  requirements:
100
- - - ! '>='
102
+ - - ">="
101
103
  - !ruby/object:Gem::Version
102
104
  version: '0'
103
105
  type: :development
104
106
  prerelease: false
105
107
  version_requirements: !ruby/object:Gem::Requirement
106
- none: false
107
108
  requirements:
108
- - - ! '>='
109
+ - - ">="
109
110
  - !ruby/object:Gem::Version
110
111
  version: '0'
111
112
  - !ruby/object:Gem::Dependency
112
113
  name: rr
113
114
  requirement: !ruby/object:Gem::Requirement
114
- none: false
115
115
  requirements:
116
- - - ! '>='
116
+ - - ">="
117
117
  - !ruby/object:Gem::Version
118
118
  version: '0'
119
119
  type: :development
120
120
  prerelease: false
121
121
  version_requirements: !ruby/object:Gem::Requirement
122
- none: false
123
122
  requirements:
124
- - - ! '>='
123
+ - - ">="
125
124
  - !ruby/object:Gem::Version
126
125
  version: '0'
127
126
  - !ruby/object:Gem::Dependency
128
127
  name: capybara
129
128
  requirement: !ruby/object:Gem::Requirement
130
- none: false
131
129
  requirements:
132
- - - ! '>='
130
+ - - ">="
133
131
  - !ruby/object:Gem::Version
134
132
  version: '0'
135
133
  type: :development
136
134
  prerelease: false
137
135
  version_requirements: !ruby/object:Gem::Requirement
138
- none: false
139
136
  requirements:
140
- - - ! '>='
137
+ - - ">="
141
138
  - !ruby/object:Gem::Version
142
139
  version: '0'
143
140
  description: This is a simple lightweight way to expose work-in-progress functionality
@@ -173,34 +170,28 @@ files:
173
170
  - spec/unit/reader_spec.rb
174
171
  - spec/unit/spec_helper.rb
175
172
  homepage: https://github.com/moredip/rack-flags
176
- licenses: []
173
+ licenses:
174
+ - Apache 2.0
175
+ metadata: {}
177
176
  post_install_message:
178
177
  rdoc_options: []
179
178
  require_paths:
180
179
  - lib
181
180
  required_ruby_version: !ruby/object:Gem::Requirement
182
- none: false
183
181
  requirements:
184
- - - ! '>='
182
+ - - ">="
185
183
  - !ruby/object:Gem::Version
186
184
  version: '0'
187
- segments:
188
- - 0
189
- hash: -1587276137499646704
190
185
  required_rubygems_version: !ruby/object:Gem::Requirement
191
- none: false
192
186
  requirements:
193
- - - ! '>='
187
+ - - ">="
194
188
  - !ruby/object:Gem::Version
195
189
  version: '0'
196
- segments:
197
- - 0
198
- hash: -1587276137499646704
199
190
  requirements: []
200
191
  rubyforge_project:
201
- rubygems_version: 1.8.25
192
+ rubygems_version: 2.2.2
202
193
  signing_key:
203
- specification_version: 3
194
+ specification_version: 4
204
195
  summary: Simple cookie-based feature flags using Rack.
205
196
  test_files:
206
197
  - spec/acceptance/administering_feature_flags_spec.rb