rconfig 0.3.2
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/lib/rconfig.rb +39 -0
- data/lib/rconfig/config_hash.rb +105 -0
- data/lib/rconfig/core_ext.rb +6 -0
- data/lib/rconfig/core_ext/hash.rb +104 -0
- data/lib/rconfig/exceptions.rb +13 -0
- data/lib/rconfig/properties_file_parser.rb +80 -0
- data/lib/rconfig/rconfig.rb +871 -0
- data/test/rconfig_test.rb +381 -0
- metadata +76 -0
@@ -0,0 +1,381 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
root_dir = File.dirname(__FILE__)
|
4
|
+
conf_dir = File.expand_path(File.dirname(__FILE__))
|
5
|
+
|
6
|
+
$LOAD_PATH << File.join(root_dir,"..","lib")
|
7
|
+
|
8
|
+
# Test environment:
|
9
|
+
ENV['TIER'] = 'development'
|
10
|
+
ENV['CONFIG_PATH'] = conf_dir + "/test_files/"
|
11
|
+
ENV.delete('CONFIG_OVERLAY') # Avoid unintended magic.
|
12
|
+
|
13
|
+
# Test dependencies:
|
14
|
+
require 'test/unit'
|
15
|
+
require 'fileutils' # FileUtils.touch
|
16
|
+
|
17
|
+
# Test target:
|
18
|
+
require 'rconfig'
|
19
|
+
|
20
|
+
|
21
|
+
class RConfigTest < Test::Unit::TestCase
|
22
|
+
|
23
|
+
|
24
|
+
def setup
|
25
|
+
super
|
26
|
+
begin
|
27
|
+
RConfig.verbose = nil # default
|
28
|
+
RConfig.reload(true)
|
29
|
+
RConfig.reload_disabled = nil # default
|
30
|
+
RConfig.reload_delay = nil # default
|
31
|
+
rescue => err
|
32
|
+
# NOTHING
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def teardown
|
38
|
+
super
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
def test_basic
|
43
|
+
assert_equal true, RConfig.test.secure_login
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
def test_default
|
48
|
+
assert_equal "yo!", RConfig.test.default
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
def test_indifferent
|
53
|
+
assert h = RConfig.test
|
54
|
+
# STDERR.puts "h = #{h.inspect}:#{h.class}"
|
55
|
+
|
56
|
+
assert hstr = h['hash_1']
|
57
|
+
assert_kind_of Hash, hstr
|
58
|
+
# STDERR.puts "hstr = #{hstr.inspect}:#{hstr.class}"
|
59
|
+
|
60
|
+
assert hsym = h[:hash_1]
|
61
|
+
assert hsym.object_id == hstr.object_id
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
def test_dot_notation
|
66
|
+
assert h = RConfig.test
|
67
|
+
assert h = h.hash_1
|
68
|
+
assert h.foo
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
def test_dot_notation_overrun
|
73
|
+
assert_raise NoMethodError do
|
74
|
+
RConfig.test.hash_1.foo.a_bridge_too_far
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
def test_array_notation
|
80
|
+
assert h = RConfig.test[:hash_1]
|
81
|
+
assert a = RConfig.test[:array_1]
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
def test_function_notation
|
86
|
+
assert h = RConfig.test(:hash_1, 'foo')
|
87
|
+
assert_equal nil, RConfig.test(:hash_1, 'foo', :too_far)
|
88
|
+
assert_equal 'c', RConfig.test(:array_1, 2)
|
89
|
+
assert_equal nil, RConfig.test(:array_1, "2")
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
def test_immutable
|
94
|
+
assert_raise TypeError do
|
95
|
+
RConfig.test.hash_1[:foo] = 1
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
def test_to_yaml
|
101
|
+
assert RConfig.test.to_yaml
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
def test_disable_reload
|
106
|
+
# Clear out everything.
|
107
|
+
RConfig.reload(true)
|
108
|
+
|
109
|
+
# Reload delay
|
110
|
+
RConfig.reload_delay = -1
|
111
|
+
# RConfig.verbose = true
|
112
|
+
RConfig.config_file_loaded = nil
|
113
|
+
|
114
|
+
# Get the name of a config file to touch.
|
115
|
+
assert cf1 = RConfig.get_config_files("test")
|
116
|
+
assert cf1 = cf1[0][2]
|
117
|
+
|
118
|
+
v = nil
|
119
|
+
th = nil
|
120
|
+
RConfig.disable_reload do
|
121
|
+
# Make sure first access works inside disable reload.
|
122
|
+
assert th = RConfig.test
|
123
|
+
assert_equal "foo", v = RConfig.test.hash_1.foo
|
124
|
+
RConfig.config_file_loaded = nil
|
125
|
+
|
126
|
+
# Get access again and insure that file was not reloaded.
|
127
|
+
assert_equal v, RConfig.test.hash_1.foo
|
128
|
+
assert th.object_id == RConfig.test.object_id
|
129
|
+
assert ! RConfig.config_file_loaded
|
130
|
+
|
131
|
+
# STDERR.puts "touching #{cf1.inspect}"
|
132
|
+
FileUtils.touch(cf1)
|
133
|
+
|
134
|
+
assert_equal v, RConfig.test.hash_1.foo
|
135
|
+
assert th.object_id == RConfig.test.object_id
|
136
|
+
assert ! RConfig.config_file_loaded
|
137
|
+
end
|
138
|
+
|
139
|
+
# STDERR.puts "reload allowed"
|
140
|
+
assert ! RConfig.config_file_loaded
|
141
|
+
assert th.object_id != RConfig.test.object_id
|
142
|
+
assert_equal v, RConfig.test.hash_1.foo
|
143
|
+
|
144
|
+
assert RConfig.config_file_loaded
|
145
|
+
assert_equal v, RConfig.test.hash_1.foo
|
146
|
+
|
147
|
+
|
148
|
+
# Restore reload_delay
|
149
|
+
RConfig.reload_delay = false
|
150
|
+
RConfig.verbose = false
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
def test_hash_merge
|
155
|
+
assert_equal "foo", RConfig.test.hash_1.foo
|
156
|
+
assert_equal "baz", RConfig.test.hash_1.bar
|
157
|
+
assert_equal "bok", RConfig.test.hash_1.bok
|
158
|
+
assert_equal "zzz", RConfig.test.hash_1.zzz
|
159
|
+
end
|
160
|
+
|
161
|
+
|
162
|
+
def test_array
|
163
|
+
assert_equal [ 'a', 'b', 'c', 'd' ], RConfig.test.array_1
|
164
|
+
end
|
165
|
+
|
166
|
+
|
167
|
+
def test_index
|
168
|
+
assert_kind_of Hash, RConfig.get_config_file(:test)
|
169
|
+
end
|
170
|
+
|
171
|
+
|
172
|
+
def test_config_files
|
173
|
+
assert_kind_of Array, cf = RConfig.get_config_files("test").select{|x| x[3]}
|
174
|
+
# STDERR.puts "cf = #{cf.inspect}"
|
175
|
+
|
176
|
+
if ENV['CONFIG_OVERLAY']
|
177
|
+
assert_equal 3, cf.size
|
178
|
+
else
|
179
|
+
assert_equal 2, cf.size
|
180
|
+
end
|
181
|
+
|
182
|
+
assert_equal 4, cf[0].size
|
183
|
+
assert_equal "test", cf[0][0]
|
184
|
+
assert_equal "test", cf[0][1]
|
185
|
+
|
186
|
+
assert_equal 4, cf[1].size
|
187
|
+
if ENV['CONFIG_OVERLAY'] == 'gb'
|
188
|
+
assert_equal "test_gb", cf[1][0]
|
189
|
+
assert_equal "test_gb", cf[1][1]
|
190
|
+
|
191
|
+
assert_equal 4, cf[2].size
|
192
|
+
assert_equal "test", cf[2][0]
|
193
|
+
assert_equal "test_local", cf[2][1]
|
194
|
+
else
|
195
|
+
assert_equal "test", cf[1][0]
|
196
|
+
assert_equal "test_local", cf[1][1]
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
|
202
|
+
def test_config_changed
|
203
|
+
RConfig.reload(true)
|
204
|
+
|
205
|
+
cf1 = RConfig.config_files("test")
|
206
|
+
cf2 = RConfig.get_config_files("test")
|
207
|
+
cf3 = RConfig.config_files("test")
|
208
|
+
|
209
|
+
# Check that _config_files is cached.
|
210
|
+
# STDERR.puts "cf1 = #{cf1.object_id.inspect}"
|
211
|
+
# STDERR.puts "cf2 = #{cf2.object_id.inspect}"
|
212
|
+
assert cf1.object_id != cf2.object_id
|
213
|
+
assert cf1.object_id == cf3.object_id
|
214
|
+
|
215
|
+
# STDERR.puts "cf1 = #{cf1.inspect}"
|
216
|
+
# STDERR.puts "cf2 = #{cf2.inspect}"
|
217
|
+
# Check that config_changed? is false, until touch.
|
218
|
+
assert cf1.object_id != cf2.object_id
|
219
|
+
assert_equal cf1, cf2
|
220
|
+
assert_equal false, RConfig.config_changed?("test")
|
221
|
+
|
222
|
+
# Touch a file.
|
223
|
+
FileUtils.touch(cf1[1][2])
|
224
|
+
cf2 = RConfig.get_config_files("test")
|
225
|
+
assert cf1.object_id != cf2.object_id
|
226
|
+
assert ! (cf1 === cf2)
|
227
|
+
assert_equal true, RConfig.config_changed?("test")
|
228
|
+
|
229
|
+
# Pull config again.
|
230
|
+
RConfig.reload(true)
|
231
|
+
cf3 = RConfig.config_files("test")
|
232
|
+
cf2 = RConfig.get_config_files("test")
|
233
|
+
# STDERR.puts "cf3 = #{cf1.inspect}"
|
234
|
+
# STDERR.puts "cf2 = #{cf2.inspect}"
|
235
|
+
assert cf1.object_id != cf3.object_id
|
236
|
+
assert RConfig.config_files("test")
|
237
|
+
assert_equal false, RConfig.config_changed?("test")
|
238
|
+
|
239
|
+
# Pull config again, expect no changes.
|
240
|
+
cf4 = RConfig.config_files("test")
|
241
|
+
# STDERR.puts "cf3 = #{cf1.inspect}"
|
242
|
+
# STDERR.puts "cf2 = #{cf2.inspect}"
|
243
|
+
assert cf3.object_id == cf4.object_id
|
244
|
+
assert RConfig.config_files("test")
|
245
|
+
assert_equal false, RConfig.config_changed?("test")
|
246
|
+
|
247
|
+
end
|
248
|
+
|
249
|
+
|
250
|
+
def test_check_reload_disabled
|
251
|
+
RConfig.reload(true)
|
252
|
+
|
253
|
+
assert_kind_of Array, RConfig.config_files('test')
|
254
|
+
|
255
|
+
RConfig.reload_disabled = true
|
256
|
+
|
257
|
+
assert_kind_of Array, RConfig.load_config_files('test')
|
258
|
+
|
259
|
+
RConfig.reload_disabled = nil
|
260
|
+
end
|
261
|
+
|
262
|
+
|
263
|
+
def test_on_load_callback
|
264
|
+
# STDERR.puts "test_on_load_callback"
|
265
|
+
|
266
|
+
RConfig.reload(true)
|
267
|
+
# RConfig.verbose = 1
|
268
|
+
|
269
|
+
cf1 = RConfig.config_files("test")
|
270
|
+
|
271
|
+
assert_equal "foo", RConfig.test.hash_1.foo
|
272
|
+
|
273
|
+
sleep 1
|
274
|
+
|
275
|
+
called_back = 0
|
276
|
+
|
277
|
+
RConfig.on_load(:test) do
|
278
|
+
called_back += 1
|
279
|
+
# STDERR.puts "on_load #{called_back}"
|
280
|
+
end
|
281
|
+
|
282
|
+
assert_equal 1, called_back
|
283
|
+
|
284
|
+
assert_equal "foo", RConfig.test.hash_1.foo
|
285
|
+
|
286
|
+
|
287
|
+
# STDERR.puts "Not expecting config change."
|
288
|
+
assert_nil RConfig.check_config_changed
|
289
|
+
assert_equal "foo", RConfig.test.hash_1.foo
|
290
|
+
assert_equal 1, called_back
|
291
|
+
|
292
|
+
file = cf1[0][2]
|
293
|
+
# STDERR.puts "Touching file #{file.inspect}"
|
294
|
+
File.chmod(0644, file)
|
295
|
+
FileUtils.touch(file)
|
296
|
+
File.chmod(0444, file)
|
297
|
+
|
298
|
+
# STDERR.puts "Expect config change."
|
299
|
+
assert_not_nil RConfig.check_config_changed
|
300
|
+
assert_equal "foo", RConfig.test.hash_1.foo
|
301
|
+
assert_equal 2, called_back
|
302
|
+
|
303
|
+
# STDERR.puts "Not expecting config change."
|
304
|
+
assert_nil RConfig.check_config_changed
|
305
|
+
assert_equal "foo", RConfig.test.hash_1.foo
|
306
|
+
assert_equal 2, called_back
|
307
|
+
|
308
|
+
# STDERR.puts "test_on_load_callback: END"
|
309
|
+
end
|
310
|
+
|
311
|
+
|
312
|
+
def test_overlay_by_name
|
313
|
+
assert_equal nil, RConfig.overlay
|
314
|
+
|
315
|
+
assert_equal "foo", RConfig.test.hash_1.foo
|
316
|
+
assert_equal "foo", RConfig.test_GB.hash_1.foo
|
317
|
+
|
318
|
+
assert_equal "bok", RConfig.test.hash_1.bok
|
319
|
+
assert_equal "GB", RConfig.test_GB.hash_1.bok
|
320
|
+
|
321
|
+
assert_equal nil, RConfig.test.hash_1.gb
|
322
|
+
assert_equal "GB", RConfig.test_GB.hash_1.gb
|
323
|
+
end
|
324
|
+
|
325
|
+
|
326
|
+
def test_overlay_change
|
327
|
+
begin
|
328
|
+
RConfig.overlay = 'gb'
|
329
|
+
|
330
|
+
assert_equal "foo", RConfig.test.hash_1.foo
|
331
|
+
assert_equal "foo", RConfig.test_GB.hash_1.foo
|
332
|
+
assert_equal "foo", RConfig.test_US.hash_1.foo
|
333
|
+
|
334
|
+
assert_equal "GB", RConfig.test.hash_1.bok
|
335
|
+
assert_equal "GB", RConfig.test_GB.hash_1.bok
|
336
|
+
assert_equal "US", RConfig.test_US.hash_1.bok
|
337
|
+
|
338
|
+
assert_equal "GB", RConfig.test.hash_1.gb
|
339
|
+
assert_equal "GB", RConfig.test_GB.hash_1.gb
|
340
|
+
assert_equal nil, RConfig.test_US.hash_1.gb
|
341
|
+
|
342
|
+
RConfig.overlay = 'us'
|
343
|
+
|
344
|
+
assert_equal "foo", RConfig.test.hash_1.foo
|
345
|
+
assert_equal "foo", RConfig.test_GB.hash_1.foo
|
346
|
+
assert_equal "foo", RConfig.test_US.hash_1.foo
|
347
|
+
|
348
|
+
assert_equal "US", RConfig.test.hash_1.bok
|
349
|
+
assert_equal "GB", RConfig.test_GB.hash_1.bok
|
350
|
+
assert_equal "US", RConfig.test_US.hash_1.bok
|
351
|
+
|
352
|
+
assert_equal nil, RConfig.test.hash_1.gb
|
353
|
+
assert_equal "GB", RConfig.test_GB.hash_1.gb
|
354
|
+
assert_equal nil, RConfig.test_US.hash_1.gb
|
355
|
+
|
356
|
+
RConfig.overlay = nil
|
357
|
+
|
358
|
+
ensure
|
359
|
+
RConfig.overlay = nil
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
|
364
|
+
# Expand this benchmark to
|
365
|
+
# compare with relative minimum performance, for example
|
366
|
+
# a loop from 1 to 1000000.
|
367
|
+
# Make this test fail if the minimum peformance criteria
|
368
|
+
# is not met.
|
369
|
+
# -- kurt@cashnetusa.com 2007/06/12
|
370
|
+
def test_zzz_benchmark
|
371
|
+
n = 10000
|
372
|
+
bm = Benchmark.measure do
|
373
|
+
n.times do
|
374
|
+
RConfig.test.hash_1.foo
|
375
|
+
end
|
376
|
+
end
|
377
|
+
puts "\n#{n}.times =>#{bm}\n"
|
378
|
+
end
|
379
|
+
|
380
|
+
end # class
|
381
|
+
|
metadata
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rconfig
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Rahmal Conda
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-11-20 00:00:00 -06:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: activesupport
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 2.2.2
|
24
|
+
version:
|
25
|
+
description: The complete solution for Ruby Configuration Management
|
26
|
+
email: rahmal@gmail.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files: []
|
32
|
+
|
33
|
+
files:
|
34
|
+
- lib/rconfig/exceptions.rb
|
35
|
+
- lib/rconfig/properties_file_parser.rb
|
36
|
+
- lib/rconfig/core_ext/hash.rb
|
37
|
+
- lib/rconfig/config_hash.rb
|
38
|
+
- lib/rconfig/rconfig.rb
|
39
|
+
- lib/rconfig/core_ext.rb
|
40
|
+
- lib/rconfig.rb
|
41
|
+
has_rdoc: true
|
42
|
+
homepage: http://www.rahmalconda.com
|
43
|
+
licenses: []
|
44
|
+
|
45
|
+
post_install_message:
|
46
|
+
rdoc_options:
|
47
|
+
- --line-numbers
|
48
|
+
- --inline-source
|
49
|
+
- --title
|
50
|
+
- RConfig
|
51
|
+
- --main
|
52
|
+
- README.rdoc
|
53
|
+
require_paths:
|
54
|
+
- lib
|
55
|
+
- tasks
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: "0"
|
61
|
+
version:
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: "0"
|
67
|
+
version:
|
68
|
+
requirements: []
|
69
|
+
|
70
|
+
rubyforge_project: rconda-rconfig
|
71
|
+
rubygems_version: 1.3.5
|
72
|
+
signing_key:
|
73
|
+
specification_version: 3
|
74
|
+
summary: RConfig manages configuration within Ruby applications. It supports yaml, xml, and properties files, with hash based and dot notation access, while providing an elegant API.
|
75
|
+
test_files:
|
76
|
+
- test/rconfig_test.rb
|