rails_config_i18n 0.3.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/.bundle/config +2 -0
  2. data/.gitignore +4 -0
  3. data/Gemfile +10 -0
  4. data/LICENSE +23 -0
  5. data/README.md +243 -0
  6. data/Rakefile +28 -0
  7. data/autotest/discover.rb +2 -0
  8. data/init.rb +1 -0
  9. data/lib/generators/rails_config/install_generator.rb +32 -0
  10. data/lib/generators/rails_config/templates/rails_config.rb +4 -0
  11. data/lib/generators/rails_config/templates/settings/development.yml +1 -0
  12. data/lib/generators/rails_config/templates/settings/production.yml +1 -0
  13. data/lib/generators/rails_config/templates/settings/test.yml +1 -0
  14. data/lib/generators/rails_config/templates/settings.local.yml +1 -0
  15. data/lib/generators/rails_config/templates/settings.yml +1 -0
  16. data/lib/rails_config/integration/rails.rb +38 -0
  17. data/lib/rails_config/integration/sinatra.rb +31 -0
  18. data/lib/rails_config/options.rb +100 -0
  19. data/lib/rails_config/rack/reloader.rb +15 -0
  20. data/lib/rails_config/rails_config.rb +55 -0
  21. data/lib/rails_config/sources/yaml_source.rb +24 -0
  22. data/lib/rails_config/vendor/deep_merge.rb +180 -0
  23. data/lib/rails_config/version.rb +3 -0
  24. data/lib/rails_config_i18n.rb +1 -0
  25. data/rails_config.gemspec +26 -0
  26. data/spec/fixtures/bool_override/config1.yml +2 -0
  27. data/spec/fixtures/bool_override/config2.yml +2 -0
  28. data/spec/fixtures/custom_types/hash.yml +7 -0
  29. data/spec/fixtures/deep_merge/config1.yml +28 -0
  30. data/spec/fixtures/deep_merge/config2.yml +28 -0
  31. data/spec/fixtures/deep_merge2/config1.yml +3 -0
  32. data/spec/fixtures/deep_merge2/config2.yml +2 -0
  33. data/spec/fixtures/development.yml +4 -0
  34. data/spec/fixtures/empty1.yml +0 -0
  35. data/spec/fixtures/empty2.yml +0 -0
  36. data/spec/fixtures/locales/settings.en.yml +3 -0
  37. data/spec/fixtures/locales/settings.zh-CN.yml +2 -0
  38. data/spec/fixtures/settings.yml +3 -0
  39. data/spec/fixtures/settings2.yml +1 -0
  40. data/spec/fixtures/with_erb.yml +4 -0
  41. data/spec/rails_config_spec.rb +235 -0
  42. data/spec/sources/yaml_source_spec.rb +69 -0
  43. data/spec/spec_helper.rb +25 -0
  44. metadata +191 -0
