spec/lib/conker_spec.rb in conker-0.11.0 vs spec/lib/conker_spec.rb in conker-0.12.0
- old
+ new
@@ -1,235 +1,321 @@
+require 'active_support/core_ext/hash/indifferent_access'
+
require 'conker'
describe Conker do
before :each do
- @env_vars = ENV.keys
@constants = Kernel.constants
end
after :each do
- # N.B. this doesn't catch if we *changed* any env vars (rather than adding
- # new ones).
- (ENV.keys - @env_vars).each {|k| ENV.delete k }
- # Same caveat doesn't apply here, because Ruby will whinge if we redefine a
- # constant.
+ # Don't need to worry about changing (rather than adding) constants,
+ # because Ruby will whinge if we do that.
(Kernel.constants - @constants).each do |k|
Kernel.send :remove_const, k
end
end
- describe 'basic usage' do
- def setup!(env = :development)
- Conker.module_eval do
- setup_config! env,
- A_SECRET: api_credential(development: nil),
- PORT: required_in_production(type: :integer, default: 42)
+ describe 'reading config from a hash' do
+ describe 'basic usage' do
+ def setup!(env = :development, config = {})
+ Conker.module_eval do
+ setup_config! env, config.with_indifferent_access,
+ A_SECRET: api_credential(development: nil),
+ PORT: required_in_production(type: :integer, default: 42)
+ end
end
- end
- it 'exposes declared variables as top-level constants' do
- setup!
- ::A_SECRET.should be_nil
- ::PORT.should == 42
- end
+ it 'exposes declared variables as top-level constants' do
+ setup!
+ ::A_SECRET.should be_nil
+ ::PORT.should == 42
+ end
- it 'does not turn random environment variables into constants' do
- ENV['PATH'].should_not be_empty
- setup!
- expect { ::PATH }.to raise_error(NameError, /PATH/)
- end
+ it 'lets values in the hash override defaults' do
+ setup! :development, PORT: 3000
+ ::PORT.should == 3000
+ end
- it 'lets environment variables override environmental defaults' do
- ENV['A_SECRET'] = 'beefbeefbeefbeef'
- setup!
- ::A_SECRET.should == 'beef' * 4
- end
+ it 'ignores environment variables' do
+ ENV['A_SECRET'] = 'beefbeefbeefbeef'
+ begin setup! ensure ENV.delete('A_SECRET') end
+ ::A_SECRET.should be_nil
+ end
- it 'throws useful errors if required variables are missing' do
- ENV['A_SECRET'].should be_nil
- ENV['PORT'] = '42'
- expect { setup! :production }.to raise_error(/A_SECRET/)
+ it 'does not turn random environment variables into constants' do
+ ENV['PATH'].should_not be_empty
+ setup!
+ expect { ::PATH }.to raise_error(NameError, /PATH/)
+ end
+
+ it 'throws useful errors if required variables are missing' do
+ expect { setup! :production, PORT: 42 }.to raise_error(/A_SECRET/)
+ end
end
- end
- describe 'required variables' do
- def setup!
- env = @env # capture it for block scope
- Conker.module_eval do
- setup_config! env,
- APPNAME: optional(default: 'conker'),
- PORT: required_in_production(type: :integer, default: 3000)
+ describe 'required variables' do
+ def setup!(config = {})
+ env = @env # capture it for block scope
+ Conker.module_eval do
+ setup_config! env, config.with_indifferent_access,
+ APPNAME: optional(default: 'conker'),
+ PORT: required_in_production(type: :integer, default: 3000)
+ end
end
- end
- describe 'in development' do
- before { @env = :development }
+ describe 'in development' do
+ before { @env = :development }
- it 'allows optional variables to be missing' do
- ENV['APPNAME'].should be_nil
- ENV['PORT'] = '80'
- expect { setup! }.not_to raise_error
+ it 'allows optional variables to be missing' do
+ expect { setup! PORT: 80 }.not_to raise_error
+ end
+
+ it 'allows required_in_production variables to be missing' do
+ expect { setup! APPNAME: 'widget' }.not_to raise_error
+ end
end
- it 'allows required_in_production variables to be missing' do
- ENV['APPNAME'] = 'widget'
- ENV['PORT'].should be_nil
- expect { setup! }.not_to raise_error
+ describe 'in production' do
+ before { @env = :production }
+
+ it 'allows optional variables to be missing' do
+ expect { setup! PORT: 80 }.not_to raise_error
+ end
+
+ it 'throws a useful error if required_in_production variables are missing' do
+ expect { setup! APPNAME: 'widget' }.to raise_error(/PORT/)
+ end
end
end
- describe 'in production' do
- before { @env = :production }
- it 'allows optional variables to be missing' do
- ENV['APPNAME'].should be_nil
- ENV['PORT'] = '80'
- expect { setup! }.not_to raise_error
+ describe 'defaults' do
+ def setup!(env = :development, config = {})
+ Conker.module_eval do
+ setup_config! env, config.with_indifferent_access,
+ NUM_THREADS: optional(type: :integer, test: 1, default: 2)
+ end
end
- it 'throws a useful error if required_in_production variables are missing' do
- ENV['APPNAME'] = 'widget'
- ENV['PORT'].should be_nil
- expect { setup! }.to raise_error(/PORT/)
+ it 'uses the specified value if one is given' do
+ setup! :development, NUM_THREADS: 4
+ NUM_THREADS.should == 4
end
- end
- end
+ it 'uses the default value if none is specified' do
+ setup! :development
+ NUM_THREADS.should == 2
+ end
- describe 'defaults' do
- def setup!(env = :development)
- Conker.module_eval do
- setup_config! env, NUM_THREADS: optional(type: :integer, test: 1, default: 2)
+ it 'allows overriding defaults for specific environments' do
+ setup! :test
+ NUM_THREADS.should == 1
end
end
- it 'uses the specified value if one is given' do
- ENV['NUM_THREADS'] = '4'
- setup!
- NUM_THREADS.should == 4
- end
- it 'uses the default value if none is specified' do
- ENV['NUM_THREADS'].should be_nil
- setup!
- NUM_THREADS.should == 2
- end
+ describe 'typed variables' do
+ describe 'boolean' do
+ def setup_sprocket_enabled!(value_string)
+ Conker.module_eval do
+ setup_config! :development, {'SPROCKET_ENABLED' => value_string},
+ SPROCKET_ENABLED: optional(type: :boolean, default: false)
+ end
+ end
- it 'allows overriding defaults for specific environments' do
- ENV['NUM_THREADS'].should be_nil
- setup! :test
- NUM_THREADS.should == 1
- end
- end
+ it 'parses "true"' do
+ setup_sprocket_enabled! 'true'
+ SPROCKET_ENABLED.should be_true
+ end
+ it 'parses "false"' do
+ setup_sprocket_enabled! 'false'
+ SPROCKET_ENABLED.should be_false
+ end
- describe 'typed variables' do
- describe 'boolean' do
- def setup_sprocket_enabled!(value_string)
- ENV['SPROCKET_ENABLED'] = value_string
- Conker.module_eval do
- setup_config! :development, :SPROCKET_ENABLED => optional(type: :boolean, default: false)
+ it 'accepts "1" as true' do
+ setup_sprocket_enabled! '1'
+ SPROCKET_ENABLED.should be_true
end
- end
- it 'parses "true"' do
- setup_sprocket_enabled! 'true'
- SPROCKET_ENABLED.should be_true
+ it 'accepts "0" as false' do
+ setup_sprocket_enabled! '0'
+ SPROCKET_ENABLED.should be_false
+ end
end
- it 'parses "false"' do
- setup_sprocket_enabled! 'false'
- SPROCKET_ENABLED.should be_false
- end
+ describe 'integer' do
+ def setup_num_threads!(value_string)
+ Conker.module_eval do
+ setup_config! :development, {'NUM_THREADS' => value_string},
+ NUM_THREADS: optional(type: :integer, default: 2)
+ end
+ end
- it 'accepts "1" as true' do
- setup_sprocket_enabled! '1'
- SPROCKET_ENABLED.should be_true
+ it 'parses "42"' do
+ setup_num_threads! '42'
+ NUM_THREADS.should == 42
+ end
+
+ it 'throws an error if the value is not an integer' do
+ expect { setup_num_threads! 'one hundred' }.to raise_error(/one hundred/)
+ end
end
- it 'accepts "0" as false' do
- setup_sprocket_enabled! '0'
- SPROCKET_ENABLED.should be_false
+ describe 'float' do
+ def setup_log_probability!(value_string)
+ Conker.module_eval do
+ setup_config! :development, {'LOG_PROBABILITY' => value_string},
+ LOG_PROBABILITY: optional(type: :float, default: 1.0)
+ end
+ end
+
+ it 'parses "0.5"' do
+ setup_log_probability! '0.5'
+ LOG_PROBABILITY.should == 0.5
+ end
+
+ it 'throws an error if the value is not a float' do
+ expect { setup_log_probability! 'zero' }.to raise_error(/zero/)
+ end
end
- end
- describe 'integer' do
- def setup_num_threads!(value_string)
- ENV['NUM_THREADS'] = value_string
- Conker.module_eval do
- setup_config! :development, :NUM_THREADS => optional(type: :integer, default: 2)
+ describe 'url' do
+ def setup_api_url!(value_string)
+ Conker.module_eval do
+ setup_config! :development, {'API_URL' => value_string},
+ API_URL: optional(type: :url, default: 'http://example.com/foo')
+ end
end
+
+ it 'exposes a URI object, not a string' do
+ setup_api_url! 'http://localhost:4321/'
+ API_URL.host.should == 'localhost'
+ end
+
+ it 'parses the default value too' do
+ setup_api_url! nil
+ API_URL.host.should == 'example.com'
+ end
end
- it 'parses "42"' do
- setup_num_threads! '42'
- NUM_THREADS.should == 42
+ describe 'addressable' do
+ def setup_api_url!(value_string)
+ Conker.module_eval do
+ setup_config! :development, {'API_URL' => value_string},
+ API_URL: optional(type: :addressable, default: 'http://example.com/foo')
+ end
+ end
+
+ it 'exposes an Addressable::URI object, not a string' do
+ setup_api_url! 'http://localhost:4321/'
+ API_URL.host.should == 'localhost'
+ end
+
+ it 'parses the default value too' do
+ setup_api_url! nil
+ API_URL.host.should == 'example.com'
+ end
end
- it 'throws an error if the value is not an integer' do
- expect { setup_num_threads! 'one hundred' }.to raise_error(/one hundred/)
+ describe 'timestamp' do
+ xit 'seems to have bit rotted'
end
end
+ end
- describe 'float' do
- def setup_log_probability!(value_string)
- ENV['LOG_PROBABILITY'] = value_string
+
+ describe 'reading config from environment variables' do
+ before :each do
+ @env_vars = ENV.keys
+ end
+
+ after :each do
+ # N.B. this doesn't catch if we *changed* any env vars (rather than adding
+ # new ones).
+ (ENV.keys - @env_vars).each {|k| ENV.delete k }
+ end
+
+
+ describe 'basic usage' do
+ def setup!(env = :development)
Conker.module_eval do
- setup_config! :development, :LOG_PROBABILITY => optional(type: :float, default: 1.0)
+ setup_config! env,
+ A_SECRET: api_credential(development: nil),
+ PORT: required_in_production(type: :integer, default: 42)
end
end
- it 'parses "0.5"' do
- setup_log_probability! '0.5'
- LOG_PROBABILITY.should == 0.5
+ it 'exposes declared variables as top-level constants' do
+ setup!
+ ::A_SECRET.should be_nil
+ ::PORT.should == 42
end
- it 'throws an error if the value is not a float' do
- expect { setup_log_probability! 'zero' }.to raise_error(/zero/)
+ it 'does not turn random environment variables into constants' do
+ ENV['PATH'].should_not be_empty
+ setup!
+ expect { ::PATH }.to raise_error(NameError, /PATH/)
end
- end
- describe 'url' do
- def setup_api_url!(value_string)
- ENV['API_URL'] = value_string
- Conker.module_eval do
- setup_config! :development, :API_URL => optional(type: :url, default: 'http://example.com/foo')
- end
+ it 'lets environment variables override environmental defaults' do
+ ENV['A_SECRET'] = 'beefbeefbeefbeef'
+ setup!
+ ::A_SECRET.should == 'beef' * 4
end
- it 'exposes a URI object, not a string' do
- setup_api_url! 'http://localhost:4321/'
- API_URL.host.should == 'localhost'
+ it 'throws useful errors if required variables are missing' do
+ ENV['A_SECRET'].should be_nil
+ ENV['PORT'] = '42'
+ expect { setup! :production }.to raise_error(/A_SECRET/)
end
+ end
+ end
- it 'parses the default value too' do
- setup_api_url! nil
- API_URL.host.should == 'example.com'
- end
+
+ describe 'reading config from a YAML file' do
+ def fixture(filename)
+ File.join(File.dirname(__FILE__), '..', 'fixtures', filename)
end
- describe 'addressable' do
- def setup_api_url!(value_string)
- ENV['API_URL'] = value_string
+ describe 'basic usage' do
+ def setup!(env = :development, filename = 'empty.yml')
+ fixture_path = fixture(filename)
Conker.module_eval do
- setup_config! :development, :API_URL => optional(type: :addressable, default: 'http://example.com/foo')
+ setup_config! env, fixture_path,
+ A_SECRET: api_credential(development: nil),
+ PORT: required_in_production(type: :integer, default: 42)
end
end
- it 'exposes an Addressable::URI object, not a string' do
- setup_api_url! 'http://localhost:4321/'
- API_URL.host.should == 'localhost'
+ it 'exposes declared variables as top-level constants' do
+ setup!
+ ::A_SECRET.should be_nil
+ ::PORT.should == 42
end
- it 'parses the default value too' do
- setup_api_url! nil
- API_URL.host.should == 'example.com'
+ it 'lets values in the file override defaults' do
+ setup! :development, 'port_3000.yml'
+ ::PORT.should == 3000
end
- end
- describe 'timestamp' do
- xit 'seems to have bit rotted'
+ it 'ignores environment variables' do
+ ENV['A_SECRET'] = 'beefbeefbeefbeef'
+ begin setup! ensure ENV.delete('A_SECRET') end
+ ::A_SECRET.should be_nil
+ end
+
+ it 'does not turn random environment variables into constants' do
+ ENV['PATH'].should_not be_empty
+ setup!
+ expect { ::PATH }.to raise_error(NameError, /PATH/)
+ end
+
+ it 'throws useful errors if required variables are missing' do
+ expect { setup! :production, 'port_3000.yml' }.to raise_error(/A_SECRET/)
+ end
end
end
end