rails_config_i18n 0.3.1.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.
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
+