@@ -0,0 +1,180 @@
1
+ module DeepMerge
2
+ class InvalidParameter < StandardError; end
3
+
4
+ DEFAULT_FIELD_KNOCKOUT_PREFIX = '--'
5
+
6
+ # Deep Merge core documentation.
7
+ # deep_merge! method permits merging of arbitrary child elements. The two top level
8
+ # elements must be hashes. These hashes can contain unlimited (to stack limit) levels
9
+ # of child elements. These child elements to not have to be of the same types.
10
+ # Where child elements are of the same type, deep_merge will attempt to merge them together.
11
+ # Where child elements are not of the same type, deep_merge will skip or optionally overwrite
12
+ # the destination element with the contents of the source element at that level.
13
+ # So if you have two hashes like this:
14
+ # source = {:x => [1,2,3], :y => 2}
15
+ # dest = {:x => [4,5,'6'], :y => [7,8,9]}
16
+ # dest.deep_merge!(source)
17
+ # Results: {:x => [1,2,3,4,5,'6'], :y => 2}
18
+ # By default, "deep_merge!" will overwrite any unmergeables and merge everything else.
19
+ # To avoid this, use "deep_merge" (no bang/exclamation mark)
20
+ #
21
+ # Options:
22
+ # Options are specified in the last parameter passed, which should be in hash format:
23
+ # hash.deep_merge!({:x => [1,2]}, {:knockout_prefix => '--'})
24
+ # :preserve_unmergeables DEFAULT: false
25
+ # Set to true to skip any unmergeable elements from source
26
+ # :knockout_prefix DEFAULT: nil
27
+ # Set to string value to signify prefix which deletes elements from existing element
28
+ # :sort_merged_arrays DEFAULT: false
29
+ # Set to true to sort all arrays that are merged together
30
+ # :unpack_arrays DEFAULT: nil
31
+ # Set to string value to run "Array::join" then "String::split" against all arrays
32
+ # :merge_debug DEFAULT: false
33
+ # Set to true to get console output of merge process for debugging
34
+ #
35
+ # Selected Options Details:
36
+ # :knockout_prefix => The purpose of this is to provide a way to remove elements
37
+ # from existing Hash by specifying them in a special way in incoming hash
38
+ # source = {:x => ['--1', '2']}
39
+ # dest = {:x => ['1', '3']}
40
+ # dest.ko_deep_merge!(source)
41
+ # Results: {:x => ['2','3']}
42
+ # Additionally, if the knockout_prefix is passed alone as a string, it will cause
43
+ # the entire element to be removed:
44
+ # source = {:x => '--'}
45
+ # dest = {:x => [1,2,3]}
46
+ # dest.ko_deep_merge!(source)
47
+ # Results: {:x => ""}
48
+ # :unpack_arrays => The purpose of this is to permit compound elements to be passed
49
+ # in as strings and to be converted into discrete array elements
50
+ # irsource = {:x => ['1,2,3', '4']}
51
+ # dest = {:x => ['5','6','7,8']}
52
+ # dest.deep_merge!(source, {:unpack_arrays => ','})
53
+ # Results: {:x => ['1','2','3','4','5','6','7','8'}
54
+ # Why: If receiving data from an HTML form, this makes it easy for a checkbox
55
+ # to pass multiple values from within a single HTML element
56
+ #
57
+ # There are many tests for this library - and you can learn more about the features
58
+ # and usages of deep_merge! by just browsing the test examples
59
+ def DeepMerge.deep_merge!(source, dest, options = {})
60
+ # turn on this line for stdout debugging text
61
+ merge_debug = options[:merge_debug] || false
62
+ overwrite_unmergeable = !options[:preserve_unmergeables]
63
+ knockout_prefix = options[:knockout_prefix] || nil
64
+ if knockout_prefix == ""; raise InvalidParameter, "knockout_prefix cannot be an empty string in deep_merge!"; end
65
+ if knockout_prefix && !overwrite_unmergeable; raise InvalidParameter, "overwrite_unmergeable must be true if knockout_prefix is specified in deep_merge!"; end
66
+ # if present: we will split and join arrays on this char before merging
67
+ array_split_char = options[:unpack_arrays] || false
68
+ # request that we sort together any arrays when they are merged
69
+ sort_merged_arrays = options[:sort_merged_arrays] || false
70
+ di = options[:debug_indent] || ''
71
+ # do nothing if source is nil
72
+ if source.nil? || (!source.is_a?(FalseClass) && source.respond_to?(:blank?) && source.blank?); return dest; end
73
+ # if dest doesn't exist, then simply copy source to it
74
+ if dest.nil? && overwrite_unmergeable; dest = source; return dest; end
75
+
76
+ puts "#{di}Source class: #{source.class.inspect} :: Dest class: #{dest.class.inspect}" if merge_debug
77
+ if source.kind_of?(Hash)
78
+ puts "#{di}Hashes: #{source.inspect} :: #{dest.inspect}" if merge_debug
79
+ source.each do |src_key, src_value|
80
+ if dest.kind_of?(Hash)
81
+ puts "#{di} looping: #{src_key.inspect} => #{src_value.inspect} :: #{dest.inspect}" if merge_debug
82
+ if !dest[src_key].nil?
83
+ puts "#{di} ==>merging: #{src_key.inspect} => #{src_value.inspect} :: #{dest[src_key].inspect}" if merge_debug
84
+ dest[src_key] = deep_merge!(src_value, dest[src_key], options.merge(:debug_indent => di + ' '))
85
+ else # dest[src_key] doesn't exist so we want to create and overwrite it (but we do this via deep_merge!)
86
+ puts "#{di} ==>merging over: #{src_key.inspect} => #{src_value.inspect}" if merge_debug
87
+ # note: we rescue here b/c some classes respond to "dup" but don't implement it (Numeric, TrueClass, FalseClass, NilClass among maybe others)
88
+ begin
89
+ src_dup = src_value.dup # we dup src_value if possible because we're going to merge into it (since dest is empty)
90
+ rescue TypeError
91
+ src_dup = src_value
92
+ end
93
+ dest[src_key] = deep_merge!(src_value, src_dup, options.merge(:debug_indent => di + ' '))
94
+ end
95
+ else # dest isn't a hash, so we overwrite it completely (if permitted)
96
+ if overwrite_unmergeable
97
+ puts "#{di} overwriting dest: #{src_key.inspect} => #{src_value.inspect} -over-> #{dest.inspect}" if merge_debug
98
+ dest = overwrite_unmergeables(source, dest, options)
99
+ end
100
+ end
101
+ end
102
+ elsif source.kind_of?(Array)
103
+ puts "#{di}Arrays: #{source.inspect} :: #{dest.inspect}" if merge_debug
104
+ # if we are instructed, join/split any source arrays before processing
105
+ if array_split_char
106
+ puts "#{di} split/join on source: #{source.inspect}" if merge_debug
107
+ source = source.join(array_split_char).split(array_split_char)
108
+ if dest.kind_of?(Array); dest = dest.join(array_split_char).split(array_split_char); end
109
+ end
110
+ # if there's a naked knockout_prefix in source, that means we are to truncate dest
111
+ if source.index(knockout_prefix); dest = clear_or_nil(dest); source.delete(knockout_prefix); end
112
+ if dest.kind_of?(Array)
113
+ if knockout_prefix
114
+ print "#{di} knocking out: " if merge_debug
115
+ # remove knockout prefix items from both source and dest
116
+ source.delete_if do |ko_item|
117
+ retval = false
118
+ item = ko_item.respond_to?(:gsub) ? ko_item.gsub(%r{^#{knockout_prefix}}, "") : ko_item
119
+ if item != ko_item
120
+ print "#{ko_item} - " if merge_debug
121
+ dest.delete(item)
122
+ dest.delete(ko_item)
123
+ retval = true
124
+ end
125
+ retval
126
+ end
127
+ puts if merge_debug
128
+ end
129
+ puts "#{di} merging arrays: #{source.inspect} :: #{dest.inspect}" if merge_debug
130
+ dest = dest | source
131
+ if sort_merged_arrays; dest.sort!; end
132
+ elsif overwrite_unmergeable
133
+ puts "#{di} overwriting dest: #{source.inspect} -over-> #{dest.inspect}" if merge_debug
134
+ dest = overwrite_unmergeables(source, dest, options)
135
+ end
136
+ else # src_hash is not an array or hash, so we'll have to overwrite dest
137
+ puts "#{di}Others: #{source.inspect} :: #{dest.inspect}" if merge_debug
138
+ dest = overwrite_unmergeables(source, dest, options)
139
+ end
140
+ puts "#{di}Returning #{dest.inspect}" if merge_debug
141
+ dest
142
+ end # deep_merge!
143
+
144
+ # allows deep_merge! to uniformly handle overwriting of unmergeable entities
145
+ def DeepMerge::overwrite_unmergeables(source, dest, options)
146
+ merge_debug = options[:merge_debug] || false
147
+ overwrite_unmergeable = !options[:preserve_unmergeables]
148
+ knockout_prefix = options[:knockout_prefix] || false
149
+ di = options[:debug_indent] || ''
150
+ if knockout_prefix && overwrite_unmergeable
151
+ if source.kind_of?(String) # remove knockout string from source before overwriting dest
152
+ src_tmp = source.gsub(%r{^#{knockout_prefix}},"")
153
+ elsif source.kind_of?(Array) # remove all knockout elements before overwriting dest
154
+ src_tmp = source.delete_if {|ko_item| ko_item.kind_of?(String) && ko_item.match(%r{^#{knockout_prefix}}) }
155
+ else
156
+ src_tmp = source
157
+ end
158
+ if src_tmp == source # if we didn't find a knockout_prefix then we just overwrite dest
159
+ puts "#{di}#{src_tmp.inspect} -over-> #{dest.inspect}" if merge_debug
160
+ dest = src_tmp
161
+ else # if we do find a knockout_prefix, then we just delete dest
162
+ puts "#{di}\"\" -over-> #{dest.inspect}" if merge_debug
163
+ dest = ""
164
+ end
165
+ elsif overwrite_unmergeable
166
+ dest = source
167
+ end
168
+ dest
169
+ end
170
+
171
+ def DeepMerge::clear_or_nil(obj)
172
+ if obj.respond_to?(:clear)
173
+ obj.clear
174
+ else
175
+ obj = nil
176
+ end
177
+ obj
178
+ end
179
+
180
+ end # module DeepMerge
@@ -0,0 +1,3 @@
1
+ module RailsConfig
2
+ VERSION = '0.3.1.1'
3
+ end
@@ -0,0 +1 @@
1
+ require 'rails_config/rails_config'
@@ -0,0 +1,26 @@
1
+ require File.dirname(__FILE__) + "/lib/rails_config/version"
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "rails_config_i18n"
5
+ s.version = RailsConfig::VERSION
6
+ s.date = Date.today.to_s
7
+ s.authors = ["Jacques Crocker", "Fred Wu", "Cedric Fung"]
8
+ s.email = ["railsjedi@gmail.com", "ifredwu@gmail.com", "wolfplanet@gmail.com"]
9
+ s.summary = "Provides a Settings helper for rails3 that reads from config/settings(.locale).yml"
10
+ s.description = "Easy to use Settings helper that loads its data in from config/settings.yml. Handles adding multiple sources, multiple locales, and easy reloading."
11
+ s.homepage = "http://github.com/abitno/rails_config_i18n"
12
+ s.extra_rdoc_files = ["README.md"]
13
+ s.rdoc_options = ["--charset=UTF-8"]
14
+ s.require_paths = ["lib"]
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+
19
+ s.add_runtime_dependency "activesupport", ">= 3.0"
20
+ s.add_runtime_dependency "i18n", ">= 0.6"
21
+ s.add_development_dependency "rake"
22
+ s.add_development_dependency "rspec", "~> 2.0"
23
+ s.add_development_dependency "autotest", ">= 0"
24
+ s.add_development_dependency "growl-glue", ">= 0"
25
+ end
26
+
@@ -0,0 +1,2 @@
1
+ override_bool: true
2
+ override_bool_opposite: false
@@ -0,0 +1,2 @@
1
+ override_bool: false
2
+ override_bool_opposite: true
@@ -0,0 +1,7 @@
1
+ prices:
2
+ type: hash
3
+ contents:
4
+ 1: 2.99
5
+ 5: 9.99
6
+ 15: 19.99
7
+ 30: 29.99
@@ -0,0 +1,28 @@
1
+ size: 1
2
+ server: google.com
3
+ inner:
4
+ something1: "blah1"
5
+ something2: "blah2"
6
+
7
+ inner2:
8
+ inner2_inner:
9
+ foo1: "blah1"
10
+
11
+
12
+ arraylist1:
13
+ - 1
14
+ - 2
15
+ - 3
16
+
17
+ arraylist2:
18
+ inner:
19
+ - 1
20
+ - 2
21
+ - 3
22
+
23
+ hash_array:
24
+ - 1
25
+ - inner:
26
+ - 1
27
+ - 2
28
+ - 3
@@ -0,0 +1,28 @@
1
+ server: google.com
2
+
3
+ inner:
4
+ something3: "blah3"
5
+
6
+ inner2:
7
+ inner2_inner:
8
+ foo2: "blah2"
9
+ foo3: "blah3"
10
+
11
+ arraylist1:
12
+ - 4
13
+ - 5
14
+ - 6
15
+
16
+
17
+ arraylist2:
18
+ inner:
19
+ - 4
20
+ - 5
21
+ - 6
22
+
23
+ hash_array:
24
+ - 2
25
+ - inner:
26
+ - 4
27
+ - 5
28
+ - 6
@@ -0,0 +1,3 @@
1
+ tvrage:
2
+ service_url: 'http://services.tvrage.com'
3
+ cache: 500
@@ -0,0 +1,2 @@
1
+ tvrage:
2
+ service_url: "http://url2"
@@ -0,0 +1,4 @@
1
+ size: 2
2
+ section:
3
+ size: 3
4
+ servers: [ {name: yahoo.com}, {name: amazon.com} ]
File without changes
File without changes
@@ -0,0 +1,3 @@
1
+ en:
2
+ language: 'English'
3
+ fallback_locale: 'Fallback locale'
@@ -0,0 +1,2 @@
1
+ zh-CN:
2
+ language: '中文'
@@ -0,0 +1,3 @@
1
+ size: 1
2
+ server: google.com
3
+ 1: "one"
@@ -0,0 +1 @@
1
+ another: "something"
@@ -0,0 +1,4 @@
1
+ computed: <%= 1 + 2 + 3 %>
2
+ section:
3
+ computed1: <%= "1" %>
4
+ computed2: <%= "2" %>
@@ -0,0 +1,235 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'i18n'
4
+ require 'spec_helper'
5
+
6
+ describe RailsConfig do
7
+
8
+ it "should load a basic config file" do
9
+ config = RailsConfig.load_files(setting_path("settings.yml"))
10
+ config.size.should eq 1
11
+ config.server.should eq "google.com"
12
+ end
13
+
14
+ it "should load 2 basic config files" do
15
+ config = RailsConfig.load_files(setting_path("settings.yml"), setting_path("settings2.yml"))
16
+ config.size.should eq 1
17
+ config.server.should eq "google.com"
18
+ config.another.should eq "something"
19
+ end
20
+
21
+ it "should load empty config for a missing file path" do
22
+ config = RailsConfig.load_files(setting_path("some_file_that_doesnt_exist.yml"))
23
+ config.should be_empty
24
+ end
25
+
26
+ it "should load an empty config for multiple missing file paths" do
27
+ files = [setting_path("doesnt_exist1.yml"), setting_path("doesnt_exist2.yml")]
28
+ config = RailsConfig.load_files(files)
29
+ config.should be_empty
30
+ end
31
+
32
+ it "should load empty config for an empty setting file" do
33
+ config = RailsConfig.load_files(setting_path("empty1.yml"))
34
+ config.should be_empty
35
+ end
36
+
37
+ it "should convert to a hash" do
38
+ config = RailsConfig.load_files(setting_path("development.yml")).to_hash
39
+ config[:section][:servers].should be_a_kind_of(Array)
40
+ end
41
+
42
+ it "should convert to a json" do
43
+ config = RailsConfig.load_files(setting_path("development.yml")).to_json
44
+ JSON.parse(config)["section"]["servers"].should be_a_kind_of(Array)
45
+ end
46
+
47
+ it "should load an empty config for multiple missing file paths" do
48
+ files = [setting_path("empty1.yml"), setting_path("empty2.yml")]
49
+ config = RailsConfig.load_files(files)
50
+ config.should be_empty
51
+ end
52
+
53
+ it "should allow overrides" do
54
+ files = [setting_path("settings.yml"), setting_path("development.yml")]
55
+ config = RailsConfig.load_files(files)
56
+ config.server.should eq "google.com"
57
+ config.size.should eq 2
58
+ end
59
+
60
+ #it "should allow full reload of the settings files" do
61
+ #files = [setting_path("settings.yml")]
62
+ #RailsConfig.load_and_set_settings(files)
63
+ #Settings.server.should eq "google.com"
64
+ #Settings.size.should eq 1
65
+
66
+ #files = [setting_path("settings.yml"), setting_path("development.yml")]
67
+ #Settings.reload_from_files(files)
68
+ #Settings.server.should eq "google.com"
69
+ #Settings.size.should eq 2
70
+ #end
71
+
72
+ context "Nested Settings" do
73
+ let(:config) do
74
+ RailsConfig.load_files(setting_path("development.yml"))
75
+ end
76
+
77
+ it "should allow nested sections" do
78
+ config.section.size.should eq 3
79
+ end
80
+
81
+ it "should allow configuration collections (arrays)" do
82
+ config.section.servers[0].name.should eq "yahoo.com"
83
+ config.section.servers[1].name.should eq "amazon.com"
84
+ end
85
+ end
86
+
87
+ context "Settings with ERB tags" do
88
+ let(:config) do
89
+ RailsConfig.load_files(setting_path("with_erb.yml"))
90
+ end
91
+
92
+ it "should evaluate ERB tags" do
93
+ config.computed.should eq 6
94
+ end
95
+
96
+ it "should evaluated nested ERB tags" do
97
+ config.section.computed1.should eq 1
98
+ config.section.computed2.should eq 2
99
+ end
100
+ end
101
+
102
+ context "Deep Merging" do
103
+ let(:config) do
104
+ files = [setting_path("deep_merge/config1.yml"), setting_path("deep_merge/config2.yml")]
105
+ RailsConfig.load_files(files)
106
+ end
107
+
108
+ it "should merge hashes from multiple configs" do
109
+ config.inner.marshal_dump.keys.size.should eq 3
110
+ config.inner2.inner2_inner.marshal_dump.keys.size.should eq 3
111
+ end
112
+
113
+ it "should merge arrays from multiple configs" do
114
+ config.arraylist1.size.should eq 6
115
+ config.arraylist2.inner.size.should eq 6
116
+ end
117
+ end
118
+
119
+ context "Boolean Overrides" do
120
+ let(:config) do
121
+ files = [setting_path("bool_override/config1.yml"), setting_path("bool_override/config2.yml")]
122
+ RailsConfig.load_files(files)
123
+ end
124
+
125
+ it "should allow overriding of bool settings" do
126
+ config.override_bool.should eq false
127
+ config.override_bool_opposite.should eq true
128
+ end
129
+ end
130
+
131
+ context "Custom Configuration" do
132
+ it "should have the default settings constant as 'Settings'" do
133
+ RailsConfig.const_name.should eq "Settings"
134
+ end
135
+
136
+ it "should be able to assign a different settings constant" do
137
+ RailsConfig.setup{ |config| config.const_name = "Settings2" }
138
+ RailsConfig.const_name.should eq "Settings2"
139
+ end
140
+ end
141
+
142
+ context "Settings with a type value of 'hash'" do
143
+ let(:config) do
144
+ files = [setting_path("custom_types/hash.yml")]
145
+ RailsConfig.load_files(files)
146
+ end
147
+
148
+ it "should turn that setting into a Real Hash" do
149
+ config.prices.should be_a(Hash)
150
+ end
151
+
152
+ it "should map the hash values correctly" do
153
+ config.prices[1].should eq 2.99
154
+ config.prices[5].should eq 9.99
155
+ config.prices[15].should eq 19.99
156
+ config.prices[30].should eq 29.99
157
+ end
158
+ end
159
+
160
+ context "Merging hash at runtime" do
161
+ let(:config) { RailsConfig.load_files(setting_path("settings.yml")) }
162
+ let(:hash) { {:options => {:suboption => 'value'}, :server => 'amazon.com'} }
163
+
164
+ it 'should be chainable' do
165
+ config.merge!({}).should eq config
166
+ end
167
+
168
+ it 'should preserve existing keys' do
169
+ expect { config.merge!({}) }.to_not change{ config.keys }
170
+ end
171
+
172
+ it 'should recursively merge keys' do
173
+ config.merge!(hash)
174
+ config.options.suboption.should eq 'value'
175
+ end
176
+
177
+ it 'should rewrite a merged value' do
178
+ expect { config.merge!(hash) }.to change{ config.server }.from('google.com').to('amazon.com')
179
+ end
180
+ end
181
+
182
+ context "Merging nested hash at runtime" do
183
+ let(:config) { RailsConfig.load_files(setting_path("deep_merge/config1.yml")) }
184
+ let(:hash) { {:inner => {:something1 => 'changed1', :something3 => 'changed3'} } }
185
+
186
+ it 'should preserve first level keys' do
187
+ expect { config.merge!(hash) }.to_not change{ config.keys }
188
+ end
189
+
190
+ it 'should preserve nested key' do
191
+ config.merge!(hash)
192
+ config.inner.something2.should eq 'blah2'
193
+ end
194
+
195
+ it 'should add new nested key' do
196
+ expect { config.merge!(hash) }.to change { config.inner.something3 }.from(nil).to("changed3")
197
+ end
198
+
199
+ it 'should rewrite a merged value' do
200
+ expect { config.merge!(hash) }.to change{ config.inner.something1 }.from('blah1').to('changed1')
201
+ end
202
+ end
203
+
204
+ context "[] accessors" do
205
+ let(:config) do
206
+ files = [setting_path("development.yml")]
207
+ RailsConfig.load_files(files)
208
+ end
209
+
210
+ it "should access attributes using []" do
211
+ config.section['size'].should eq 3
212
+ config.section[:size].should eq 3
213
+ config[:section][:size].should eq 3
214
+ end
215
+
216
+ it "should set values using []=" do
217
+ config.section[:foo] = 'bar'
218
+ config.section.foo.should eq 'bar'
219
+ end
220
+ end
221
+
222
+ context "I18n locales" do
223
+ it "should output language" do
224
+ files = [setting_path("locales/settings.en.yml"), setting_path("locales/settings.zh-CN.yml")]
225
+ RailsConfig.load_and_set_settings(files)
226
+
227
+ I18n.locale = 'en'
228
+ RailsConfig.language.should eq 'English'
229
+
230
+ I18n.locale = 'zh-CN'
231
+ RailsConfig.language.should eq '中文'
232
+ RailsConfig.fallback_locale.should eq 'Fallback locale'
233
+ end
234
+ end
235
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ module RailsConfig::Sources
4
+ describe YAMLSource do
5
+
6
+ it "should take a path as initializer" do
7
+ source = YAMLSource.new "somepath"
8
+ source.path.should == "somepath"
9
+ end
10
+
11
+ context "basic yml file" do
12
+ let(:source) do
13
+ YAMLSource.new setting_path("development.yml")
14
+ end
15
+
16
+ it "should properly read the settings" do
17
+ results = source.load
18
+ results["size"].should == 2
19
+ end
20
+
21
+ it "should properly read nested settings" do
22
+ results = source.load
23
+ results["section"]["size"].should == 3
24
+ results["section"]["servers"].should be_an(Array)
25
+ results["section"]["servers"].size.should == 2
26
+ end
27
+ end
28
+
29
+ context "yml file with erb tags" do
30
+ let(:source) do
31
+ YAMLSource.new setting_path("with_erb.yml")
32
+ end
33
+
34
+ it "should properly evaluate the erb" do
35
+ results = source.load
36
+ results["computed"].should == 6
37
+ end
38
+
39
+ it "should properly evaluate the nested erb settings" do
40
+ results = source.load
41
+ results["section"]["computed1"].should == 1
42
+ results["section"]["computed2"].should == 2
43
+ end
44
+ end
45
+
46
+ context "missing yml file" do
47
+ let(:source) do
48
+ YAMLSource.new "somewhere_that_doesnt_exist.yml"
49
+ end
50
+
51
+ it "should return an empty hash" do
52
+ results = source.load
53
+ results.should == {}
54
+ end
55
+ end
56
+
57
+ context "blank yml file" do
58
+ let(:source) do
59
+ YAMLSource.new setting_path("empty1.yml")
60
+ end
61
+
62
+ it "should return an empty hash" do
63
+ results = source.load
64
+ results.should == {}
65
+ end
66
+ end
67
+
68
+ end
69
+ end
@@ -0,0 +1,25 @@
1
+ require 'rails_config_i18n'
2
+ require 'pathname'
3
+ require 'bundler/setup'
4
+
5
+ def in_editor?
6
+ ENV.has_key?('TM_MODE') || ENV.has_key?('EMACS') || ENV.has_key?('VIM')
7
+ end
8
+
9
+ RSpec.configure do |c|
10
+ c.color_enabled = !in_editor?
11
+ c.run_all_when_everything_filtered = true
12
+
13
+ # setup fixtures path
14
+ c.before(:all) do
15
+ @fixture_path = Pathname.new(File.join(File.dirname(__FILE__), "/fixtures"))
16
+ raise "Fixture folder not found: #{@fixture_path}" unless @fixture_path.directory?
17
+ end
18
+
19
+ # returns the file path of a fixture setting file
20
+ def setting_path(filename)
21
+ @fixture_path.join(filename)
22
+ end
23
+
24
+ end
25
+