configliere 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.
@@ -0,0 +1,62 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'configliere/commandline'
3
+
4
+ describe "Configliere::Commandline" do
5
+ before do
6
+ @config = Configliere::Param.new :param_1 => 'val 1', :cat => :hat
7
+ end
8
+
9
+ it 'handles --param=val pairs' do
10
+ ::ARGV.replace ['--my_param=my_val']
11
+ @config.resolve!
12
+ @config.should == { :my_param => 'my_val', :param_1 => 'val 1', :cat => :hat}
13
+ end
14
+ it 'handles --dotted.param.name=val pairs' do
15
+ ::ARGV.replace ['--dotted.param.name=my_val']
16
+ @config.resolve!
17
+ @config.rest.should be_empty
18
+ @config.should == { :dotted => { :param => { :name => 'my_val' }}, :param_1 => 'val 1', :cat => :hat}
19
+ end
20
+ it 'handles --dashed-param-name=val pairs' do
21
+ ::ARGV.replace ['--dashed-param-name=my_val']
22
+ @config.resolve!
23
+ @config.rest.should be_empty
24
+ @config.should == { :dashed => { :param => { :name => 'my_val' }}, :param_1 => 'val 1', :cat => :hat}
25
+ end
26
+ it 'uses the last-seen of the commandline values' do
27
+ ::ARGV.replace ['--param_1=A', '--param_1=B']
28
+ @config.resolve!
29
+ @config.rest.should be_empty
30
+ @config.should == { :param_1 => 'B', :cat => :hat}
31
+ end
32
+ it 'sets a bare parameter (no "=") to true' do
33
+ ::ARGV.replace ['--param_1', '--deep.param']
34
+ @config.resolve!
35
+ @config.rest.should be_empty
36
+ @config.should == { :param_1 => true, :deep => { :param => true }, :cat => :hat}
37
+ end
38
+ it 'sets an explicit blank to nil' do
39
+ ::ARGV.replace ['--param_1=', '--deep.param=']
40
+ @config.resolve!
41
+ @config.should == { :param_1 => nil, :deep => { :param => nil }, :cat => :hat}
42
+ end
43
+
44
+ it 'saves non --param args into rest' do
45
+ ::ARGV.replace ['--param_1', 'file1', 'file2']
46
+ @config.resolve!
47
+ @config.should == { :param_1 => true, :cat => :hat}
48
+ @config.rest.should == ['file1', 'file2']
49
+ end
50
+
51
+ it 'stops processing on "--"' do
52
+ ::ARGV.replace ['--param_1=A', '--', '--param_1=B']
53
+ @config.resolve!
54
+ @config.rest.should == ['--param_1=B']
55
+ @config.should == { :param_1 => 'A', :cat => :hat}
56
+ end
57
+
58
+ after do
59
+ ::ARGV.replace []
60
+ end
61
+ end
62
+
@@ -0,0 +1,26 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ Configliere.use :config_blocks
3
+
4
+ describe "Configliere::ConfigBlocks" do
5
+ before do
6
+ @config = Configliere::Param.new :normal_param => 'normal'
7
+ end
8
+
9
+ describe 'resolving' do
10
+ it 'runs blocks' do
11
+ @block_watcher = 'watcher'
12
+ @block_watcher.should_receive(:fnord).with(@config)
13
+ @config.finally{|arg| @block_watcher.fnord(arg) }
14
+ @config.resolve!
15
+ end
16
+ it 'resolves blocks last' do
17
+ Configliere.use :config_blocks, :define, :encrypted
18
+ @config.should_receive(:resolve_types!).ordered
19
+ @config.should_receive(:resolve_finally_blocks!).ordered
20
+ @config.resolve!
21
+ end
22
+ end
23
+
24
+ end
25
+
26
+
@@ -0,0 +1,18 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'configliere/crypter'
3
+ include Configliere
4
+
5
+ describe "Crypter" do
6
+ ENCRYPTED_FOO_VAL = "q\317\201\247\230\314P\021\305\n\363\315d\207\345y\346\255\a\202\006i\245\343T\203e\327a\316\245\313"
7
+ it "encrypts" do
8
+ # Force the same initialization vector as used to prepare the test value
9
+ @cipher = Crypter.send(:new_cipher, :encrypt, 'sekrit')
10
+ Crypter.should_receive(:new_cipher).and_return(@cipher)
11
+ @cipher.should_receive(:random_iv).and_return ENCRYPTED_FOO_VAL[0..15]
12
+ # OK so do the test now.
13
+ Crypter.encrypt('foo_val', 'sekrit').should == ENCRYPTED_FOO_VAL
14
+ end
15
+ it "decrypts" do
16
+ Crypter.decrypt(ENCRYPTED_FOO_VAL, 'sekrit').should == 'foo_val'
17
+ end
18
+ end
@@ -0,0 +1,97 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ Configliere.use :define
3
+
4
+ describe "Configliere::Define" do
5
+ before do
6
+ @config = Configliere::Param.new :normal_param => 'normal'
7
+ end
8
+ describe 'defining any aspect of a param' do
9
+ it 'adopts values' do
10
+ @config.define :param, :description => 'desc'
11
+ @config.param_definitions[:param].should == { :description => 'desc'}
12
+ end
13
+ it 'merges new definitions' do
14
+ @config.define :param, :description => 'desc 1'
15
+ @config.define :param, :description => 'desc 2'
16
+ @config.param_definitions[:param].should == { :description => 'desc 2'}
17
+ @config.define :param, :encrypted => true
18
+ @config.param_definitions[:param].should == { :encrypted => true, :description => 'desc 2'}
19
+ end
20
+ it 'lists params defined as the given aspect' do
21
+ @config.define :param_1, :description => 'desc 1'
22
+ @config.define :param_2, :description => 'desc 2'
23
+ @config.define :param_3, :something_else => 'foo'
24
+ @config.send(:params_with, :description).should include(:param_1)
25
+ @config.send(:params_with, :description).should include(:param_2)
26
+ end
27
+ end
28
+
29
+ describe 'defining descriptions' do
30
+ before do
31
+ @config.define :param_1, :description => 'desc 1'
32
+ @config.define :param_2, :description => 'desc 2'
33
+ end
34
+ it 'shows description for a param' do
35
+ @config.description_for(:param_1).should == 'desc 1'
36
+ end
37
+ it 'lists descriptions' do
38
+ @config.descriptions.should == { :param_1 => 'desc 1', :param_2 => 'desc 2'}
39
+ end
40
+ it 'lists descriptions' do
41
+ @config.described_params.should include(:param_1)
42
+ @config.described_params.should include(:param_2)
43
+ end
44
+ end
45
+
46
+ require 'date'; require 'time'
47
+ describe 'type coercion' do
48
+ [
49
+ [:boolean, '0', false], [:boolean, 0, false], [:boolean, '', false], [:boolean, [], false], [:boolean, nil, nil],
50
+ [:boolean, '1', true], [:boolean, 1, true], [:boolean, '5', true], [:boolean, 'true', true],
51
+ [Integer, '5', 5], [Integer, 5, 5], [Integer, nil, nil], [Integer, '', nil],
52
+ [Integer, '5', 5], [Integer, 5, 5], [Integer, nil, nil], [Integer, '', nil],
53
+ [Float, '5.2', 5.2], [Float, 5.2, 5.2], [Float, nil, nil], [Float, '', nil],
54
+ [Symbol, 'foo', :foo], [Symbol, :foo, :foo], [Symbol, nil, nil], [Symbol, '', nil],
55
+ [Date, '1985-11-05', Date.parse('1985-11-05')], [Date, nil, nil], [Date, '', nil],
56
+ [DateTime, '1985-11-05 11:00:00', DateTime.parse('1985-11-05 11:00:00')], [DateTime, nil, nil], [DateTime, '', nil],
57
+ [Time, '1985-11-05 11:00:00', Time.parse('1985-11-05 11:00:00')], [Time, nil, nil], [Time, '', nil],
58
+ ].each do |type, orig, desired|
59
+ it "for #{type} converts #{orig.inspect} to #{desired.inspect}" do
60
+ @config.define :param, :type => type
61
+ @config[:param] = orig ; @config.resolve! ; @config[:param].should == desired
62
+ end
63
+ end
64
+ end
65
+
66
+
67
+ describe 'defining requireds' do
68
+ before do
69
+ @config.define :param_1, :required => true
70
+ @config.define :param_2, :required => true
71
+ @config.define :optional_1, :required => false
72
+ @config.define :optional_2
73
+ end
74
+ it 'lists required params' do
75
+ @config.required_params.should include(:param_1)
76
+ @config.required_params.should include(:param_2)
77
+ end
78
+ it 'counts false values as required' do
79
+ p [@config]
80
+ @config.defaults :param_1 => true, :param_2 => false
81
+ @config.validate!.should == true
82
+ end
83
+ it 'counts nil-but-set values as missing' do
84
+ @config.defaults :param_1 => true, :param_2 => nil
85
+ lambda{ @config.validate! }.should raise_error "Missing values for param_2"
86
+ end
87
+ it 'counts never-set values as missing' do
88
+ lambda{ @config.validate! }.should raise_error "Missing values for param_1, param_2"
89
+ end
90
+ it 'lists all missing values when it raises' do
91
+ Configliere.use :define
92
+ lambda{ p @config.validate! }.should raise_error "Missing values for param_1, param_2"
93
+ end
94
+ end
95
+ end
96
+
97
+
@@ -0,0 +1,71 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ Configliere.use :encrypted
3
+
4
+ describe "Configliere::Encrypted" do
5
+ before do
6
+ @config = Configliere::Param.new :secret => 'encrypt_me', :normal_param => 'normal'
7
+ @config.define :secret, :encrypted => true
8
+ @config.encrypt_pass = 'pass'
9
+ end
10
+
11
+ describe 'defining encrypted params' do
12
+ it 'is encrypted if defined with :encrypted => true' do
13
+ @config.send(:encrypted_params).should include(:secret)
14
+ end
15
+ it 'is not encrypted if defined with :encrypted => false' do
16
+ @config.define :another_param, :encrypted => false
17
+ @config.send(:encrypted_params).should_not include(:another_param)
18
+ @config.send(:encrypted_params).should include(:secret)
19
+ end
20
+ it 'is encrypted if not defined' do
21
+ @config.send(:encrypted_params).should_not include(:missing_param)
22
+ end
23
+ end
24
+
25
+ describe 'encrypting encryptable params' do
26
+ it 'encrypts all params marked encrypted' do
27
+ Configliere::Crypter.should_receive(:encrypt).with('encrypt_me', 'pass').and_return('ok_encrypted')
28
+ @config.send(:export).should == { :normal_param => 'normal', :encrypted_secret => 'ok_encrypted'}
29
+ end
30
+ it 'gets encrypted params successfully' do
31
+ Configliere::Crypter.should_receive(:encrypt).with('encrypt_me', 'pass').and_return('ok_encrypted')
32
+ @config.send(:encrypted, @config[:secret]).should == 'ok_encrypted'
33
+ end
34
+ it 'fails if no pass is set' do
35
+ # create the config but don't set an encrypt_pass
36
+ @config = Configliere::Param.new :secret => 'encrypt_me', :normal_param => 'normal'
37
+ lambda{ @config.send(:encrypted, @config[:secret]) }.should raise_error('Blank encryption password!')
38
+ end
39
+ end
40
+
41
+ describe 'decrypting encryptable params' do
42
+ it 'decrypts all params marked encrypted' do
43
+ @config.delete :secret
44
+ @config.defaults :encrypted_secret => 'decrypt_me'
45
+ Configliere::Crypter.should_receive(:decrypt).with('decrypt_me', 'pass').and_return('ok_decrypted')
46
+ @config.send(:resolve_encrypted!)
47
+ @config.should == { :normal_param => 'normal', :secret => 'ok_decrypted'}
48
+ end
49
+ end
50
+
51
+ describe 'loading a file' do
52
+ before do
53
+ @encrypted_str = "*\210BM\305\353\325\240.\226\212g\266f|\177\221\252k\263\363\260\031\263\371\035\257\024f+\001\350"
54
+ end
55
+ it 'encrypts' do
56
+ Configliere::Crypter.should_receive(:encrypt).and_return(@encrypted_str)
57
+ Configliere::ParamStore.should_receive(:write_yaml_file).with('/fake/file', :normal_param=>"normal", :encrypted_secret => @encrypted_str)
58
+ @config.save! '/fake/file'
59
+ end
60
+ it 'decrypts' do
61
+ @hsh = { :loaded_param => "loaded", :encrypted_secret => @encrypted_str }
62
+ File.stub(:open)
63
+ YAML.should_receive(:load).and_return(@hsh)
64
+ @config.read 'file.yaml'
65
+ @config.resolve!
66
+ @config.should == { :loaded_param => "loaded", :secret => 'decrypt_me', :normal_param => 'normal' }
67
+ end
68
+ end
69
+ end
70
+
71
+
@@ -0,0 +1,23 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ Configliere.use :environment
3
+
4
+ describe "Configliere::Environment" do
5
+ before do
6
+ @config = Configliere::Param.new
7
+ end
8
+
9
+ describe 'loads environment variables' do
10
+ it 'loads a simple value into the corresponding symbolic key' do
11
+ ENV.should_receive(:[]).with('HOME').and_return('/fake/path')
12
+ @config.environment_variables 'HOME'
13
+ @config[:home].should == '/fake/path'
14
+ end
15
+ it 'loads a hash into the individual params' do
16
+ ENV.should_receive(:[]).with('HOME').and_return('/fake/path')
17
+ ENV.should_receive(:[]).with('POWER_SUPPLY').and_return('1.21 jigawatts')
18
+ @config.environment_variables 'HOME' => :home, 'POWER_SUPPLY' => 'delorean.power_supply'
19
+ @config[:home].should == '/fake/path'
20
+ @config[:delorean][:power_supply].should == '1.21 jigawatts'
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,43 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Configliere::Param" do
4
+ before do
5
+ @config = Configliere::Param.new
6
+ end
7
+
8
+ describe '#defaults' do
9
+ it 'merges new params' do
10
+ @config.defaults :hat => :cat, :basket => :lotion, :moon => { :man => :smiling }
11
+ @config.defaults :basket => :tasket, :moon => { :cow => :jumping }
12
+ @config.should == { :hat => :cat, :basket => :tasket, :moon => { :man => :smiling, :cow => :jumping } }
13
+ end
14
+ end
15
+
16
+ describe 'setting vals' do
17
+ it 'symbolizes keys' do
18
+ @config.defaults :hat => :cat, :basket => :lotion
19
+ @config['hat'] = :fedora
20
+ @config['new'] = :unseen
21
+ @config.should == { :hat => :fedora, :basket => :lotion, :new => :unseen }
22
+ end
23
+ it 'deep-sets dotted vals' do
24
+ @config.defaults :hat => :cat, :basket => :lotion, :moon => { :man => :smiling }
25
+ @config['moon.man'] = :cheesy
26
+ @config[:moon][:man].should == :cheesy
27
+ @config['moon.cheese.type'] = :tilsit
28
+ @config[:moon][:cheese][:type].should == :tilsit
29
+ end
30
+ it 'deep-gets dotted vals' do
31
+ hsh = { :hat => :cat, :basket => :lotion, :moon => { :man => :smiling, :cheese => {:type => :tilsit} } }
32
+ @config.defaults hsh
33
+ @config['moon.man'].should == :smiling
34
+ @config['moon.cheese.type'].should == :tilsit
35
+ @config['moon.cheese.smell'].should be_nil
36
+ @config['moon.non.existent.interim.values'].should be_nil
37
+ @config['moon.non'].should be_nil
38
+ lambda{ @config['hat.cat'] }.should raise_error(NoMethodError, 'undefined method `[]\' for :cat:Symbol')
39
+ @config.should == hsh # shouldn't change from reading
40
+ end
41
+ end
42
+
43
+ end
@@ -0,0 +1,81 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ Configliere.use :param_store
3
+
4
+ describe "Configliere::ParamStore" do
5
+ before do
6
+ @config = Configliere.new :my_param => 'val'
7
+ end
8
+
9
+ describe 'loads a config file' do
10
+ before do
11
+ @config = Configliere::Param.new :my_param => 'val'
12
+ @fake_file = '{ :my_param: val }'
13
+ end
14
+ describe 'successfully' do
15
+ it 'loads a symbol name from the default config file' do
16
+ File.should_receive(:open).with(Configliere::DEFAULT_CONFIG_FILE).and_return(':my_settings: ' + @fake_file)
17
+ @config.read :my_settings
18
+ end
19
+ it 'loads an absolute pathname from the given file' do
20
+ File.should_receive(:open).with('/fake/path.yaml').and_return(@fake_file)
21
+ @config.read '/fake/path.yaml'
22
+ end
23
+ it 'loads a simple filename from the default config dir' do
24
+ File.should_receive(:open).with(Configliere::DEFAULT_CONFIG_DIR + '/file.yaml').and_return(@fake_file)
25
+ @config.read 'file.yaml'
26
+ end
27
+ after do
28
+ @config[:my_param].should == 'val'
29
+ end
30
+ end
31
+ describe 'in edge cases' do
32
+ it 'handles a file not found' do
33
+ @config = Configliere::Param.new
34
+ File.stub(:open).and_raise(Errno::ENOENT)
35
+ @config.read('nonexistent_file.yaml').should == {}
36
+ end
37
+ end
38
+ end
39
+
40
+ describe 'saves to a config file' do
41
+ describe 'successfully' do
42
+ it 'saves a symbol name to the default config file' do
43
+ Configliere::ParamStore.should_receive(:merge_into_yaml_file).
44
+ with(Configliere::DEFAULT_CONFIG_FILE, :my_settings, { :my_param => 'val'})
45
+ @config.save! :my_settings
46
+ end
47
+ it 'saves a pathname to the given file' do
48
+ fake_file = StringIO.new('', 'w')
49
+ File.should_receive(:open).with('/fake/path.yaml', 'w').and_yield(fake_file)
50
+ fake_file.should_receive(:<<).with("--- \n:my_param: val\n")
51
+ @config.save! '/fake/path.yaml'
52
+ end
53
+ end
54
+ end
55
+
56
+ describe 'merge_into_yaml_file' do
57
+ it 'merges, leaving existing values put' do
58
+ fake_file = StringIO.new(":my_settings: { :my_param: orig_val }\n:other_settings: { :that_param: other_val }", 'r+')
59
+ File.should_receive(:open).with('/fake/path.yaml').and_return(fake_file)
60
+ File.should_receive(:open).with('/fake/path.yaml', 'w').and_yield(fake_file)
61
+ mock_dump = 'mock_dump'
62
+ YAML.should_receive(:dump).with({ :my_settings => { :my_param => 'new_val'}, :other_settings => { :that_param => 'other_val'}}).and_return(mock_dump)
63
+ fake_file.should_receive(:<<).with(mock_dump)
64
+ Configliere::ParamStore.merge_into_yaml_file '/fake/path.yaml', :my_settings, :my_param => 'new_val'
65
+ end
66
+ end
67
+
68
+ describe 'maps handles to filenames' do
69
+ it 'loads a symbol name from the default config file' do
70
+ @config.send(:filename_for_handle, :my_settings).should == Configliere::DEFAULT_CONFIG_FILE
71
+ end
72
+ it 'loads an absolute pathname from the given file' do
73
+ @config.send(:filename_for_handle, '/fake/path.yaml').should == '/fake/path.yaml'
74
+ end
75
+ it 'loads a simple filename from the default config dir' do
76
+ @config.send(:filename_for_handle, 'file.yaml').should == Configliere::DEFAULT_CONFIG_DIR + '/file.yaml'
77
+ end
78
+ end
79
+
80
+ end
81
+
@@ -0,0 +1,21 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Configliere" do
4
+ it 'creates a new param on new' do
5
+ mock_param = 'mock_param'
6
+ Configliere::Param.should_receive(:new).with(:this => :that).and_return(mock_param)
7
+ Configliere.new(:this => :that).should == mock_param
8
+ end
9
+ it 'creates a global variable Settings' do
10
+ Settings.class.should == Configliere::Param
11
+ end
12
+ it 'creates a glocal method Settings' do
13
+ Settings.should_receive(:defaults).with(:foo => :bar)
14
+ Settings(:foo => :bar)
15
+ end
16
+
17
+ it 'requires modules with use' do
18
+ lambda{ Configliere.use(:param, :foo) }.should raise_error(LoadError, 'no such file to load -- configliere/foo')
19
+ end
20
+
21
+ end