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.
- data/.bundle/config +2 -0
- data/.gitignore +4 -0
- data/Gemfile +10 -0
- data/LICENSE +23 -0
- data/README.md +243 -0
- data/Rakefile +28 -0
- data/autotest/discover.rb +2 -0
- data/init.rb +1 -0
- data/lib/generators/rails_config/install_generator.rb +32 -0
- data/lib/generators/rails_config/templates/rails_config.rb +4 -0
- data/lib/generators/rails_config/templates/settings/development.yml +1 -0
- data/lib/generators/rails_config/templates/settings/production.yml +1 -0
- data/lib/generators/rails_config/templates/settings/test.yml +1 -0
- data/lib/generators/rails_config/templates/settings.local.yml +1 -0
- data/lib/generators/rails_config/templates/settings.yml +1 -0
- data/lib/rails_config/integration/rails.rb +38 -0
- data/lib/rails_config/integration/sinatra.rb +31 -0
- data/lib/rails_config/options.rb +100 -0
- data/lib/rails_config/rack/reloader.rb +15 -0
- data/lib/rails_config/rails_config.rb +55 -0
- data/lib/rails_config/sources/yaml_source.rb +24 -0
- data/lib/rails_config/vendor/deep_merge.rb +180 -0
- data/lib/rails_config/version.rb +3 -0
- data/lib/rails_config_i18n.rb +1 -0
- data/rails_config.gemspec +26 -0
- data/spec/fixtures/bool_override/config1.yml +2 -0
- data/spec/fixtures/bool_override/config2.yml +2 -0
- data/spec/fixtures/custom_types/hash.yml +7 -0
- data/spec/fixtures/deep_merge/config1.yml +28 -0
- data/spec/fixtures/deep_merge/config2.yml +28 -0
- data/spec/fixtures/deep_merge2/config1.yml +3 -0
- data/spec/fixtures/deep_merge2/config2.yml +2 -0
- data/spec/fixtures/development.yml +4 -0
- data/spec/fixtures/empty1.yml +0 -0
- data/spec/fixtures/empty2.yml +0 -0
- data/spec/fixtures/locales/settings.en.yml +3 -0
- data/spec/fixtures/locales/settings.zh-CN.yml +2 -0
- data/spec/fixtures/settings.yml +3 -0
- data/spec/fixtures/settings2.yml +1 -0
- data/spec/fixtures/with_erb.yml +4 -0
- data/spec/rails_config_spec.rb +235 -0
- data/spec/sources/yaml_source_spec.rb +69 -0
- data/spec/spec_helper.rb +25 -0
- 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 @@
|
|
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,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
|
File without changes
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
another: "something"
|
@@ -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
|
data/spec/spec_helper.rb
ADDED
@@ -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
|
+
|