configliere 0.3.4 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/.document +3 -0
  2. data/.watchr +20 -0
  3. data/CHANGELOG.textile +99 -3
  4. data/Gemfile +26 -0
  5. data/Gemfile.lock +54 -0
  6. data/README.textile +162 -138
  7. data/Rakefile +30 -21
  8. data/VERSION +1 -1
  9. data/bin/configliere +77 -77
  10. data/bin/configliere-decrypt +85 -0
  11. data/bin/configliere-delete +85 -0
  12. data/bin/configliere-dump +85 -0
  13. data/bin/configliere-encrypt +85 -0
  14. data/bin/configliere-list +85 -0
  15. data/bin/configliere-set +85 -0
  16. data/configliere.gemspec +53 -23
  17. data/examples/config_block_script.rb +9 -2
  18. data/examples/encrypted_script.rb +28 -16
  19. data/examples/env_var_script.rb +2 -2
  20. data/examples/help_message_demo.rb +16 -0
  21. data/examples/independent_config.rb +28 -0
  22. data/examples/prompt.rb +23 -0
  23. data/examples/simple_script.rb +28 -15
  24. data/examples/simple_script.yaml +1 -1
  25. data/lib/configliere.rb +22 -24
  26. data/lib/configliere/commandline.rb +135 -116
  27. data/lib/configliere/commands.rb +38 -54
  28. data/lib/configliere/config_block.rb +4 -2
  29. data/lib/configliere/config_file.rb +30 -52
  30. data/lib/configliere/crypter.rb +8 -5
  31. data/lib/configliere/deep_hash.rb +368 -0
  32. data/lib/configliere/define.rb +83 -89
  33. data/lib/configliere/encrypted.rb +17 -18
  34. data/lib/configliere/env_var.rb +5 -7
  35. data/lib/configliere/param.rb +37 -64
  36. data/lib/configliere/prompt.rb +23 -0
  37. data/spec/configliere/commandline_spec.rb +156 -57
  38. data/spec/configliere/commands_spec.rb +75 -30
  39. data/spec/configliere/config_block_spec.rb +10 -1
  40. data/spec/configliere/config_file_spec.rb +83 -55
  41. data/spec/configliere/crypter_spec.rb +3 -2
  42. data/spec/configliere/deep_hash_spec.rb +401 -0
  43. data/spec/configliere/define_spec.rb +121 -42
  44. data/spec/configliere/encrypted_spec.rb +53 -20
  45. data/spec/configliere/env_var_spec.rb +24 -4
  46. data/spec/configliere/param_spec.rb +25 -27
  47. data/spec/configliere/prompt_spec.rb +50 -0
  48. data/spec/configliere_spec.rb +3 -9
  49. data/spec/spec_helper.rb +17 -6
  50. metadata +110 -35
  51. data/lib/configliere/core_ext.rb +0 -2
  52. data/lib/configliere/core_ext/blank.rb +0 -93
  53. data/lib/configliere/core_ext/hash.rb +0 -108
  54. data/lib/configliere/core_ext/sash.rb +0 -170
  55. data/spec/configliere/core_ext/hash_spec.rb +0 -78
  56. data/spec/configliere/core_ext/sash_spec.rb +0 -312
