configliere 0.3.4 → 0.4.4

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