@@ -1,108 +0,0 @@
1
- #
2
- # core_ext/hash.rb -- hash extensions
3
- #
4
- class Hash
5
-
6
- # lambda for recursive merges
7
- ::Hash::DEEP_MERGER = proc do |key,v1,v2|
8
- (v1.respond_to?(:merge) && v2.respond_to?(:merge)) ? v1.merge(v2.compact, &Hash::DEEP_MERGER) : (v2.nil? ? v1 : v2)
9
- end unless defined?(::Hash::DEEP_MERGER)
10
-
11
- #
12
- # Merge hashes recursively.
13
- # Nothing special happens to array values
14
- #
15
- # x = { :subhash => { 1 => :val_from_x, 222 => :only_in_x, 333 => :only_in_x }, :scalar => :scalar_from_x}
16
- # y = { :subhash => { 1 => :val_from_y, 999 => :only_in_y }, :scalar => :scalar_from_y }
17
- # x.deep_merge y
18
- # => {:subhash=>{1=>:val_from_y, 222=>:only_in_x, 333=>:only_in_x, 999=>:only_in_y}, :scalar=>:scalar_from_y}
19
- # y.deep_merge x
20
- # => {:subhash=>{1=>:val_from_x, 222=>:only_in_x, 333=>:only_in_x, 999=>:only_in_y}, :scalar=>:scalar_from_x}
21
- #
22
- # Nil values always lose.
23
- #
24
- # x = {:subhash=>{:nil_in_x=>nil, 1=>:val1,}, :nil_in_x=>nil}
25
- # y = {:subhash=>{:nil_in_x=>5}, :nil_in_x=>5}
26
- # y.deep_merge x
27
- # => {:subhash=>{1=>:val1, :nil_in_x=>5}, :nil_in_x=>5}
28
- # x.deep_merge y
29
- # => {:subhash=>{1=>:val1, :nil_in_x=>5}, :nil_in_x=>5}
30
- #
31
- def deep_merge hsh2
32
- merge hsh2, &Hash::DEEP_MERGER
33
- end unless method_defined?(:deep_merge)
34
-
35
- def deep_merge! hsh2
36
- update hsh2, &Hash::DEEP_MERGER
37
- self
38
- end unless method_defined?(:deep_merge!)
39
-
40
- #
41
- # Treat hash as tree of hashes:
42
- #
43
- # x = { 1 => :val, :subhash => { 1 => :val1 } }
44
- # x.deep_set(:subhash, :cat, :hat)
45
- # # => { 1 => :val, :subhash => { 1 => :val1, :cat => :hat } }
46
- # x.deep_set(:subhash, 1, :newval)
47
- # # => { 1 => :val, :subhash => { 1 => :newval, :cat => :hat } }
48
- #
49
- #
50
- def deep_set *args
51
- val = args.pop
52
- last_key = args.pop
53
- # dig down to last subtree (building out if necessary)
54
- hsh = self
55
- args.each{|key| hsh = (hsh[key] ||= self.class.new) }
56
- # set leaf value
57
- hsh[last_key] = val
58
- end unless method_defined?(:deep_set)
59
-
60
- #
61
- # Treat hash as tree of hashes:
62
- #
63
- # x = { 1 => :val, :subhash => { 1 => :val1 } }
64
- # x.deep_get(:subhash, 1)
65
- # # => :val
66
- # x.deep_get(:subhash, 2)
67
- # # => nil
68
- # x.deep_get(:subhash, 2, 3)
69
- # # => nil
70
- # x.deep_get(:subhash, 2)
71
- # # => nil
72
- #
73
- def deep_get *args
74
- last_key = args.pop
75
- # dig down to last subtree (building out if necessary)
76
- hsh = args.inject(self){|h, k| h[k] || {} }
77
- # get leaf value
78
- hsh[last_key]
79
- end unless method_defined?(:deep_get)
80
-
81
- #
82
- # Treat hash as tree of hashes:
83
- #
84
- # x = { 1 => :val, :subhash => { 1 => :val1, 2 => :val2 } }
85
- # x.deep_delete(:subhash, 1)
86
- # #=> :val
87
- # x
88
- # #=> { 1 => :val, :subhash => { 2 => :val2 } }
89
- #
90
- def deep_delete *args
91
- last_key = args.pop
92
- last_hsh = args.empty? ? self : (deep_get(*args)||{})
93
- last_hsh.delete(last_key)
94
- end unless method_defined?(:deep_delete)
95
-
96
- #
97
- # remove all key-value pairs where the value is nil
98
- #
99
- def compact
100
- reject{|key,val| val.nil? }
101
- end unless method_defined?(:compact)
102
- #
103
- # Replace the hash with its compacted self
104
- #
105
- def compact!
106
- replace(compact)
107
- end unless method_defined?(:compact!)
108
- end
@@ -1,170 +0,0 @@
1
- require 'configliere/core_ext/hash'
2
-
3
- #
4
- # Hash with indifferent access
5
- #
6
- # Adapted from extlib/lib/mash.rb
7
- #
8
- class Sash < ::Hash
9
-
10
- # @param constructor<Object>
11
- # The default value for the mash. Defaults to an empty hash.
12
- #
13
- # @details [Alternatives]
14
- # If constructor is a Hash, a new mash will be created based on the keys of
15
- # the hash and no default value will be set.
16
- def initialize(constructor = {})
17
- if constructor.is_a?(Hash)
18
- super()
19
- update(constructor) unless constructor.empty?
20
- else
21
- super(constructor)
22
- end
23
- end
24
-
25
- alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
26
- alias_method :regular_update, :update unless method_defined?(:regular_update)
27
-
28
- # @param key<Object> The key to set.
29
- # @param value<Object>
30
- # The value to set the key to.
31
- #
32
- # @see Mash#convert_key
33
- # @see Mash#convert_value
34
- def []=(key, value)
35
- regular_writer(convert_key(key), convert_value(value))
36
- end
37
-
38
- alias_method :merge!, :update
39
-
40
- # @param key<Object> The key to check for. This will be run through convert_key.
41
- #
42
- # @return [Boolean] True if the key exists in the mash.
43
- def key?(key)
44
- super(convert_key(key))
45
- end
46
-
47
- # def include? def has_key? def member?
48
- alias_method :include?, :key?
49
- alias_method :has_key?, :key?
50
- alias_method :member?, :key?
51
-
52
- # @param key<Object> The key to fetch. This will be run through convert_key.
53
- # @param *extras<Array> Default value.
54
- #
55
- # @return [Object] The value at key or the default value.
56
- def fetch(key, *extras)
57
- super(convert_key(key), *extras)
58
- end
59
-
60
- # @param *indices<Array>
61
- # The keys to retrieve values for. These will be run through +convert_key+.
62
- #
63
- # @return [Array] The values at each of the provided keys
64
- def values_at(*indices)
65
- indices.collect{|key| self[convert_key(key)]}
66
- end
67
-
68
- # @param hash<Hash> The hash to merge with the mash.
69
- #
70
- # @return [Mash] A new mash with the hash values merged in.
71
- def merge(hash, &block)
72
- self.dup.update(hash, &block)
73
- end
74
-
75
- # @param key<Object>
76
- # The key to delete from the mash.\
77
- def delete(key)
78
- super(convert_key(key))
79
- end
80
-
81
- # @return [Hash] The mash as a Hash with string keys.
82
- def to_hash
83
- Hash.new(default).merge(self)
84
- end
85
-
86
- # @param key<Object> The default value for the mash. Defaults to nil.
87
- #
88
- # @details [Alternatives]
89
- # If key is a Symbol and it is a key in the mash, then the default value will
90
- # be set to the value matching the key.
91
- def default(key = nil)
92
- if key.is_a?(String) && include?(key = key.to_sym)
93
- self[key]
94
- else
95
- super(key)
96
- end
97
- end
98
-
99
- # @param other_hash<Hash>
100
- # A hash to update values in the mash with. The keys and the values will be
101
- # converted to Mash format.
102
- #
103
- # @return [Mash] The updated mash.
104
- def update(other_hash, &block)
105
- sash = self.class.new
106
- other_hash.each_pair do |key, value|
107
- val = convert_value(value)
108
- sash[convert_key(key)] = val
109
- end
110
- regular_update(sash, &block)
111
- end
112
-
113
- # Used to provide the same interface as Hash.
114
- #
115
- # @return [Sash] This sash unchanged.
116
- def symbolize_keys!; self end
117
-
118
- # @return [Hash] The sash as a Hash with stringified keys.
119
- def stringify_keys
120
- h = Hash.new(default)
121
- each { |key, val| h[key.to_sym] = val }
122
- h
123
- end
124
-
125
- protected
126
- # @param key<Object> The key to convert.
127
- #
128
- # @param [Object]
129
- # The converted key. If the key was a string, it will be converted to a
130
- # symbol.
131
- #
132
- # @api private
133
- def convert_key(key)
134
- key.is_a?(String) ? key.to_sym : key
135
- end
136
-
137
- # @param value<Object> The value to convert.
138
- #
139
- # @return [Object]
140
- # The converted value. A Hash or an Array of hashes, will be converted to
141
- # their Mash equivalents.
142
- #
143
- # @api private
144
- def convert_value(value)
145
- if value.class == Hash
146
- value.to_sash
147
- elsif value.is_a?(Array)
148
- value.collect { |e| convert_value(e) }
149
- else
150
- value
151
- end
152
- end
153
-
154
- end
155
-
156
-
157
- class ::Hash
158
-
159
- # Convert to Sash. This class has semantics of ActiveSupport's
160
- # HashWithIndifferentAccess and we only have it so that people can write
161
- # params[:key] instead of params['key'].
162
- #
163
- # @return [Mash] This hash as a Mash for string or symbol key access.
164
- def to_sash
165
- hash = Sash.new(self)
166
- hash.default = default
167
- hash
168
- end
169
-
170
- end
@@ -1,78 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '../../spec_helper'))
2
-
3
- describe Hash do
4
- before(:each) do
5
- @hash = { :hsh1a => { :hsh2 => { :key3 => "val3" }, :key2 => "val2" }, :key1b => 'val1b' }
6
- end
7
-
8
- describe "#deep_merge!" do
9
- it "merges two subhashes when they share a key" do
10
- @hash.deep_merge!(:hsh1a => { :hsh2 => { :key3a => "val3a" } })
11
- @hash.should == { :hsh1a => { :hsh2 => { :key3a => "val3a", :key3 => "val3" }, :key2 => "val2" }, :key1b => 'val1b' }
12
- end
13
- it "preserves values in the original" do
14
- @hash.deep_merge! :other_key => "other_val"
15
- @hash[:hsh1a][:key2].should == "val2"
16
- @hash[:other_key].should == "other_val"
17
- end
18
- it "replaces values from the given Hash" do
19
- @hash.deep_merge!(:hsh1a => { :hsh2 => { :key3 => "new_val3" }, :key2 => { "other2" => "other_val2" }})
20
- @hash[:hsh1a][:hsh2][:key3].should == 'new_val3'
21
- @hash[:hsh1a][:key2].should == { "other2" => "other_val2" }
22
- end
23
- end
24
-
25
-
26
- describe "#deep_set" do
27
- it 'should set a new value (single arg)' do
28
- @hash.deep_set :new_key, 'new_val'
29
- @hash[:new_key].should == 'new_val'
30
- end
31
- it 'should set a new value (multiple args)' do
32
- @hash.deep_set :hsh1a, :hsh2, :new_key, 'new_val'
33
- @hash[:hsh1a][:hsh2][:new_key].should == 'new_val'
34
- end
35
- it 'should replace an existing value (single arg)' do
36
- @hash.deep_set :key1b, 'new_val'
37
- @hash[:key1b].should == 'new_val'
38
- end
39
- it 'should replace an existing value (multiple args)' do
40
- @hash.deep_set :hsh1a, :hsh2, 'new_val'
41
- @hash[:hsh1a][:hsh2].should == 'new_val'
42
- end
43
- it 'should auto-vivify intermediate hashes' do
44
- @hash.deep_set :one, :two, :three, :four, 'new_val'
45
- @hash[:one][:two][:three][:four].should == 'new_val'
46
- end
47
- end
48
-
49
- describe "#deep_delete" do
50
- it 'should remove the key from the array (multiple args)' do
51
- @hash.deep_delete(:hsh1a)
52
- @hash[:hsh1a].should be_nil
53
- @hash.should == { :key1b => 'val1b'}
54
- end
55
- it 'should remove the key from the array (multiple args)' do
56
- @hash.deep_delete(:hsh1a, :hsh2, :key3)
57
- @hash[:hsh1a][:hsh2][:key3].should be_nil
58
- @hash.should == {:key1b=>"val1b", :hsh1a=>{:key2=>"val2", :hsh2=>{}}}
59
- end
60
- it 'should return the value if present (single args)' do
61
- returned_val = @hash.deep_delete(:key1b)
62
- returned_val.should == 'val1b'
63
- end
64
- it 'should return the value if present (multiple args)' do
65
- returned_val = @hash.deep_delete(:hsh1a, :hsh2, :key3)
66
- returned_val.should == 'val3'
67
- end
68
- it 'should return nil if the key is absent (single arg)' do
69
- returned_val = @hash.deep_delete(:hsh1a, :hsh2, :missing_key)
70
- returned_val.should be_nil
71
- end
72
- it 'should return nil if the key is absent (multiple args)' do
73
- returned_val = @hash.deep_delete(:missing_key)
74
- returned_val.should be_nil
75
- end
76
- end
77
-
78
- end
@@ -1,312 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '../../spec_helper'))
2
-
3
- class AwesomeHash < Hash
4
- end
5
-
6
- describe Sash do
7
- before(:each) do
8
- @hash = { "str_key" => "strk_val", :sym_key => "symk_val"}
9
- @sub = AwesomeHash.new("str_key" => "strk_val", :sym_key => "symk_val")
10
- end
11
-
12
- describe "#deep_merge!" do
13
- before do
14
- @sash = Sash.new :hsh1 => { :hsh2 => { :key3 => "val3" }, :key2 => "val2" }
15
- end
16
- it "merges two subhashes when they share a key" do
17
- @sash.deep_merge!(:hsh1 => { :hsh2 => { :key3a => "val3a" } })
18
- @sash.should == { :hsh1 => { :hsh2 => { :key3a => "val3a", :key3 => "val3" }, :key2 => "val2" } }
19
- end
20
- it "merges two subhashes when they share a symbolized key" do
21
- @sash.deep_merge!(:hsh1 => { "hsh2" => { "key3a" => "val3a" } })
22
- @sash.should == { :hsh1 => { :hsh2 => { :key3a => "val3a", :key3 => "val3" }, :key2 => "val2" } }
23
- end
24
- it "preserves values in the original" do
25
- @sash.deep_merge! :other_key => "other_val"
26
- @sash[:other_key].should == "other_val"
27
- @sash[:hsh1][:key2].should == "val2"
28
- end
29
-
30
- it "converts all keys into symbols when param is a Hash" do
31
- @sash.deep_merge!(:hsh1 => { "hsh2" => { "key3a" => "val3a" } })
32
- @sash.should == { :hsh1 => { :hsh2 => { :key3a => "val3a", :key3 => "val3" }, :key2 => "val2" } }
33
- end
34
- it "converts all Hash values into Sashes if param is a Hash" do
35
- @sash.deep_merge!({:hsh1 => { :hsh2 => { :key3a => "val3a" } }, :other1 => { "other2" => "other_val2" }})
36
- @sash[:hsh1].should be_an_instance_of(Sash)
37
- @sash[:hsh1][:hsh2].should be_an_instance_of(Sash)
38
- @sash[:other1].should be_an_instance_of(Sash)
39
- end
40
- it "replaces values from the given Hash" do
41
- @sash.deep_merge!(:hsh1 => { :hsh2 => { :key3 => "new_val3" }, :key2 => { "other2" => "other_val2" }})
42
- @sash[:hsh1][:hsh2][:key3].should == 'new_val3'
43
- @sash[:hsh1][:key2].should == { :other2 => "other_val2" }
44
- end
45
- end
46
-
47
- describe "#initialize" do
48
- it 'converts all keys into symbols when param is a Hash' do
49
- sash = Sash.new(@hash)
50
- sash.keys.any? { |key| key.is_a?(String) }.should be_false
51
- end
52
-
53
- it 'converts all pure Hash values into Sashes if param is a Hash' do
54
- sash = Sash.new :sym_key => @hash
55
-
56
- sash[:sym_key].should be_an_instance_of(Sash)
57
- # sanity check
58
- sash[:sym_key][:sym_key].should == "symk_val"
59
- end
60
-
61
- it 'does not convert Hash subclass values into Sashes' do
62
- sash = Sash.new :sub => @sub
63
- sash[:sub].should be_an_instance_of(AwesomeHash)
64
- end
65
-
66
- it 'converts all value items if value is an Array' do
67
- sash = Sash.new :arry => { :sym_key => [@hash] }
68
-
69
- sash[:arry].should be_an_instance_of(Sash)
70
- # sanity check
71
- sash[:arry][:sym_key].first[:sym_key].should == "symk_val"
72
-
73
- end
74
-
75
- it 'delegates to superclass constructor if param is not a Hash' do
76
- sash = Sash.new("dash berlin")
77
-
78
- sash["unexisting key"].should == "dash berlin"
79
- end
80
- end # describe "#initialize"
81
-
82
-
83
-
84
- describe "#update" do
85
- it 'converts all keys into symbols when param is a Hash' do
86
- sash = Sash.new(@hash)
87
- sash.update("starry" => "night")
88
-
89
- sash.keys.any?{|key| key.is_a?(String) }.should be_false
90
- end
91
-
92
- it 'converts all Hash values into Sashes if param is a Hash' do
93
- sash = Sash.new :hash => @hash
94
- sash.update(:hash => { :sym_key => "is buggy in Ruby 1.8.6" })
95
-
96
- sash[:hash].should be_an_instance_of(Sash)
97
- end
98
- end # describe "#update"
99
-
100
-
101
-
102
- describe "#[]=" do
103
- it 'converts key into symbol' do
104
- sash = Sash.new(@hash)
105
- sash["str_key"] = { "starry" => "night" }
106
-
107
- sash.keys.any?{|key| key.is_a?(String) }.should be_false
108
- end
109
-
110
- it 'converts all Hash value into Sash' do
111
- sash = Sash.new :hash => @hash
112
- sash[:hash] = { :sym_key => "is buggy in Ruby 1.8.6" }
113
-
114
- sash[:hash].should be_an_instance_of(Sash)
115
- end
116
- end # describe "#[]="
117
-
118
-
119
-
120
- describe "#key?" do
121
- before(:each) do
122
- @sash = Sash.new(@hash)
123
- end
124
-
125
- it 'converts key before lookup' do
126
- @sash.key?("str_key").should be_true
127
- @sash.key?(:str_key).should be_true
128
-
129
- @sash.key?("sym_key").should be_true
130
- @sash.key?(:sym_key).should be_true
131
-
132
- @sash.key?(:rainclouds).should be_false
133
- @sash.key?("rainclouds").should be_false
134
- end
135
-
136
- it 'is aliased as include?' do
137
- @sash.include?("str_key").should be_true
138
- @sash.include?(:str_key).should be_true
139
-
140
- @sash.include?("sym_key").should be_true
141
- @sash.include?(:sym_key).should be_true
142
-
143
- @sash.include?(:rainclouds).should be_false
144
- @sash.include?("rainclouds").should be_false
145
- end
146
-
147
- it 'is aliased as member?' do
148
- @sash.member?("str_key").should be_true
149
- @sash.member?(:str_key).should be_true
150
-
151
- @sash.member?("sym_key").should be_true
152
- @sash.member?(:sym_key).should be_true
153
-
154
- @sash.member?(:rainclouds).should be_false
155
- @sash.member?("rainclouds").should be_false
156
- end
157
- end # describe "#key?"
158
-
159
- def arrays_should_be_equal arr1, arr2
160
- arr1.sort_by{|s| s.to_s }.should == arr2.sort_by{|s| s.to_s }
161
- end
162
-
163
- describe "#dup" do
164
- it 'returns instance of Sash' do
165
- Sash.new(@hash).dup.should be_an_instance_of(Sash)
166
- end
167
-
168
- it 'preserves keys' do
169
- sash = Sash.new(@hash)
170
- dup = sash.dup
171
-
172
- arrays_should_be_equal sash.keys, dup.keys
173
- end
174
-
175
- it 'preserves value' do
176
- sash = Sash.new(@hash)
177
- dup = sash.dup
178
-
179
- arrays_should_be_equal sash.values, dup.values
180
- end
181
- end
182
-
183
-
184
-
185
- describe "#to_hash" do
186
- it 'returns instance of Hash' do
187
- Sash.new(@hash).to_hash.should be_an_instance_of(Hash)
188
- end
189
-
190
- it 'preserves keys' do
191
- sash = Sash.new(@hash)
192
- converted = sash.to_hash
193
- arrays_should_be_equal sash.keys, converted.keys
194
- end
195
-
196
- it 'preserves value' do
197
- sash = Sash.new(@hash)
198
- converted = sash.to_hash
199
- arrays_should_be_equal sash.values, converted.values
200
- end
201
- end
202
-
203
-
204
-
205
- describe "#stringify_keys" do
206
- it 'returns instance of Sash' do
207
- Sash.new(@hash).stringify_keys.should be_an_instance_of(Hash)
208
- end
209
-
210
- it 'converts keys to symbols' do
211
- sash = Sash.new(@hash)
212
- converted = sash.stringify_keys
213
-
214
- converted_keys = converted.keys.sort{|k1, k2| k1.to_s <=> k2.to_s}
215
- orig_keys = sash.keys.map{|k| k.to_sym}.sort{|i1, i2| i1.to_s <=> i2.to_s}
216
-
217
- converted_keys.should == orig_keys
218
- end
219
-
220
- it 'preserves value' do
221
- sash = Sash.new(@hash)
222
- converted = sash.stringify_keys
223
-
224
- arrays_should_be_equal sash.values, converted.values
225
- end
226
- end
227
-
228
-
229
-
230
- describe "#delete" do
231
- it 'converts Symbol key into String before deleting' do
232
- sash = Sash.new(@hash)
233
-
234
- sash.delete(:sym_key)
235
- sash.key?("hash").should be_false
236
- end
237
-
238
- it 'works with String keys as well' do
239
- sash = Sash.new(@hash)
240
-
241
- sash.delete("str_key")
242
- sash.key?("str_key").should be_false
243
- end
244
- end
245
-
246
-
247
-
248
- describe "#merge" do
249
- before(:each) do
250
- @sash = Sash.new(@hash).merge(:no => "in between")
251
- end
252
-
253
- it 'returns instance of Sash' do
254
- @sash.should be_an_instance_of(Sash)
255
- end
256
-
257
- it 'merges in give Hash' do
258
- @sash["no"].should == "in between"
259
- end
260
- end
261
-
262
-
263
-
264
- describe "#fetch" do
265
- before(:each) do
266
- @sash = Sash.new(@hash).merge(:no => "in between")
267
- end
268
-
269
- it 'converts key before fetching' do
270
- @sash.fetch("no").should == "in between"
271
- end
272
-
273
- it 'returns alternative value if key lookup fails' do
274
- @sash.fetch("flying", "screwdriver").should == "screwdriver"
275
- end
276
- end
277
-
278
-
279
- describe "#default" do
280
- before(:each) do
281
- @sash = Sash.new(:yet_another_technical_revolution)
282
- end
283
-
284
- it 'returns default value unless key exists in sash' do
285
- @sash.default("peak oil is now behind, baby").should == :yet_another_technical_revolution
286
- end
287
-
288
- it 'returns existing value if key is String and exists in sash' do
289
- @sash.update("no" => "in between")
290
- @sash.default("no").should == "in between"
291
- end
292
- end
293
-
294
-
295
- describe "#values_at" do
296
- before(:each) do
297
- @sash = Sash.new(@hash).merge(:no => "in between")
298
- end
299
-
300
- it 'is indifferent to whether keys are strings or symbols' do
301
- @sash.values_at("sym_key", :str_key, :no).should == ["symk_val", "strk_val", "in between"]
302
- end
303
- end
304
-
305
-
306
- describe "#symbolize_keys!" do
307
- it 'returns the sash itself' do
308
- sash = Sash.new(@hash)
309
- sash.symbolize_keys!.object_id.should == sash.object_id
310
- end
311
- end
312
- end